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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH8 D( s! W0 z; b
6 j( S8 _. u& ^
20210402161452602.png
% x1 S; [/ e9 P( ~; p
) _! I8 H+ ~) D4 u: `( U+ I
20210402161514595.png

# G, e; Z# k, I, ]* `+ k, j. h$ \+ q3 [* S1 s+ e3 \  |
20210402161532893.png
) j- C1 J  m# P! O- l: J9 L# {

0 V- f6 i1 ~  I! c+ t配置EHT_RST引脚' a) o- O1 E( E" G

9 k+ N! d' v3 J& e, |7 [
20210402161604234.png

0 s0 P( E2 r/ C6 S6 n+ s( t% x+ p1 T) }
LWIP3 ]# X) ?' K% r  g! f
* v8 N1 s+ x$ w/ Z  m* w
20210402161716753.png
" \; r" B$ t+ c, e& N! s
  m' g6 H/ a1 O! {1 ~$ b
20210402161746306.png
/ ?! z% w/ B4 Y
# {* l! `1 [5 R6 ?
注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情
0 [: Z7 \) f& X7 {4 k! v7 q/ s' W  t! H
" J( i$ _) W6 L5 {
20210402163232833.png

2 }8 i6 y  ^' W( L. v
* \& t5 ]' c( _; O. I5 I% ILAN8742
+ D" A/ _9 H  Z* w+ c3 ?
20210402163258853.png
2 X3 v" F2 g/ F7 `! C8 w
, n6 D  @7 U% a1 b$ b7 I0 C
MPU+ O  A+ I$ T8 s0 d" k; m
Lwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。- Y" N6 b$ l- H0 _5 J& R2 M/ a

5 D* @+ i: {4 g  H! T: n. v使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。, {4 e$ B: C9 M1 S/ Y/ a/ k# c

- O  A; w; |9 G2 L6 k% x2 f9 Y$ e
2021040216385026.png
+ W* a# b. P- h6 T( }' j

7 L+ a& R+ N5 m' c. p+ H5 ~5 D
20210402164922519.png
6 P' [5 r! D! H  b# `/ k# B& E
% P( [' W9 @6 ]* Z) G$ P9 Q" Z; A
20210402163942899.png
! B6 x3 A6 y3 \6 c
* e# O# p1 N% E: m/ T* t, v/ T  P
- ?4 p, r6 n0 [/ j' e- [; @
MPU设定总结(非操作步骤)) M- Y+ ^4 C7 r! k2 F5 `
总结一下这样做的原因与目的:
8 |' r( M) |7 w(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;" }( G8 Q$ e( J" [
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;
: j' o$ `7 o$ n, r(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。  w0 I6 N+ ]+ ?. k8 g# F

% J9 z8 k2 B# u4 W# m5 u5 B6 ]3 S
20210402165153856.png
' I' Q6 N/ b8 K! L: W
+ h5 C1 |4 b+ K
MPU选项含义(非操作步骤)  f) R. }# E9 J9 U& A
cubeMX里面配置TEX、C、B,三者搭配。  E: X, W3 x+ I/ ~+ o& {' a3 |  C
  d0 O7 S1 M! J6 f: A
20210402165235835.png
* j/ L: k# \. w$ s
! R; t/ i- \2 j/ Z' i2 T; |- s4 [, |
4 ?) o- T( [7 O; o
Access permission被定义为3,即Full access。+ |+ \& _" j! F5 a5 }& r
$ _! Z. P1 T5 x5 [/ _% c* V+ k
20210402165246437.png
% ]6 ^# V2 V/ F3 D

7 Z+ N0 u: I. [8 L) H经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。3 t% R* i8 j  d; s/ `. d
3 @' s" M0 m$ W  w: N8 s$ m' ^# Y- |
好了,可以进行下一步!- E2 L8 h, f( `3 ^) d3 c

+ I0 E7 S5 u' B$ j7 G, b, P9 e4 ?Lwip协议栈TCP保活(KeepAlive)设定

4 o/ ]7 y- D6 i万事具备了么?no!2 r4 I! [" C+ W

: A2 c  p% |# O8 q以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。- i4 j- ?* J5 E/ j+ h  s
" |- o" v' u* _8 E5 I& S
有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。
" ^9 J' q8 K3 i( {0 q6 m" t0 m0 U" H- B2 g) L. h7 o- q9 |* h
由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入( u! Z- ~0 ~1 p; u
1 _6 j6 n5 n; X
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive
    " k6 w8 q+ c4 z9 w
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    $ K# Z) H) c8 {" m
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测
    ' i9 J6 O& V" K) T7 [8 v
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码
' z% S& z' X5 i/ a5 z2 ?. V/ A
tcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码
9 J0 ~6 d6 e+ P6 h1 W
这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。
$ K6 b5 ]. g1 L5 v9 ^9 o电脑IP :192.168.0.99
7 Y* Y- G' i# P单片机IP :192.168.0.80; W! v& v4 x. S- ?& Z0 B
- q" O6 k; X; P8 F' j7 N' x! B6 |
20210402165445842.png
  ~" g2 I2 f3 D
& c- e; @$ ^! w4 C
自动化流程为:# D' h/ p% G6 A3 f- w
拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接
' r5 n2 N0 t$ [8 Z- x5 B  b6 \" ~  `如此往复…
$ t1 T+ Y  g. l* L. `+ O: }) z8 u9 M0 K; \
用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:: B. l- p- f5 R% l; \: _$ s
1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
  J: U" ?- c( ^解决办法: 在 …Src ethernetif.c 修改如下:$ ?; F+ Z' |) E$ ~* A7 N

: g8 ]/ l( L6 u1 M6 p2 ^
  1. heth.Instance = ETH;/ t2 H1 E1 t  ?  f  A

  2.   w  \! |& D" S/ D+ ^& ?& M( o
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
    2 Q! Q1 R6 p2 x! j/ S" }3 C
  4. + t6 q: N/ K+ O  O; |
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;5 c0 Q) X7 \; g  a" i  n2 @5 |0 B* ?

  6. / v- _8 S3 ?, E
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1
    + g: J0 j* M0 h+ ~+ s- Z
复制代码

* ]6 w7 l1 B9 K& ~2.初始化时必须对LAN8720A 进行硬件复位。5 y, x0 U( Y4 S0 ~+ ]
解决办法:0 q+ S  R; x' ^# m6 b
% k4 n* b2 T) L& T
分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:
9 I1 S+ T# D# d& W+ U- \4 J" Q' @: z
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
    $ p" r* T7 Y  u8 G4 o/ Q7 [7 s
  2. 2 e( G) J+ Y6 Q' _5 [; L/ f5 R
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;  W- g6 A1 ^! M# y
  4. " O0 T, x- Z" Y* e8 L
  5. /* USER CODE BEGIN MACADDRESS */
    & d2 I* I: }) {* J# ^9 l- Y

  6. ' Z6 C6 {2 z: I  I, p
  7. /* USER CODE END MACADDRESS */
    9 r) J+ D& a+ t" m' P5 m1 }" |

  8. ! U, |; ^+ S) _4 K9 p
  9. LAN8720_RESET();// modify by kmsmg
    6 n4 e5 A+ h- ?0 w$ b- y4 E

  10. ! K- c. D( R) Y) E; }
  11. hal_eth_init_status = HAL_ETH_Init(&heth);
      L$ f, d0 R% l

  12. . Q/ \0 \( |9 x" G$ V8 E" {) E6 u
  13. ............9 S( A2 N) M1 w8 w
  14. 6 a) V! u% l. C; e8 @# e# o( g
  15. //-----------------------------------------------+ D; [5 P" g! A7 i4 o2 x# G9 Q
  16.   ^6 m$ }( F5 L" F' A% M
  17. void LAN8720_RESET(void)8 S4 [( v6 [, X: ^: ?/ T

  18. 0 O5 m2 ?2 k" o9 J* g( ]* \
  19. {: D: T. X3 F" o
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);; r% n. [# Z7 U8 k

  21. 8 ~) H, M. o" R% A7 a8 P
  22. HAL_Delay(55);5 H" k9 P2 n8 F( ?* T. H

  23. . G/ `2 ^) P# P2 o9 {, w, v9 A4 n
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);! r) E$ h% T) b* h( A. w
  25. " w1 R2 {8 L% W" ]0 o- I
  26. }
    3 k% F% i% w  p5 e
  27. ; D: y& h5 p1 h, M
复制代码

1 ?& Z& C. }' Z" d2 L3 O; ^/ q4 [. ^* n

& h6 j7 K2 N2 c, A6 o
收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版