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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH/ h5 n& N* F! o: j+ h7 R
1 p8 w& h; Z+ n$ \. l5 }: N
20210402161452602.png

' n- F$ {8 I5 C- Z3 O
& l9 `! v6 ~, C8 N9 t" g0 |
20210402161514595.png

$ N9 t& _9 _. G2 j+ F
2 _) }: d" V0 J
20210402161532893.png
! t0 n3 R$ }* N- R
  ^: r! b6 k0 k
配置EHT_RST引脚
  U/ ?( P& `9 t: d8 p4 Y* Z1 g& ?( e3 D
20210402161604234.png
5 ]# d7 F4 M7 F, x7 q" g

! f1 C+ |- e" I3 N' ELWIP; C- x( Y" Q( W$ ^$ P& P$ J7 K

: C& s9 B5 o: C$ W% F9 A2 \8 r( J
20210402161716753.png
( p" V7 S, R0 ~7 j! M

$ e2 H6 C3 l1 N
20210402161746306.png

; P9 R% z& _; q& d
& k: ~  D" I/ b5 ^( R4 u2 [注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情; D$ u! {: I& y* b2 c, m+ B! H

3 {) v2 j" X2 G0 u
20210402163232833.png
. Y' d+ |6 _% J

4 X) @: h; l0 c: LLAN8742! a8 J5 {$ D# Y- m: y: }! v
20210402163258853.png

) v, d7 d8 @6 b  J
8 ^* V. W' Z/ k+ gMPU
+ ?. s5 y$ h, w1 eLwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。
: b% j3 P: Z/ b4 L" R& f9 G
% H3 }/ n9 o' ^- r4 U使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。
$ ]0 v7 n) F7 ~: V. g# I5 H- D2 R% L  ~, K
2021040216385026.png

& @4 ^  u- J. N' ?% l5 t- x4 O; V
% u$ R' h" b# X$ n4 w
20210402164922519.png

! _# {- L7 x, `6 [3 i) g. ?4 {; Y9 w, l. D5 E
20210402163942899.png

" S8 F! Q3 T! _
3 s/ z6 G/ j, I, R
9 ?* F2 N9 R- ZMPU设定总结(非操作步骤)
7 _* A" T3 P4 x总结一下这样做的原因与目的:& i  i2 M6 U9 c  v
(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;4 Q0 P! h6 U0 ^5 o3 r, C
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;& Q6 ]  L3 g% k, v
(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。% g, a2 ]; z& ^0 |' x# }

2 B2 L; }  K# M$ g/ ^) R& h& W
20210402165153856.png

9 B' |* _+ }/ c# n' B/ D2 \* L# {9 `( D" z
MPU选项含义(非操作步骤)7 z9 _7 Z  S7 F& G' d
cubeMX里面配置TEX、C、B,三者搭配。" R3 ^: F! G8 s; R4 ^

# o( d8 j6 T+ S1 h0 A2 z
20210402165235835.png
- ?; _3 Q' `% x! X, Y- w% p! g! F

# `" f4 X4 H7 F' {, e
) r9 ]/ S$ p9 l' J. ?' xAccess permission被定义为3,即Full access。: i3 L3 T: ~5 d- {: f

% m, Q4 j. _% i0 r3 k# _  A1 h. G
20210402165246437.png
; d, y/ R  d, {7 o* E7 @
8 h8 G' \0 Q2 e) f8 y0 d% s
经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。
0 M( k8 s' Q& G3 Y' Q2 A- D  |( ?& Z- s+ Z, C9 o2 A# I& Z
好了,可以进行下一步!
$ B6 Z. ]* \% Y0 i
* g1 f% C$ A6 ]# nLwip协议栈TCP保活(KeepAlive)设定
9 ?+ D5 g. k0 o. x" z
万事具备了么?no!. _8 N, C9 I. S( k( D' N( |

" X7 Q* f! b: D; [" L- m5 `以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
/ E; E7 X* B; h) l& k; t; q: S" A$ D% j, m" z5 X$ N4 _& e9 @
有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。: Q: I) s- A# u( w! r

" A% l& }: A  K1 Z由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入# M4 b8 M) y- T4 r+ g$ o
3 K2 o' A+ `/ I' L0 ?
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive
    / t, u( @: V; P
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    ' h2 c! W* C* F# w# s4 i: n
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测9 ~& `5 _0 d* R- A2 v+ }6 @( K
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码

/ [2 r/ ~5 S9 ]) q1 ]3 N6 _tcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码
' v, ]! ]% R8 P5 a4 w& O
这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。9 \  i8 x7 I( |; ~: ]/ k
电脑IP :192.168.0.99
, m# n- I1 i9 ?0 z1 q* Z& Y7 g$ }单片机IP :192.168.0.80' u7 j$ N6 R& d. i  ^0 \! S) t
. J  m9 ?+ d( U( ?( e9 c: Z
20210402165445842.png
) @# y1 t  D- B

2 |( I+ {% r4 j# y( J自动化流程为:8 X. a$ r% I/ N& f# \" c- {$ J8 ?
拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接
3 h" Q- o( q: o. L如此往复…& \+ J4 \" {% P

4 ?3 J0 }2 |/ v2 B! Y. w! A用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:
4 c. [. V2 o7 J" J- n1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
# B. ]8 {% V( Q: I" Y3 n: h3 F7 C解决办法: 在 …Src ethernetif.c 修改如下:
( h' i2 d5 g: b8 X* g) k
& {5 m$ v7 _" }! z
  1. heth.Instance = ETH;
    4 `: J8 B# M. C( l. ]
  2.   t' E% I3 j& u1 b, n
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;6 B+ w* j5 J9 f* r

  4. 0 H+ V+ Q" \' h1 B- I
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
    , \. F+ U5 B- {. U& T$ i

  6. 2 p* O/ q! b: Y' f
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=13 Q0 [2 o! Q9 k2 `$ K4 E! }
复制代码
8 ^0 Z; V( D( S4 v
2.初始化时必须对LAN8720A 进行硬件复位。
* B" \4 t% W0 [5 e( h: b解决办法:
/ G4 g  t) `& r4 _2 t" ^+ s: k2 v2 i# o: x% U& f
分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:5 E. H2 U. p! {, ]* ]
* i* m. v. F4 L
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;0 {( Q% f4 P5 H* [0 Z2 R

  2. , I7 s5 C* D  p5 j! a; s8 N
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;* n+ _4 `( l+ {. G$ e% i  {

  4. 7 X/ q2 h9 Y3 p1 ^
  5. /* USER CODE BEGIN MACADDRESS */
    ) J- E* U2 y' f9 j, o

  6. , L6 |9 w' x' ^3 ^. W9 `/ o1 F
  7. /* USER CODE END MACADDRESS */
    # A9 A0 L/ V5 Q# h0 C
  8. 1 B7 V$ J, {' w9 U( ^+ i) w
  9. LAN8720_RESET();// modify by kmsmg
    ; U5 J3 ]1 w: q. A% L/ U
  10. 6 a4 X0 C' y0 D% M6 M% p
  11. hal_eth_init_status = HAL_ETH_Init(&heth);6 V% n8 o7 a% ]5 R

  12. + |4 n: V$ ^& q' l
  13. ............
    . ~8 l6 w& f, C2 m' {

  14. 2 X& Z/ u# H+ }1 Q9 g
  15. //-----------------------------------------------# u( p3 }4 s) n1 o0 X

  16. % i: e  Z0 @6 i. o$ A4 ^
  17. void LAN8720_RESET(void)3 i6 e: p! m0 C1 F: W: |1 O

  18. " y9 E$ p1 O5 ~# `+ }
  19. {
    * m! z/ E1 g8 x" D& M7 j
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);  s0 \2 Y6 J; C; v" k& j# D
  21. 2 j* h) g, D4 p, J+ `
  22. HAL_Delay(55);8 n6 {" k" d- X+ Z: P

  23. 0 N1 Y- x/ }, H! s
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);
    ) @, p! |; @6 J. j( x0 t9 F: a2 ^

  25. / U; ], s# R0 U* }
  26. }- k% C; K6 A4 X

  27. . A% M" n* Q; `8 D* e
复制代码
; B5 I9 G2 r$ k( U8 E$ M

& @1 n1 ?9 P  P- G, O) W9 O
6 }2 y4 B5 C9 B1 C8 i
赞 收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版