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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH9 H1 {# f  S$ e9 Z
: p9 a% E6 D% W0 ?) {9 w
20210402161452602.png
$ ]% U. J: H& Z6 h1 p" F: ?

/ P! D- _, h* t0 B6 z3 r
20210402161514595.png

" `0 h- A# {' V7 }* q5 O* l- [4 S2 A( a1 O
20210402161532893.png
) K$ r; c0 b  ?/ D( l

9 s3 @4 O( ], W; ^; S配置EHT_RST引脚
4 M5 F+ r* F% E: F
3 y0 o6 `% P: K3 M. ?4 o3 M
20210402161604234.png

; F  L& V$ ~- w; ~1 l2 j9 ?7 ]% T7 G+ b9 Z
LWIP
8 ]- f0 J* f3 D) c8 W- ~. q* E/ g2 t: V; E
20210402161716753.png

$ c+ u6 `$ h2 Z9 h
$ O' ~0 A7 n& \+ D
20210402161746306.png

+ p( c0 F" \4 q6 k9 Y7 u
, a: T  a! F: V" i; u/ ?注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情
7 ^; c! d$ L2 x8 b
$ U, c& K& U% H; n# F
20210402163232833.png

% Q& M: d0 p; ^  h9 E$ f4 T) q" h. r  u3 I( i' g: N7 x% n
LAN8742
. F, \9 {& E. M# |' L8 I
20210402163258853.png

4 T, \( m+ k+ j+ `& i
% F* n8 j) k9 A$ D+ V" s7 v& }% F% iMPU
8 r8 k- U" z6 I- y) dLwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。1 z6 `2 l/ B. }0 m

/ U' Q2 l9 O& v% z使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。  }: Q% l" ]7 |" i% @- Y+ d: o8 }: x% h

# b# M4 h6 s0 x8 h. u: A9 E1 t1 [5 Y
2021040216385026.png
; }! X( g2 U' x0 M( i
1 x* `& n3 e! i* [- Z, @
20210402164922519.png

& j+ ]; g0 A( E" K
: J$ z& E( N1 A: S9 t
20210402163942899.png
: t2 l1 n1 G" @% Q
! E- l+ c) i  F3 k% Z5 u; c
% _8 j- x) Q: W- f# Q' l# E
MPU设定总结(非操作步骤)
6 o4 P% y2 Q. p: m# D( b5 q. }总结一下这样做的原因与目的:
0 S8 T1 e5 c, u+ t, g/ E/ T8 o(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;. G5 Y5 M! c5 h$ a: x
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;4 u' y6 N! J& x  |
(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。' [7 [, w& w, r# _- i6 }4 t3 I7 H
# }1 O6 M: a" K/ U( S) I
20210402165153856.png

: M* G) _1 {/ \7 t1 u0 o# s% g' K/ N. C7 d3 R  e# R& U
MPU选项含义(非操作步骤)5 N: p" I8 K4 S+ W: P
cubeMX里面配置TEX、C、B,三者搭配。4 I" i- N' a  n: t

3 T6 t, |/ V) z/ w6 ]: ~. _
20210402165235835.png
! \% |. f4 x4 n) r! e
0 [7 b" A( ]0 O) i# |  U! K
6 ^  k9 u$ v8 c$ @# U- K
Access permission被定义为3,即Full access。* N3 z+ |/ W* }7 q1 I$ E
& {/ |, e, ^/ ^9 C- s
20210402165246437.png
, y; R( H4 F  K" H# j7 `- Y! n5 ]

7 `7 N% |& j" t经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。; }2 u3 \8 c. x- t$ a: h
  c1 z9 X4 x- d* ?
好了,可以进行下一步!
+ l# M- G, ?! h* p, j. ?, [3 D# s
# X& ^5 \6 E% j- bLwip协议栈TCP保活(KeepAlive)设定

4 E  P9 @: O( m万事具备了么?no!
! g: Y6 d0 @% `
/ ?. ^! Q- i- P/ d! N以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
8 F$ Z9 W  e  r2 a% w: U7 T
) c) d/ y0 x( H) r5 ^2 @有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。- r/ [# D9 P1 w! e& L

4 l1 C) D. {: T# [) x, i  F由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入
/ p& K# D7 F( x- ?
8 k4 R6 l; h- q4 ]8 t6 S
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive
    : s! k/ g% Q$ S) L6 L2 b% E2 _' }: s
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    , e- `8 e" a0 h; S
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测
    ) n, b$ q" ^4 L3 A3 C- C
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码

' b; g" B( h0 z+ B$ Gtcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码

' u" T3 t& r+ G1 X7 B8 T9 m这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。1 G) Q- j5 d5 e# l3 R' e
电脑IP :192.168.0.995 w9 L1 E; k% Z5 U. U) d
单片机IP :192.168.0.80) s) [1 x: m/ Z! G( _2 y, z

& f, [# M6 u4 |: f! b4 B4 f6 K( N- V0 N
20210402165445842.png
. u/ t) C3 q. p: _0 w8 t  W
7 X  {& W+ p9 L
自动化流程为:9 L2 c7 u6 t1 m2 u' p
拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接; u3 d1 i0 L: R% _2 |. N# R* Q! }
如此往复…
1 u7 c! v# Z  L' i: x9 F6 S6 d! Z3 J' N' Z7 M4 D
用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:
+ |4 b1 @; i1 X5 o  ?( N8 q1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
  \0 N$ [/ U' K0 Z2 C% t  c解决办法: 在 …Src ethernetif.c 修改如下:
7 F; |& \7 Q' m7 m: t+ E5 w
5 S3 A2 E& j/ _
  1. heth.Instance = ETH;
    ; N5 i2 @) i, Y. S" d& U

  2.   {9 @( {* [3 v9 d# H+ v
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;# Z9 [' k8 T% ~6 h- j7 n

  4. ! @. c! \9 f8 F" Q3 j
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
    & \. \" k7 ?% Q3 p3 ^1 o
  6. 1 x( h  A/ {2 c, O" Q  ~% ^- y
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1. n' d+ B# l+ r2 f; G2 e
复制代码
' [: u& K2 B! l7 ^
2.初始化时必须对LAN8720A 进行硬件复位。
3 ?1 C0 s; d+ `, ^0 O解决办法:* Z0 Y& E3 x: `) P1 [  B

0 h# T1 v5 _! H' s) Z; s分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:1 b9 M' D+ D. U

6 O6 L* S! ~# t
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
    & M9 b; x( i/ W8 L6 m6 k
  2. : E& _' Y7 {8 {& X
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;5 {- F' J+ F, M& @: w( i
  4. . @, i7 j9 e' m$ @! B2 t- z% K0 R5 @! t' g
  5. /* USER CODE BEGIN MACADDRESS */9 T3 L: ?+ `8 k$ P) \9 I

  6. : R* ^% H* ]% K* I- P: R) Z1 d
  7. /* USER CODE END MACADDRESS */
    ( K' P6 @6 A+ U8 c0 U6 \- V3 k( T
  8. / a7 ^" L4 y+ p2 P
  9. LAN8720_RESET();// modify by kmsmg
    1 i4 y+ k$ C! K4 q1 \/ }
  10. 4 `2 W/ A& ?, n3 p- `, W/ J5 ~' J& Y
  11. hal_eth_init_status = HAL_ETH_Init(&heth);
    8 P# T# t6 ^; t- e: W( N

  12. 8 H+ Q5 C9 d; S7 E
  13. ............8 `. L. P' ]/ y: s$ H
  14. 9 d& x5 [! ?1 v$ s. k
  15. //-----------------------------------------------
    : `" D6 T8 d4 Y7 D; n# U

  16. ! u) _3 C3 ^" q1 T5 f
  17. void LAN8720_RESET(void)
    , T' @% m3 O& a3 c& h) u

  18. , r3 I) ?8 f4 W( Q4 c- s
  19. {
    / m6 z3 f( w, @* s$ K8 D
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);4 u/ I7 L/ s5 |# W3 p+ G

  21. 5 D; P- J0 l" p# ]
  22. HAL_Delay(55);  }6 E* i3 v: H. J% t

  23. 9 B. p. W# y. Y
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);
    5 b% g8 }& l) s9 F% K8 R7 l3 j
  25. 1 W1 l8 j0 f, `4 c* F2 Q4 |% N/ T; \8 R
  26. }7 ]- O- r; z8 E* C0 ^- U9 r+ |
  27. $ \9 R/ _' g* @+ Y* M! u
复制代码

5 f8 V7 Y% n8 y! a' t, e0 m5 w1 [
; \% ?: p5 b$ r2 D2 d: j( T. n% d+ @% W
收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似分享

官网相关资源

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