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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH
, @5 \5 X5 V( M+ a2 ?  F. u, Y5 Q1 O8 b
20210402161452602.png
8 V2 z7 Q" H1 z1 M( [) t' v( P% \

( j* G* k" `0 @. s& G
20210402161514595.png

+ J1 I. v1 N" {- T( E
0 P7 z/ y0 O8 X; S- W# ^
20210402161532893.png
& V( D1 N6 d. ?& p; E
9 |/ m) T) e) R9 n2 a
配置EHT_RST引脚
& u- w% [; S$ ?% X( q4 k/ C+ U6 s6 |/ M2 q
20210402161604234.png
' S' N+ \2 n7 N9 y. s  ]
% ]2 p/ B  e- Y2 P% Z
LWIP
; v  ~% c. i3 P9 k7 t2 K& O0 u+ z" x* A
20210402161716753.png

" }" }- e" @8 T+ u6 H* C7 c- T4 n: V. N( _3 }- `0 F
20210402161746306.png

0 G* G: S  m; h, n) }7 k9 d
& {& f5 h& x- U" M; w注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情" X' C! S0 [0 }9 V) k% z. G
9 r' g9 m) F' X
20210402163232833.png

9 q+ {" U, W2 o. S; s2 c) {1 n$ p; {, V/ f' F: W8 @7 d) J
LAN8742
0 s# m3 i+ P0 z+ _
20210402163258853.png
3 e6 q, B0 L9 f: W
# W5 ?8 H9 ~- E3 }! V; L: t4 J
MPU
& W1 e  z) W: Y; f4 a$ JLwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。
* p5 V, r- E+ p( m# f" e
: }' ^1 x; T" W/ p$ P4 z; T) H+ f( Z使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。+ Y+ N* P. O$ V' }; s- X) }) C
; }5 w9 B$ l, |, Z! ^9 L
2021040216385026.png
( i1 P: ^8 U% u2 ~$ i0 K& E
, e! L) W% w) Q& j/ W  m# |' D% T
20210402164922519.png

" g7 ^, }9 ?5 t4 c! j& K+ e5 N0 B0 w  K+ w
20210402163942899.png
8 e) U5 v/ q6 i0 B

, D) _) U' P6 n, v& H! A; X1 p' T! [2 ^+ B" M3 y2 O/ `7 ]8 A
MPU设定总结(非操作步骤)
: @% L5 |5 d* k3 K( j2 g总结一下这样做的原因与目的:
  {0 l$ L. G" L8 c* P(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;, D9 i6 r( \& V0 N5 Q; Z* b
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;* H+ a; e. m. A. n* @4 P
(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。4 G" a0 K" W; g" M: w
9 r6 z8 _8 \7 z4 B
20210402165153856.png
# i# ^, ]  N- a+ U1 t

& n/ a+ L7 x3 A) i) d2 WMPU选项含义(非操作步骤)
: ~( [& A1 c! S$ XcubeMX里面配置TEX、C、B,三者搭配。
  h# R& Z( u, h5 J1 @! l+ C6 U! l/ L# t. N0 \, G* G$ z
20210402165235835.png
" _& z: e6 A2 k7 o
! V  y7 g/ J+ t  R2 X% V' h, S5 |* e. `

" c; g0 Z( {/ n" O" TAccess permission被定义为3,即Full access。
2 L5 G8 I# _' }( H! r. s6 p+ g% J" u- Y# ^0 t6 T0 Q; s
20210402165246437.png
* @/ v3 p  a5 z$ _

) T! D) D% h5 A4 E' g+ C经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。
9 M% z  f1 n$ |" s" _& u6 G$ G) T+ D2 \5 K$ t$ \
好了,可以进行下一步!
' Z. q6 I8 U& s* \) ]+ B( `8 Y$ J( r+ y
Lwip协议栈TCP保活(KeepAlive)设定
  E8 x: E: _& [
万事具备了么?no!7 l. u9 Y+ }0 _9 ?$ m
$ Y9 X- }) _3 g6 U$ H/ a! T7 ~
以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
4 n; k- u6 ^% ]" T" ~, R, W# S
  a, H- n& Q# ]! a5 f5 d  f5 H有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。  ^' i( d7 M4 ?6 Y" q4 r; c

$ z  t8 A& F9 {/ r. p8 b由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入2 }7 _! k2 n* q/ r: Z8 t2 s
4 a; H" k* Z0 D* T( d% P
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive( \% w* w2 D3 L) l# ?8 s& S2 a
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    + X! c) y% Q# @
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测
    8 H: k: X, s2 i7 ?1 f
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码
" c8 F9 f- `) P7 g; r
tcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码
7 S& @; K: m0 ~! v4 n8 h$ G* q  x) r
这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。1 \) b* X& ^, b4 {" Q
电脑IP :192.168.0.99$ K/ E2 t0 d8 ^  m9 T: u" G
单片机IP :192.168.0.80
1 ]3 X: \. e6 h# |, _5 I
5 f8 [+ e* R3 q
20210402165445842.png

- \  d. L5 K1 i: h
/ W3 L$ V2 B% q0 Q* p自动化流程为:
3 m" c- `' S3 ?! d* t$ {拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接4 J: w1 r8 n! \; [
如此往复…
; A+ e2 V2 f% o: Q# K+ c; Y: j& [: a0 c  k# i2 A
用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:8 K6 p& o0 Z7 J4 L
1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
. n: E2 Z7 m' y$ q! N解决办法: 在 …Src ethernetif.c 修改如下:" R4 h) {9 T4 J" o+ c1 y- {
9 }4 e7 d( s$ D: I
  1. heth.Instance = ETH;
    8 s) U; |. {  ]- l
  2. : V0 t- }3 R' E3 V
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;. P! @! A2 X- j$ f
  4. " N3 n- I$ z8 k( ~) o5 ]+ [7 p1 P6 m
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
    ) `: x  h  d" Y
  6. 3 D' E0 ]( M, a6 V
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1
    9 C: B" s& R- r6 W( [" ?
复制代码
; `! ]9 J0 |0 }5 A% w& g3 Z6 e
2.初始化时必须对LAN8720A 进行硬件复位。
% R. w' Z1 @$ u' F4 w5 D5 G- {解决办法:% Y  t& F8 h, W5 m$ c

3 x, H) F: ?8 h8 @: c分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:7 ~1 r' d! T" O' U8 _2 v
  v* m' ?; n* z: W2 k
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;7 p" ?' B: y& N. W2 b% B
  2. + @* O9 k/ n5 D' B1 o0 U% ~
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    : P$ \+ p; S4 [- Q
  4. ) |7 b% _# o8 Q0 U
  5. /* USER CODE BEGIN MACADDRESS */: u1 v9 Z4 o2 D) k- S
  6. 8 |- z) H' l+ F- q. M
  7. /* USER CODE END MACADDRESS */$ g9 @6 I8 T+ M4 G- s7 U7 k

  8. 3 ?* [4 d5 g  W) a4 M
  9. LAN8720_RESET();// modify by kmsmg7 W1 k7 O* F$ N' x

  10. * _. \( K, k# A
  11. hal_eth_init_status = HAL_ETH_Init(&heth);3 N! h# f+ L! N) B3 B' D

  12. 9 g" H& x2 }- U
  13. ............
    7 S, U: ?, E' I5 T# ]# v
  14. ! u* b! V8 \+ B" g0 L/ x
  15. //-----------------------------------------------
    & N+ [! g/ y7 P) J, @, {* \

  16. 9 }) ?/ o* |* T! W2 d1 c
  17. void LAN8720_RESET(void)
    # N/ n+ c5 X6 S8 J) f# g1 f

  18. 5 `* b5 |+ }: I
  19. {
    & z9 L$ }0 G9 f
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);
      C% E4 w* O0 }% q% x4 i' U. C

  21. 7 p* N$ q2 a+ E! q* @4 x
  22. HAL_Delay(55);% y  D% R2 q0 `" X" @# ~9 _) y: d6 k
  23. ) c- @# i1 k" Z+ o2 J* a1 V
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);
    ' G7 }1 h! t/ `' Q* d

  25. . x, U4 F6 d+ j% c
  26. }' U, U7 F, ~8 ~/ @+ Y; O+ p

  27. * @# C( Y2 ?; K; \& `" [
复制代码

2 b+ P$ f) C8 x6 q" v0 T) E( G. h6 v$ S
4 m2 W' w2 A- B9 Q8 A4 i7 H
收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似分享

官网相关资源

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