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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH
: }0 P  [5 b% i" G0 P% G, x6 R9 @' }$ D% Y/ g
20210402161452602.png

5 y% O, j! z: B. {
: e% n1 j( _, X7 \; v9 V% O
20210402161514595.png

( R! t. `" t% Y9 ]4 H8 f( _. N+ C# s& w
20210402161532893.png

. w3 b& X# H3 p; w9 Q
2 u3 e; m( A0 F- ?  M7 O  G4 M配置EHT_RST引脚
$ Q! E2 z. n- E. E1 j7 u4 s5 }, G  W* o; }6 W5 ~1 i( j( o1 c
20210402161604234.png
* s( P% ~* c' ]2 Z

2 L! v: o6 f- ~) [) }LWIP7 W1 [9 G2 _) U) p

# b' T" Y. b2 e& u3 Q3 W
20210402161716753.png
1 F, z5 Q/ u& }- _- g7 j- M
5 T' M9 L1 }  M* W6 H" R3 T# ^! e- p) U* ~
20210402161746306.png

3 f5 Q6 ~/ X% C; a
, n7 `4 F4 x8 f, L注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情% A2 s2 o- }6 a. Y. o, f$ O; q

& ~& U& o1 @) o  i) ]+ @
20210402163232833.png

( y3 g" L( C0 _2 M( K' {
% J! C0 ]- a" M0 M: {7 vLAN8742
6 c4 O2 F# L3 G2 @8 q
20210402163258853.png
* i% i6 L, d. z6 }
- m$ ^: ?; u3 Y! q
MPU: G3 a- F5 J( g. a1 q9 `" O
Lwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。
( s. U; G8 h" U, C8 }' J% B
; H' H" H- n& X) c. o使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。" M6 I' p+ c9 Y' j- s+ L
' T( g5 \+ i/ r6 r; n1 r- A
2021040216385026.png

5 z5 m- a8 p* f( |9 d
/ G7 T( ~+ Q/ t) c/ r- k, @% S
20210402164922519.png

+ }1 ^9 [4 j7 y: V. b: L1 N/ ]
0 q; b# Q8 t6 h) ~
20210402163942899.png
+ Q2 j5 N8 y& e, W7 k/ P7 Q
- o9 i5 R  i  b
3 q' C; x: P7 J5 q
MPU设定总结(非操作步骤)# L& I+ e, t, |
总结一下这样做的原因与目的:, R* \' G, L- K4 ?6 q6 L0 R, p
(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;
7 }$ {! _" D1 `(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;
: w, ]0 C% D9 I  G. j(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。2 B9 H9 m+ L5 z% e

* |+ h2 S1 l+ x% R/ V7 x' h& q# x
20210402165153856.png

2 w; }- r' {4 A0 u& r' P' P9 e
5 E% f" S4 W  yMPU选项含义(非操作步骤)
) G% U1 ?* J4 g8 s: ^cubeMX里面配置TEX、C、B,三者搭配。! n, Q  ~* [6 J% f

5 G/ I5 ~. h8 j: D8 x
20210402165235835.png
: U! |  |9 p7 Q
$ k; ?3 ]! @: j) l% y! W
% b$ F8 e: s- P4 k( x- B! o
Access permission被定义为3,即Full access。
( f6 v2 {) s, y2 `
/ P; K: ^3 S0 R* n
20210402165246437.png

9 u2 [. r$ `/ e" B, S9 Q( A- v7 l$ u5 H- c
经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。5 T; ]! }1 r  Q' G4 |* H
! j0 V- b; u% B( C
好了,可以进行下一步!
# o- K9 F0 B( C$ }# F5 C; \# N( n* G" {, [# u" K
Lwip协议栈TCP保活(KeepAlive)设定

$ b& m# u  c( E6 s* u( }万事具备了么?no!
) d/ V- s; p7 K& Z# c# H% w* s" s% I' C& s
以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
% ^& f3 ]! Q4 Q* V1 w2 {% {
0 m; y) d8 P( Z/ h1 m有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。
1 ?' N# s. M7 {2 G0 [8 u
5 H1 J3 z# ]/ A" w由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入
  r+ v% P3 h4 ?& I" z# ^$ E7 A, C; G. ^" k' j) \: p+ n  G
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive& e& w) M$ c8 @" B5 X
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    ' o0 O% Q) i$ J* s; C( M4 R
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测9 r3 d! ^+ O& O8 O; w# |
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码

& J' D$ g- f- V' v6 C# htcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码
/ o" N- R' {! e
这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。+ N! H/ k( U. \) B: ~5 I
电脑IP :192.168.0.996 v  u* _, F9 Z* O( I0 O9 K  J
单片机IP :192.168.0.80
5 f6 l9 ^. R& `4 n
% H/ p/ r; O+ X( I* i, ~
20210402165445842.png
# Q& T* B+ [: O0 j) ?, u7 ^1 w8 j

& X/ x$ ~' C3 [/ F/ E! o  ]自动化流程为:
. r- Y$ J" E  d' y4 z+ Y拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接
# G2 K" g0 s3 A5 o; A! E如此往复…* V4 M. z# g- M& @* }5 V+ e

$ `0 f0 D, @% s7 {' ]) Z9 V用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:
/ w+ E; a0 \4 }; b9 F7 q) U/ U- _1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
+ @# L0 y# C$ s, \( o3 k: N6 b5 v解决办法: 在 …Src ethernetif.c 修改如下:
- D( @" _; B- Q; ~, G
' n! R! J  X/ U2 D  U" {
  1. heth.Instance = ETH;
    / p6 y0 X9 `5 f; s6 ?# {
  2. & `* v5 _1 N5 I8 B3 y: v- C
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
    9 C2 a* p7 X0 I) ]% D% C
  4. . ~" @, E+ l# J  R' C* d
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;5 H6 {( }+ K  ~7 O$ d

  6. , s0 {# r, Q5 |  r
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1+ \: Y4 ?6 n+ d) q( R( k$ E
复制代码
! N) }# ^. D8 M/ T
2.初始化时必须对LAN8720A 进行硬件复位。& u6 ^0 v8 h' Q- k
解决办法:* d, v: p& _# s2 E* n8 X9 a: J
, p4 b) C7 [7 s; M8 p7 _( H
分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:
9 v  Y) T6 S0 ^! d
0 F0 p6 F3 w; n7 o* Q* Z
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;* ^' U& `/ p. n" J2 v

  2. 3 l, |: E9 m( f) [4 J' U: }
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;/ G5 e" {' r; I. z9 m" e

  4. 5 E/ [3 S- p& b  J* w: H
  5. /* USER CODE BEGIN MACADDRESS */0 N! a- \$ K' h, T# {8 N/ V

  6. 5 N$ k- v9 i$ D+ G1 x& j
  7. /* USER CODE END MACADDRESS */
    . {# `$ t2 d8 `7 X: ?+ o0 q" g
  8. - a' ~2 I, A- E6 B$ @
  9. LAN8720_RESET();// modify by kmsmg
    ( [2 c6 r# [0 ?0 m$ R7 S

  10. * c! w$ i: o: J! B5 k* s
  11. hal_eth_init_status = HAL_ETH_Init(&heth);
    # J3 _4 }0 n+ ^% u) i
  12. . l: b8 E! e/ Z5 o4 V' w
  13. ............! l* v! b  O5 t" G1 h; ~

  14. 0 j; g4 G5 {( j6 N# i9 O; i6 `
  15. //-----------------------------------------------
    1 |$ h/ X5 {' B( i9 u
  16. ! ^- t5 q, W+ ~0 r$ I" Y
  17. void LAN8720_RESET(void)
    1 T9 B2 Y: j0 c$ Z- z
  18. 0 S+ [( j( z- r$ t# A+ x  \" m3 `
  19. {
    1 c7 y6 S5 W/ w8 f
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);
    3 v7 m( Z& M' L5 h% A) r8 ?
  21. 2 I. K% q/ @0 d8 w7 K
  22. HAL_Delay(55);6 f' s, X' Q4 O7 D. N7 p' U- ^

  23. ) L+ q8 a8 b5 U% ^# o; H
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);2 y0 i2 B" B8 @' z
  25. $ A$ ]1 m% o, `0 W; g1 C1 r& @
  26. }' Z. ?' i# S: T3 O* X  {8 I

  27. ' A4 Q/ g( _" Z% h) b
复制代码
: a" V; ^- m7 r8 z
6 A' C2 g; e# B3 `) @. `4 x
1 B6 @5 s% V4 ^( X9 a
收藏 评论0 发布时间:2021-12-26 14:55

举报

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