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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH
1 b5 X6 R1 z2 J8 G2 l
* }& N, Y5 z( K% j% A' ?
20210402161452602.png
! _9 _" K' [; h% W$ C

, s* R" _4 h% X$ _
20210402161514595.png
% ^# S: y& b% T7 |" A4 w

6 f( e4 X. W* S: u
20210402161532893.png

& @, P3 Z- x6 j, @; K
! {$ ?& w6 o3 A) J! B4 `配置EHT_RST引脚
- k8 O' f5 Y: U7 d2 ]. W) v% \
" C! @# p0 ?* R; x  g! i' a
20210402161604234.png
# z. `$ ~- n6 ^9 f2 G8 g! ?
( i$ j) j! C+ {. j% g
LWIP
9 s$ `7 f1 n4 n5 }2 Y
) D) ^" [) `1 o0 I$ E
20210402161716753.png

5 R$ ~" h" m5 `0 S8 o+ X- ]! d/ g* K* `& F% N
20210402161746306.png
1 [. W: _/ D0 i; P0 y9 C

2 C" ?# k3 S* @+ H1 h9 ^, y8 k注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情
/ d) O( M: H7 i: E, @4 `! \& c( r6 m/ i
20210402163232833.png
, N8 A$ ~! k: p% L0 f

, Z& V4 r9 [, j9 h  N: [/ XLAN8742
/ h# l8 d+ S2 A3 q
20210402163258853.png
7 g6 o0 n9 V  \0 f' U9 X  Q9 Q

% R2 y' o4 ?9 w% O7 T* N4 MMPU# ?4 [) ^/ E- g+ y$ u" |- V
Lwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。7 _% E3 m. L6 k/ @: y) D/ ]. P

8 j. ~% C& A: f. e0 I0 p1 s使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。0 l' _" E2 }9 D7 R
* j: ]% v, d6 `* T& x, h1 U" \4 w  j
2021040216385026.png

# V+ x* w  i) k+ J* |2 A0 V$ Z! O
20210402164922519.png
3 w' b( g# `4 R1 w7 k2 H" c

, e# |$ t  _# _9 }( q3 \% m; `
20210402163942899.png

# U  j9 H0 R- m* A+ V
, c' I' c6 H) Y) X
$ P7 M& a" J7 `$ b  h* I6 y" N3 PMPU设定总结(非操作步骤)
$ b2 z5 ]  i: g7 k总结一下这样做的原因与目的:) F2 `! I! s5 ]. z8 `
(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;" b$ H- `$ p1 d0 r! x/ Q( x
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;
' b: y. ]; `) ^(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。" K& |! a* M' @' R5 \$ [
9 |+ W* O; W; r
20210402165153856.png

( {) o) c, j4 ]/ M  `
" i/ l7 ]* K4 Y4 x( bMPU选项含义(非操作步骤)
% m6 q4 w7 _7 f" pcubeMX里面配置TEX、C、B,三者搭配。( z  X4 w3 Y; y$ O6 u) i
4 o: U- g0 n+ y$ P' h, W7 P3 `7 E3 B
20210402165235835.png
7 h# d) ]0 ?- s, |( l
. w( ^: f2 g. n3 M% x: f8 X# v
6 ?: N5 F9 y( D6 K
Access permission被定义为3,即Full access。& T& C; P6 I! s) m/ @0 m- h0 {% u

) D, T5 S! n: a, Z* l3 W
20210402165246437.png

+ E6 O1 `( ^& `4 R3 d9 P+ M. _8 i( P* |
经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。
+ M* t- y8 r0 D( F) @0 y  a+ W6 E7 u% \  ?4 P
好了,可以进行下一步!  @2 y4 L) e* n
$ d8 O* D8 c* p; w3 }/ J" X7 x
Lwip协议栈TCP保活(KeepAlive)设定
# l  B& u9 v3 A/ v
万事具备了么?no!+ v& n9 l- o# U1 o: Z6 }

  i% q* m, W. b6 p  D  Y以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。2 H# R- e) a8 E
# F& x  v& E0 M% ]# o4 y9 C
有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。+ c9 T) @: D! @+ _4 X9 p7 Z
* z6 i5 g* i; {7 \' P/ N2 b; W+ a
由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入( o/ v- {  j9 j
  U% t) f, O( j" s1 M
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive# m, @! p! ]5 Y$ n4 `2 R
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    6 f' G9 W3 L* M+ n
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测
    " ]: E; F- @/ z# m" x3 b
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码

# b( N* u8 N6 t: N1 d6 Vtcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码
0 O0 s! {4 ^0 N9 w3 |" Z8 t
这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。( m2 g6 i1 `( Q0 E
电脑IP :192.168.0.99+ X6 Y' w6 s! T8 d' T
单片机IP :192.168.0.805 \: z) H5 `) c" D  |! r# o

0 ~1 O  g) \- y2 X
20210402165445842.png
2 K! h$ K( [" t

/ Q) `5 s5 f% y1 p! s2 m自动化流程为:/ I( f1 b! _2 t: z$ |
拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接6 [3 a2 k4 M1 i% a
如此往复…
  x4 Y9 N. u5 \! J$ I8 K; J' e0 z, H/ E
用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:; r, ^2 V$ q7 o7 u
1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
2 i' |+ x  I% E6 g6 ~6 c解决办法: 在 …Src ethernetif.c 修改如下:+ I7 V9 M! A! E" B
: K0 v6 L# j3 ~! r( y8 D
  1. heth.Instance = ETH;3 ?, d8 e3 @% X. U( @! x) `- C+ Q

  2. - o  x  N: w2 p: Q
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;5 ?7 E. o' ?3 e% y8 C
  4. $ e& O- _6 s) h3 v. q$ a" S
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;* O5 w, b9 ?& B1 \# d; U5 {8 X
  6. # P" }6 K& U+ q: b- |
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1+ f: D% I+ ~7 w& `0 n
复制代码
$ l9 T9 {8 f* T
2.初始化时必须对LAN8720A 进行硬件复位。. D, s+ ^$ p7 A' d, `
解决办法:9 Z4 K, |2 X4 `" p1 b
0 y. _' Q7 l3 R- Z7 ^+ e, k/ Y* H
分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:
  R% f# I* U( Q9 D% }6 {/ v, [; F9 c1 V7 u) K! t2 f
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;) t- m, X1 [/ l7 y4 I

  2. 1 R  \9 r5 `- E+ W
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;6 ^& y( h4 z) n6 J* P9 \
  4. ; u- |/ `9 ?! N2 s2 \3 J7 y
  5. /* USER CODE BEGIN MACADDRESS */
    4 p" `4 l5 L/ ?# {
  6. ; `5 H' H' g) E9 A
  7. /* USER CODE END MACADDRESS */
    + d/ P( B$ ?8 g

  8. # a- A5 x5 s+ F9 }! A
  9. LAN8720_RESET();// modify by kmsmg! {, p+ q, N$ E4 t) M
  10. , G6 j) _0 g6 g$ ]. s
  11. hal_eth_init_status = HAL_ETH_Init(&heth);/ Z& W) e/ W3 Q% y6 [+ Q( E8 [& f
  12. + I" L% g6 T1 H$ W' `; g$ m, a/ U- J
  13. ............
    ( ^+ P$ y- R# N- |
  14. 8 x1 `3 h" L. P' [+ k2 T* z8 z
  15. //-----------------------------------------------2 Z0 }( {  e+ E1 g, y+ J

  16. ) D$ I  r4 ?2 v3 i7 Y" l3 K- w/ w
  17. void LAN8720_RESET(void). U0 a& X7 ~- z5 ~* M

  18. " o" R4 V! r. [, z7 i! d3 I7 o
  19. {
    " g% J6 J, z+ C
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);
    - z5 Q1 A2 ?8 |) M0 w+ J

  21. % O3 i4 e7 j8 V
  22. HAL_Delay(55);
    1 r# i7 _8 D5 \* T! g, d
  23. 2 L( @' j: H' Z( ~# Z9 A3 Z, n6 v
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);0 U/ _8 u1 h8 f% Y3 L) T

  25. # @( B0 @, m# a- U. r  c
  26. }
    6 V6 o' {( H$ V% o; I; Z

  27. * a% b7 t' ]* k
复制代码

, b8 n0 ]( T5 _* |- w2 ^; B; I( X6 F$ [% Z& H$ m
8 T" E1 T1 L; R/ s; X
收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版