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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH1 F: d$ u3 m) e
( }/ n/ n, H" d" ^; {, [+ b( B
20210402161452602.png
- R9 J3 j% L0 Q  x# @

8 L- T, j& U# O  n; L, p
20210402161514595.png
0 J; K, S2 O" Y  @

' F% y; [2 I' o: h+ }/ U
20210402161532893.png
) q" ~" [: z9 Z- q# Y7 n7 |

$ x( j/ \5 u/ C# F/ d配置EHT_RST引脚
$ {5 x3 K- p& p( d" L5 O
$ ]- s) m* m/ R! l- Z
20210402161604234.png
: Y0 [; T; R, W4 f" W
2 `, [! A4 h6 e; C3 i7 ?* r
LWIP
4 \9 m5 ~  z+ ]! {6 a! s
0 Y" O9 L9 F- n/ Y( |
20210402161716753.png

7 o' o# @0 T! m; M5 O$ g- ]" S
6 T+ _* o( v6 [0 I% k& W; K
20210402161746306.png

' Y" ?% ~; w2 n1 }# X3 k) \( {5 A9 n- y, U
注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情
+ T# s# E1 r, L- i4 x3 ?
* e7 t+ m4 ^6 R) O! T
20210402163232833.png

  D% ~" g( J" V* Y6 g- b3 ^4 l/ m* @7 d1 j) a& N; x" B
LAN87423 {2 c/ }( ]# K2 E% H) j
20210402163258853.png

* F3 S. J7 J- y* ?# K# U* F7 P  K$ [; \4 j0 U9 T2 [
MPU5 Q! L% ?! x6 p) C2 q
Lwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。  e5 S/ I9 l2 Z0 S7 Q) {

0 _8 N) @8 _( g1 p* k/ _使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。) I9 ~( z) g* Z5 A5 `/ \7 \

) i( |3 j) V% d1 ]8 h! Q' z8 D
2021040216385026.png

$ L$ G6 n+ O$ }9 `7 i7 F2 f1 j, J2 m. o
20210402164922519.png
4 h. M+ |. z. T/ I

4 `/ O4 d" F, ], ?
20210402163942899.png

; B7 l9 c5 S: Q' K5 ^" P$ v# X
4 R. s* M/ Y, {$ k0 g1 O
' J; ^6 R3 k5 VMPU设定总结(非操作步骤)$ q8 u2 J, u  _9 b. U) Y' C% `# O
总结一下这样做的原因与目的:, {3 d, T! D3 N3 N  _
(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;# d" `9 u# P! I* E2 y+ E
(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;
& R* v# L/ z7 M: n% ~(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。
! h9 T; K. D7 z- F% V3 I" f
# G  D* d0 {' t! @
20210402165153856.png
( J/ T' [0 |9 U1 D5 q& o: u/ ^
8 W" v( \% p! l' b, B
MPU选项含义(非操作步骤)
3 |/ y8 @# P( h6 O9 J( NcubeMX里面配置TEX、C、B,三者搭配。
" }: _& h, n' a
9 |- |4 D1 L, k- ]) K, u4 ^* l  X
20210402165235835.png
% M4 k' b/ U; d5 W& H; W

; T7 B9 n) @. L1 I1 Q; ~" `' y! O: M
Access permission被定义为3,即Full access。; @  O0 U  b: a6 U) i

' \+ d. a* t4 H; y& z$ z
20210402165246437.png

2 L+ _' T+ j  |( i  g4 s; @0 U
+ N1 }& h5 c6 \0 q" U4 \经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。$ n9 X* Q( w4 A  |
* G' e3 w, E4 t! c/ {7 w1 W
好了,可以进行下一步!
0 J* G, F! `! G6 a3 M
0 @8 {5 _- |: L7 j% l7 eLwip协议栈TCP保活(KeepAlive)设定
: {: _* [, g9 b4 x
万事具备了么?no!+ C: Q4 I4 d0 R% @/ t- _
' O' Y/ ^3 M) F& R0 n
以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
1 p1 |$ K( z3 u  `: I+ I( @, T/ v0 Q
有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。( F# ^' v% W$ Z# G  ~( S

6 G. F" s+ r# n: r. C/ O5 T由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入" O9 ]7 R6 S2 B, U+ ?/ S/ W9 g
7 N' N% b' o: L8 R9 t# l, D
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive: F  O6 L4 o$ o  K
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测
    ( w! L/ T, D. c  M% }' E
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测  x% _# R& ?' R8 P! {% p
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码

9 J+ ~$ h. N. ?9 Htcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码

3 V  }( J6 [  i8 ?0 u这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。5 i- N6 I+ [% ^' ?6 O
电脑IP :192.168.0.99
, P$ [; l5 y/ G" u: O单片机IP :192.168.0.80
0 b! m7 k9 L4 A* u; h1 j5 Y
: k) C. @# B0 a" E, e: S
20210402165445842.png

$ _7 V  n# W! e. O2 J3 Y0 i) m2 s; o; B5 U3 ?( m
自动化流程为:; E' g' n* l/ g* E9 g' j
拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接
, L: V9 o! B* e" t) x如此往复…
* `. T& g/ {# d. g* y4 k  }* H1 y' F. B3 x
用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:
+ t6 O2 E0 t# b7 O/ c0 e. f1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。
4 Y( l! Z- T# @8 v解决办法: 在 …Src ethernetif.c 修改如下:. C  J+ j4 m# {& [6 Y

" Y( n- k% o0 h
  1. heth.Instance = ETH;6 ^* ~. C6 X$ A& r1 w( m$ _9 l: j
  2. , h/ ?% j  B+ N3 b4 ?
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;! y- P( P) u5 v! p( _; ?7 R
  4.   d" f6 o/ F+ O' I
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
    $ ]0 R+ @9 n: g# t& w: K; P

  6. & O! j! R* w/ N. a
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1# ?/ c& M1 @. P$ \9 L0 K* q6 D% |
复制代码
0 q. V, w3 @* Z  `0 M( s/ N9 R
2.初始化时必须对LAN8720A 进行硬件复位。5 B4 ~5 q  R% d! f  {0 U
解决办法:- L3 K" C5 F; j! i# y% S2 ^5 e! B
7 f  n" [0 y- Q, m' ?! Q( ?
分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:4 V. [( d' r3 s) @, c; @& N
  M: E* l, W/ j4 \3 f* h
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
    7 f0 y, _# ^- k+ h$ e

  2. " |; i8 l8 [! u$ I0 z4 a( |
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    , @2 F! f; c9 w3 F6 {8 a# t

  4. / L% ]& m( q* l) @, ]8 a
  5. /* USER CODE BEGIN MACADDRESS */1 @$ i% N1 B) z$ N
  6. : j8 Q8 @- M, A) t5 ?
  7. /* USER CODE END MACADDRESS */
      o- e% A+ z5 {. Z. B
  8. ! |; k3 _; B  X$ C( n7 G( Q
  9. LAN8720_RESET();// modify by kmsmg$ |4 R. `; V1 K5 e3 Y! t
  10. 6 V+ Q8 r& n# r6 d5 z
  11. hal_eth_init_status = HAL_ETH_Init(&heth);
    6 T1 t6 B: W6 `- G: V5 L
  12. ; _4 _& g. r& n7 @+ u7 v) J
  13. ............
    $ L* [7 J8 l# a- B& t+ a
  14. $ T* x0 ~7 Q( t  [" H
  15. //-----------------------------------------------
    9 U' H8 Z" q6 V1 G0 l# \0 i

  16. 8 M1 `; N: {( f- G" B0 r, Z! J
  17. void LAN8720_RESET(void)
    2 H" M; u) X5 \5 u+ T
  18. 1 v  C( h1 C* g: A
  19. {
    7 X6 I% u( d$ ~3 T8 k
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);
    - o8 z5 X7 K- g8 ~

  21. & E3 i. g( [0 U% Y
  22. HAL_Delay(55);
    ; z# p* h# y: P7 c5 T3 m! N3 E: J* M
  23. 6 V3 ^+ H' `2 O  O6 q: S) [5 t% x; W
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);" |/ D. K/ D5 {- V3 Y, Z5 c
  25. 8 i7 K: n9 \2 P& H9 G5 w7 V5 N3 b
  26. }
    $ J: X& |; D" s. X" \/ G
  27. 2 D2 m/ d  E1 h
复制代码

* s: ]3 x! {* t4 A0 w& k- a
- H! u5 S: ~+ ~/ ^- B! H$ i
# v3 w. X! p! F- a) u% O7 o
赞 收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版