你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32H7+CUBE+ETH+LWIP配置及设置

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH* l- x3 f+ J1 }2 i

6 R9 o- T4 [/ c0 Q: y7 [
20210402161452602.png
( S6 x! O4 I+ z) U/ n
" |; L, o2 A1 ~3 Q0 e5 c& i5 P
20210402161514595.png
& |  N* \3 |. X4 k$ x2 p' k. k: `+ g
7 `- m! D+ q7 c' j
20210402161532893.png

- ~6 R! [3 S7 o; a# T9 Z1 o( j7 L: b/ G6 t% S+ E* _
配置EHT_RST引脚
4 @+ n; w# R: ?8 s' {/ R$ X
) U5 v9 E9 [  c- |' U- k: H. `4 ^
20210402161604234.png

$ H) S- x" U+ O. x- ]5 Q
; {3 B5 V) t6 d% r/ }8 DLWIP
$ t. ~" Y1 X: n2 v7 u! V# N/ W
20210402161716753.png

3 V+ S2 \- p; X# [5 \* p- }4 r9 x7 ]6 S! X
20210402161746306.png

# Y9 }" u: }/ T! A! _& q4 c6 y
注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情
! o( ]0 _1 p- r- g
( q. P+ E% e! Z' M4 t
20210402163232833.png
' w1 s# T1 S0 p
5 V+ [" `, H; k+ z! w
LAN8742
6 i- E5 c: S0 j6 _
20210402163258853.png
( B( R6 @9 P) t$ N7 ~8 e; n
2 p0 ]- H  R! F  e' U
MPU8 o, T  D+ {; q5 M
Lwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。
8 w* \  P% T, h0 o& y8 M8 U& ~  B" n4 v- m7 e
使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。
  O7 [7 Q% s6 V: A4 r
+ r" B5 U8 X2 G9 x( [, I
2021040216385026.png
; Z4 X) N; i+ y2 ~. D$ r9 l! g
% Z' L& R, x8 }* l
20210402164922519.png
$ {$ E8 G" {8 Z' G* a! i1 o
* {3 n0 V4 n/ D& S9 w1 [
20210402163942899.png
2 n5 ]+ X! e  o1 r
3 u7 k  R% i; m$ _2 x% J
9 U9 J3 H$ O+ k
MPU设定总结(非操作步骤)
0 A6 F4 C  C1 N( K8 }. A" ^, |总结一下这样做的原因与目的:
# e; u' m& g. Q0 D% D" `(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;' o+ X0 V0 c9 Q
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;
& ^, Z) {& N& ^- O8 c5 [(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。
6 R& r; M3 K5 M7 C* }6 {
( f' \% o7 w, ?# f
20210402165153856.png

9 {& U. U7 C9 ]9 M+ W# ^5 H$ g6 g' ~! @: R+ k
MPU选项含义(非操作步骤)# [3 w2 }8 j, T# C( `
cubeMX里面配置TEX、C、B,三者搭配。
) R: r  f2 d' I) k) a" j
- |- q+ |0 I+ {3 B( ^
20210402165235835.png
' ?8 n; x5 M* a1 ]- P: F

& k& [/ R+ z2 b; d1 `; x+ M# y% P1 e, f( ]- U5 v- |" u: m
Access permission被定义为3,即Full access。
4 p2 n! B$ @7 [4 U2 S1 ]8 Z. I, K* D, ]) V' a* M  M1 @
20210402165246437.png

& {0 E. D1 f: `1 l% W( q* Q3 X  E4 K: o# M: n
经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。! z. V" R% R5 G$ b/ ~. K  S

) P2 P# o/ J1 s9 F& _& U7 V, Y好了,可以进行下一步!! @! L/ F% G" [8 H8 d
. h; g2 {2 f, `& `$ h0 W
Lwip协议栈TCP保活(KeepAlive)设定
$ o* y" F. O. m' P
万事具备了么?no!* W& k2 O6 \  i0 ^  o2 o& X
6 ~& T' I& f3 O  t  i/ c, T; z) d3 p
以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
# q6 _5 _& x+ k9 U6 A( A+ t
' s$ o$ ~  V) X有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。
  N9 q# H" |, c
3 _0 C% E/ U- ?; l* p2 Y3 b# q由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入
$ l5 O! s& k2 s1 G4 ]  ?) B+ C
1 t: S3 R0 c6 S9 U4 [0 N/ T; @
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive
    8 @2 p( ]/ x. X2 `1 y" u
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测2 O) _* y& {( c
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测. n, F) u! ]  r/ u$ \. b3 I
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码

' O& Q" p+ A4 G6 s' rtcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码

( m) f# |0 w! R" B( K这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。- _& P" T# b) ]2 L- F9 O' O' p  m
电脑IP :192.168.0.99% n: A% V* {, ]0 Y' E
单片机IP :192.168.0.807 I2 @) {2 y$ k' ~
) i  u3 O: t( }1 a" p; m
20210402165445842.png
/ A- J1 ^9 t6 |5 \! O9 _$ R4 B- h

2 e; W. S, M5 r# |+ f自动化流程为:. k0 b- a& E: Y5 [0 H) V/ i5 g
拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接
8 g) z# ^# P# E+ F6 V" u  {如此往复…1 X+ A. M) ~, i8 Z9 v- s4 u

2 g; M  U0 t8 q9 o) L  G6 J用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:# d" r! N8 ^& t2 n- ?
1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
- X$ L) _0 Z, |; y5 Q解决办法: 在 …Src ethernetif.c 修改如下:
5 E- s) g  y: b0 w7 }8 _
0 B9 J: G1 `! U. O% h4 X; h' ?4 U0 j
  1. heth.Instance = ETH;
    7 j( ^2 {$ Y: R% J9 Z* r6 c) r

  2. + F7 Y" t5 ?  w& _* f; P. f/ `0 d/ C
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
    & T3 g& P  w$ G

  4. 6 ], [; r" ?  }9 Z+ q7 F1 w5 |* l9 F
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;/ o% I8 K" A" \7 L
  6. 5 Z1 U. F) u8 U
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1
    8 ]+ j& Y. ?) @* X/ b' P+ s
复制代码

2 z0 e' J* j$ T! _2 S2.初始化时必须对LAN8720A 进行硬件复位。
4 V6 @+ P1 s( W/ b7 l' \解决办法:
$ [' U) B' t; Q
1 k8 p! L9 L- w1 w' z) M分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:9 f5 S2 {( k' {
2 J0 I! T: |) A3 b
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
    2 u3 K! b0 M4 P5 j

  2. 6 X+ o' h2 e% C4 o. H) F, W* h* G+ ?
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    2 n5 w+ A8 y+ C& N; Y1 r

  4. 8 ]: H5 ]5 c: |3 O7 B' ~" l
  5. /* USER CODE BEGIN MACADDRESS */& N( I% L/ `+ V  y% b# e

  6. 6 M  h5 f" _0 o5 q1 c
  7. /* USER CODE END MACADDRESS */
    5 ~) n: x4 [' U5 B" O. o- g% N

  8. 3 V0 C2 f6 P( P
  9. LAN8720_RESET();// modify by kmsmg
    6 P3 Z# y! p) g+ J% k  E$ l

  10. 4 {& J' B. d' A
  11. hal_eth_init_status = HAL_ETH_Init(&heth);
    1 j2 V3 @4 e) N! M$ @' P/ c
  12.   f! d8 p5 E$ ]% Q' f0 n, \
  13. ............
    ( ~7 `) e4 H. f

  14. ) g3 J$ Y. w$ O* p; P5 O; x
  15. //------------------------------------------------ ]/ _. C- y& N

  16. 5 t' ]( Z0 m: o2 H
  17. void LAN8720_RESET(void)1 q: M3 w, d; `% x2 L2 K. k- ^( O. a

  18. 4 R6 q: A! h6 K9 G# }6 Y
  19. {! D  _  V5 L% A# T3 N; G3 a( k
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);- r7 M1 ]2 o; Z4 R. I1 W9 x* o

  21. 4 m0 P' E  `0 M* E5 l; P
  22. HAL_Delay(55);; R9 P3 K- C! A7 F# g& D
  23. ' e6 E& K" Q" l
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);2 m- G" c0 ~7 g7 z$ c: ]' c
  25. 3 \, _0 x9 Q8 o* Y8 Y8 m' K$ M
  26. }
    ' ~# T: W5 E) k5 J1 I4 f0 z/ E
  27. 1 e( N0 h6 M4 h  l3 q7 h
复制代码

) F) b7 w. U9 }4 g0 T/ n- |' r9 G1 J% f* i- E+ x3 g

7 {2 O2 p, ?6 B3 i- @/ {( i8 B8 P! P( l
收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版