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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 14:55
ETH
( V& Y$ ~1 l: o8 E5 Q' }4 |, C. g
! s& K; U; ]3 Z
20210402161452602.png
( S( g& _5 r' m; D
' c. e# D1 L3 D* G0 |
20210402161514595.png
$ U2 D: l: ]3 {0 R8 ?" {1 f9 Y

8 C! R: Q! t/ s* t5 H$ g
20210402161532893.png

, ]# h1 u& t- I: o4 ^
( Y& B8 x) x* ?4 z, R, M; A% V配置EHT_RST引脚
- K+ \0 T! `) V, \8 q+ j; H  |' c" q  n0 i( ^  m& `# K. ?& {% I
20210402161604234.png
0 \1 ]  r+ q; y4 |8 m" B- w2 E3 U
$ Y' o+ i- s9 M3 {) V; R: r$ ?( L
LWIP
& V( _' f$ g; i) F6 e4 c: ?8 m: S
5 J( b  U3 @& m. x1 B9 N6 F, n
20210402161716753.png

1 p! `  ?$ b, r; {
; D& U4 p9 f) Q) {
20210402161746306.png

. G1 q0 Q: J8 u8 J0 i* j$ d! q# a1 c7 t6 U. b9 s1 v
注意一定要把LWIP_NETIF_LINK_CALLBACK选上,不然连接状态改变不能进入拔下或者插入网线回调函数,里面做一点自己的事情! B: N8 |2 b: K- ^
, Z: v( ?/ T' C( R; Y
20210402163232833.png

6 G1 q8 e" U$ I/ T/ W, b* }0 G0 |1 t' ^# @
LAN8742
  j2 m0 P: Q0 k5 d6 I; {
20210402163258853.png

# O: a5 e7 I0 C' C: |" Y6 M/ G
1 X6 w( A, `  H$ ^MPU
! K, g/ j7 l! K# p  g9 ]Lwip使用DMA传递信息,对应的DMA内存定义在sram中。H7的sram分为好几段,高速段为cpu独享,通俗点说就是这一段允许用户编写的程序使用,但是不允许DMA使用。所以为DMA定义的内存或者数组要避开这一段。另外Lwip使用DMA时存在交互存取问题,避开这一段后,也不能让cpu像使用普通cache那样乱序使用,否则将可能出现严重问题。很多人用F7、H7和Lwip协议栈都出现ping不通的现象,都是内存管理问题。怎样管理??需要使用内存守护单元MPU。
: H3 w# Y  U1 i; @! d: U
4 b* r  i1 J$ `7 D使用CubeMX配置MPU,最多可以管理16段。为lwip配置,管理两段即可。2 R4 b3 h. C* \% Y( m3 x& Q) @& R

6 ]/ g1 m0 c" @  M
2021040216385026.png
% _' u4 k* i/ ^/ U
7 R" F" _( O; {+ J/ f$ |; i( U
20210402164922519.png
9 ?* e8 U  i- L' A% b
/ s' N1 y2 [* y1 F
20210402163942899.png

8 e9 S& Y- g- b2 F3 J5 o+ D8 O9 ~. l

" J5 ~" X- R% g  bMPU设定总结(非操作步骤)/ _! c7 X) C$ F' {/ d0 w
总结一下这样做的原因与目的:# E) D( ~  |8 `/ M
(1)Lwip不被允许使用cpu专用的高速L1缓存(DTCM),只能用D2 Sram区域;
" T) O* m5 J/ `4 q# V. z! b(2)cpu可以无序访问cache,为防止这种情况,Lwip的DMA段必须是device类型或者Strongly-ordered类型,保证有序;4 L7 j; X6 u7 M8 U) c0 Y
(3)通过MPU配置这段cache,其中一段允许share、允许buffer,长度为256Byte,放TXRX交互存取头;另外一段不share,不buffer,不cache;长度32k。
5 @- v; ^4 w" \. D, f) x* Q3 \' T- a8 |. E" n& S1 m) \
20210402165153856.png
, P0 f9 V4 X7 \+ X/ E" }8 e* k( v' C

4 r7 U! o. D5 {MPU选项含义(非操作步骤)
) b4 h" V! m% ?: wcubeMX里面配置TEX、C、B,三者搭配。
: V) x7 x+ e" t( h4 u
) {* {# m! A  _! E) Y
20210402165235835.png
& O# B1 _8 @# m% w( e
, O3 s3 j$ k& ^4 a: f

7 ~- `! J; ^' _6 X5 @7 }Access permission被定义为3,即Full access。* A: P) c$ C/ T6 L, p/ N3 f
' `8 b, Z3 ]3 {
20210402165246437.png
/ d! |& y* ~, U: _8 u  C9 c; u6 t

4 i+ Q, D- K2 G4 @经过上面的配置,编译下载,不出意外不用写任何代码就可以ping通了。
9 `& i! l2 n5 |9 [- J" F6 _# i4 l* N0 ]( P- ]+ n
好了,可以进行下一步!
) s2 n4 A  B! @' T  v% |/ e) E# ~" I6 p0 Z. x2 D! d  X
Lwip协议栈TCP保活(KeepAlive)设定
6 ~( d( v6 \3 M3 }6 [: ]1 t% E
万事具备了么?no!
- q% F  `3 V  q+ k& g: L, B4 p$ J  i$ W. a5 _
以上只解决了异常自动重连的问题,并不等于协议栈具备检测异常的能力。即H7必须知道网线是在什么时候被拔掉。
( h0 t1 r" u! u. U1 j" W  g1 A) ~! \+ T
有很多博客都提到KeepAlive的开启方法,但都是详细说明怎样打开,打开了该怎么用就没说。。。. H! q  p. ?7 W5 |" o* J+ G
; F) ]' G3 A) k8 p
由于tcp是可靠连接,有数据往来的时候能够检测异常,需要解决的是无数据检测。这就要用到TCP协议的KeepAlive功能,原理就是在空闲的时候,以一定的频率发空数据包给服务器,服务器收到后答复一个数据包,说白了又把空闲段给变成有数据往复状态了。TCP协议栈包含KeepAlive,lwip协议栈这部分也没少,启用几个宏即可自动进行收发。设定方法为:在lwipopts.h后面加入
4 \9 v% @8 |" d
5 \! }5 k) r+ k" j6 T& `( r! f4 D
  1. #define  LWIP_TCP_KEEPALIVE       1             //激活keepalive
    : |! y  R1 j5 r, F4 }$ A. N
  2. #define  TCP_KEEPIDLE_DEFAULT     2000UL        //2秒内连接双方都无数据,则发起保活探测7 R$ T' v  S. L% [
  3. #define  TCP_KEEPINTVL_DEFAULT    1000UL        //1秒发送一次保活探测
    + D9 ~# \# K7 ]5 _! @. K
  4. #define  TCP_KEEPCNT_DEFAULT      3UL           //3次保活探测无数据则进入错误回调函数
复制代码
: K& m( Z4 D& J& }3 U! y
tcpecho.c中实例化netconn后,为其tcp成员加入SPF_KEEPALIVE属性。
  1. xNetConn->pcb.tcp->so_options |= SOF_KEEPALIVE; //保活设定,实际上是tcp的一个属性选项
复制代码

7 H5 j& d8 q% Y# c& |3 d  {( F: d& L这样就能实时检测连接状态了。使用wireshark抓取数据是下图的样子,里面可以看到空闲时段交互的keepalive数据包。
# E* e7 A4 i5 ^8 |# s& ?电脑IP :192.168.0.99
+ _' o9 c8 ]* G' S& z- j* C单片机IP :192.168.0.80( x6 ]" z) f5 m3 @6 P* \3 x! i) u  \
8 [( C( v$ Y' \0 e1 A
20210402165445842.png

9 l! G' }" X0 ?; e8 c2 v+ c1 N1 h! D2 ^% X. u
自动化流程为:
" Z9 V: |9 y% q8 j8 L拔掉网线------进入回调函数销毁tcp资源------主程序while循环连接出错------主程序销毁netconn资源------主程序实例化新的netconn资源------再次连接
% i: X. E8 Q! I& N0 q( h) q- z如此往复…( O9 _; I& p$ X( l9 E8 ~( x

, l9 K( L$ P: t% E  \用STM32CubeMX 生成了一个包含 EHT ,Lwip 的项目,调试一直不正常,经仔细检查存在以下问题:/ K0 Q5 v' I7 }$ G+ t4 E
1.硬件采用了LAN8720A ,但是STM32CubeMX 生成的是LAN8742A的代码,必须根据硬件连接更改地址。. F* q% U. Q- P
解决办法: 在 …Src ethernetif.c 修改如下:
; N$ c5 u( b' x( E3 ^: o& x+ G* k$ x' T; n
  1. heth.Instance = ETH;
    0 ~1 V# I/ C6 j& t3 _. u/ L
  2. " M4 b* X. g% ^1 g; }6 d
  3. heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;9 {, R" A8 C- J" z8 s1 z( [! B

  4. , i9 g1 k, B1 A" ^8 K8 `$ i" ?
  5. // heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
      }& J1 m4 g. ]" f  J$ w0 p

  6. 7 e4 f# f" X8 t: z' m
  7. heth.Init.PhyAddress = LAN8720A_PHY_ADDRESS; //modify by kmsmg,LAN8720A_PHY_ADDRESS=0,LAN8742A_PHY_ADDRESS=1
    1 ]3 F. R; I; r4 i) m4 I7 I
复制代码
& v  R. B4 t8 ~% z  L1 J5 ^
2.初始化时必须对LAN8720A 进行硬件复位。- B& ~  u& @, R, x& v2 ^
解决办法:
% O' t. R) b$ x
& o, f! R3 ~8 a$ h) W0 J1 g" ]分配一个 GPIO 连接LAN8720A的复位端,在 …Src ethernetif.c 修改如下:
% j) [  V/ A$ X1 j* R$ t5 Y- o/ a
1 |0 O$ p" }, ]. @
  1. heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;& a6 Y; d8 |0 c* p8 o  v: {0 Q
  2. ! k" t6 y1 w+ D( N! E' l
  3. heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;+ F7 Y- f* [% H2 g9 E1 m  }
  4. 8 l7 U' m/ a3 S7 ^/ D
  5. /* USER CODE BEGIN MACADDRESS */
    8 f: E% P* Q  k4 {8 w% S9 T

  6. - i9 K$ l6 E& ?4 Z+ O% M  R
  7. /* USER CODE END MACADDRESS */
    " \. H- G( N  \/ Q
  8. " V: a: K( _0 J3 O  r
  9. LAN8720_RESET();// modify by kmsmg
    . R. o6 m2 J6 j( c' m4 u2 ^

  10. ( F" R1 z) `) X: S: \$ [0 b
  11. hal_eth_init_status = HAL_ETH_Init(&heth);* f/ D' i$ ^9 u: a" T
  12. , u" x6 x- f8 z& y% W6 u3 L! R3 |
  13. ............
    - J/ Q( ^* R( A+ K9 `% D$ o
  14. / c& V+ K- U1 G/ |' J* G
  15. //-----------------------------------------------
    + f/ F# d7 y, a$ r) X* E: o% j
  16. 0 ?$ P$ H* s1 T% \: E
  17. void LAN8720_RESET(void)" T6 s* g, |! t- P+ N# S+ y
  18. / i1 p, y5 ?% R  s
  19. {
    / W. K( a3 V& ~/ M1 E) h
  20. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_RESET);
    , t* B0 D5 K2 R( Q) z+ Z

  21. # V: H5 i. `; s5 Q% u
  22. HAL_Delay(55);
    2 ^+ D  B, p. ]. n. Y

  23. - x/ E- u+ Z0 L
  24. HAL_GPIO_WritePin(GPIOD, GP_EHT_REST_Pin, GPIO_PIN_SET);
    % ]& T/ Y8 D# z( m  Y
  25. " j* S2 ~# T! c! x
  26. }, Y$ n. t, S; S2 K, r' D3 K; c
  27. 2 q- i1 b2 m5 s! V; ~
复制代码
3 V& g8 I8 X3 \$ y4 Y5 o
$ r1 d  ~. l; S! @: t: @/ |' N

0 M! p0 o& U" r# s% W3 |. P$ r, Z! D6 `
收藏 评论0 发布时间:2021-12-26 14:55

举报

0个回答

所属标签

相似技术帖

官网相关资源

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