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

【经验分享】基于RT-Thread在STM32H7上移植LWIP(一)

[复制链接]
STMCU小助手 发布时间:2021-12-25 11:17
一,写在前面
4 f# _4 a% L) V6 d* |! ?' LSTM32H7目前还是一个比较新的MCU,网上的资料相对于F1 F4系列相对来说就很少了,我自己在移植这个LWIP的时候走了不少弯路,得到了不少人帮助。写这篇文章也是对我自己移植的一个总结,也是希望后来人能少走弯路。9 B4 B3 c7 k, a4 P& S
这篇文章有由个人编辑并整理,如有错误,欢迎拍砖。
% y) {1 \  W  S+ l# f/ G' N9 p
; U* m* S' h- H8 R/ x二,RT-Thread,STM32H7,LWIP简介
$ w' {# \5 Y+ B4 M5 i1 IRT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是运行于MIPS32、ARM Cortex-A系列处理器上功能丰富系统。
: g4 ]% O& F3 G$ [" ^  E; `' i. d8 F7 ]- I. p
STM32H7是ST意法半导体Cortex_M系列最高性能处理器。主频高达400M,FLASH高达2Mbytes,SRAM高达1Mbytes,采用六级流水线,自带 指令 和数据 Cache、集成 JPEG编解码器、编解码器、集成 双精度硬件浮点计算单元( DPFPU)和 DSP指令。/ b+ a5 @1 D1 B$ H% [
  ~) T/ ?) K: q( \' A/ G5 a- u$ b
LWIP是瑞典计算机科学院(SICS)的Adam Dunkels开发的一个小型开源的TCP/IP协议栈。" s/ `3 L6 \0 |

. J9 [/ ]8 ?; \三,STM32H7的特殊性
9 ^0 G' e) P! `, W) R# y; W/ W2 d这里的特殊性,仅仅只是对比F1 F4系列:
0 ^6 \* Z7 B& w( @. {& g
# v$ O, ?( J* ?& y& y) eRAM3 n  c2 t9 A1 u- v2 V5 K# O# z
F1 F4系列只有一块RAM,在使用RTOS的时候直接分配给RTOS做堆就可以了。
+ t  m$ u3 c. c; j; v* [H7的RAM构成看下表:
9 Y; g$ G3 h8 C7 L
20190504165951455.png

$ _! K% |) t9 B( @) E) ^; r% @9 m+ z  ~3 a" C7 ^- y" Y% Y
DTCM的速度是400M,但是DMA无法进行访问。
; P' e2 e6 G: S( [8 I3 VAXI SRAM的速度是200M,DMA可以进行访问。
. _5 D* F8 M7 r6 x) L) i, |SRAM3是以太网和USB的缓冲区。( |1 Q2 n% v- O, Q6 k
5 \) o: a5 F/ X1 Y3 X
CACHE* |& W2 ?: V' C/ ?7 I9 N
H7比F1 F4多了一个L1 CACHE一级缓存,这个缓存在为低速存储器带来加速的同时,也为程序带 来了一些问题,其中最为主要的时数据一致性的问题。
: V0 g8 x- x' M& n$ Z" V% N/ @4 S+ r3 B. C1 R. u6 [) O
DMA
3 B% m# M( f% n! FH7的DAM分为DMA1,DAM2,BDMA,MDMA。其中SDIO和ETH的DMA又是独立的,就是说他们有专用的DMA和其他的DAM之间使用不冲突,无须额外使能,只需要开启中断就默认使用DMA模式。7 b9 G" m3 G# G5 ?* ~, Z
- b! a6 n5 W) R, J' s7 ~
20190504172355726.png

# n/ N" M, ?9 ^6 {4 O0 F, A$ }- U$ T9 Q
四 ,移植前的准备工作
2 O. _# I6 W' C+ V确保有一个可以在开发板上能正常运行RT_Thread的工程,目前RT_Thread已经有了正点原子H743的BSP,通过ENV工具使用scons --dist来把这个工程拿出来,复制出dist文件夹下的工程就可以直接使用了;' f7 S3 {( r4 X" y9 J9 Q
使用ENV工具,开启软件模拟IIC,因为正点原子的开发板的PHY复位接到了pcf8574的7号引脚,然后生成工程肯定会报错,这个时候从别的BSP目录下拷贝出pcf8574.c pcf8574.h phy_reset.c,放到工程里,然后在rtconfig.h加入以下代码来启用模拟IIC
/ U0 ]5 B- x7 L8 N! ~
  1. #define BSP_USING_I2C2
    1 m$ D! q. ~2 N; e# q
  2. ) `( ~& w+ ~1 m: i# t7 k: z
  3. #define BSP_I2C2_SCL_PIN 116
    9 P6 N: c2 I& Q" `. y4 e, k
  4. #define BSP_I2C2_SDA_PIN 117
复制代码
) C3 c& a$ Z8 I7 K6 f" @& W
这里的引脚号由硬件决定,如果不是原子的开发板可以省略这一步
5 Z, E7 N! F, J# a* O! X' u: f; E5 B7 f% }
因为RT-Thread目录下的STM32BSP是依赖CUBEMX,所以还需要在CUBEMX里面开启ETH的引脚,这个请和自己的板子一致;, \6 I, @3 U8 s! l& t
, f* D( A8 _: i/ x
20190504230500122.png

( G' F2 D4 E' [5 x$ a# ]" M* w) p! L' S8 \( g
开启RMII模式,注意这里的PC1引脚无法选择成高电平,需要在生成的使msp.c里面自己修改为高电平,并开启中断。
( N% g0 M& u: v
) \. n( d( k9 i& o  H2 S检查是否开启了I_CACHE和D_CACHE
# S  B! c; B; L- _. ^% R/ P* Q  z: U" W) Q
20190504230946919.png

' ]) }$ q% Q, W9 P! T9 g! u/ m! f' ?2 w
这里一定要开启,里面由依赖关系,不然会导致cache无法正确运行。
! D' F/ t! z! U, E& `! t" ^
( A4 P3 O* o. r& e; @然后通过CUBEMX生成工程并把时钟初始化部分拷贝出来复制到board.c中
7 w. |( m4 j: g( ^3 x( C: v" `$ ~/ w# Y2 q& c/ z6 `& @! w
在drv_mpu.c中加入MPU配置, S+ o3 B8 H" M
以太网DMA描述符区,只能配置为Strongly - order或者Device。5 c2 ^# H* q, G6 @) n: i7 c- ^: \
  1.   MPU_Region_InitTypeDef MPU_InitStruct;( r1 e9 m; ?9 c# m5 m/ t3 ?' W

  2. 0 c% O7 [" A" G% R- b) r, Z, e' V
  3.   /* Disable the MPU */
    ) O+ t. u! O0 Q$ N, q+ `
  4.   HAL_MPU_Disable();
    , l% E/ a3 {$ c( X

  5. 4 Y  w6 I; g  J! b( P
  6.   /* Configure the MPU attributes as Device not cacheable 4 o+ n4 @# O/ e+ B( M" B% l; K
  7.      for ETH DMA descriptors */
    # c7 n; o: W/ b
  8.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;: M$ O; O8 @* K0 r. W
  9.   MPU_InitStruct.BaseAddress = 0x30040000;
    $ }- c8 X# H2 \( E+ E: ^- {- X
  10.   MPU_InitStruct.Size = MPU_REGION_SIZE_256B;7 `: g' l# V( A; C
  11.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;& {4 ^! s5 e8 \% X, [3 `( K9 `
  12.   MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;3 ^4 k6 E$ s7 l1 s6 h7 Q
  13.   MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    ; W  _: l, v/ s. Z( }1 E8 O
  14.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    & \" p! j1 N6 B4 H+ [0 N
  15.   MPU_InitStruct.Number = MPU_REGION_NUMBER0;3 r* [- ^3 W' l7 \
  16.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;, o: X6 H. i9 F4 a0 x
  17.   MPU_InitStruct.SubRegionDisable = 0x00;
    8 @* g( z5 g2 r+ _
  18.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;) ~/ A( X  A) ~5 n6 {

  19. % g) O' z1 ^4 P& I5 ^; _0 k2 l
  20.   HAL_MPU_ConfigRegion(&MPU_InitStruct);/ K9 R* ~5 w& ~! x/ x0 w

  21. ) b( w$ I, l9 u& w: o% N3 j  d
  22.   /* Configure the MPU attributes as Cacheable write through
    5 z+ e6 Z, {: X2 t
  23.      for LwIP RAM heap which contains the Tx buffers */
    5 ?' p" \9 R0 Z5 M5 w$ t/ ^
  24.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;7 Q7 c- k( n2 j. J  \
  25.   MPU_InitStruct.BaseAddress = 0x30044000;. J; u8 a. t, d- e; y- I7 _/ Y
  26.   MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;1 ]' j) C! @! ]; x7 {% F
  27.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;6 y8 O! P- B& _' [( G9 H
  28.   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    7 p' l1 J; q: |3 e
  29.   MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
      _3 t: u2 d. U' F
  30.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    - W0 V# X1 l) U* f
  31.   MPU_InitStruct.Number = MPU_REGION_NUMBER1;: v5 L% O# V$ M4 K$ P8 p9 o$ P
  32.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    " F, {' O; X8 o% z% W
  33.   MPU_InitStruct.SubRegionDisable = 0x00;
    3 S6 {0 @/ |7 F  D
  34.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
    - Z+ Y: ~- j4 o
  35. 6 _! f! X. u/ k; a/ ^7 Z; n
  36.   HAL_MPU_ConfigRegion(&MPU_InitStruct);) \! o7 O. g7 q: m0 q
  37. 1 Q. p* u9 T0 ~) T0 O, S" z3 @
  38.   /* Enable the MPU */
    " w3 y, M8 o7 {5 v
  39.   HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);! d. [7 C$ A7 E+ h8 x$ w2 M! z/ {
复制代码

7 h: L+ I: {$ A- m( `, D# H在工程中添加ETH库函数,stm32h7xx_hal_eth.c和stm32h7xx_hal_eth_ex.c3 i3 }1 t% ^8 @, y! V
0 d' c6 T2 i# S& l# }; @
五,LWIP协议栈的移植

) a9 l/ U! V# S+ \9 G该移植参考思路,移植也可以通过git log的方式参考这个移植步骤,但是这里移植里面有几处错误后文会提出。后来发现这个移植与STM32Cube\Repository\STM32Cube_FW_H7_V1.3.2\Projects\STM32H743ZI-Nucleo\Applications\LwIP,基本一致。
0 }: r. T6 l& f$ U1 q  i2 ?) a9 O  N. t/ ~* A4 a
LWIP协议栈的源码: l3 f0 U7 L$ s  ^9 ]
如果你有安装CUBEMX,那么直接从STM32Cube\Repository\STM32Cube_FW_H7_V1.3.2\Middlewares\Third_Party\LwIPP的目录下把LWIP的源码拷贝出来就可以了。或者下载参考思路里面的链接把LWIP源码拷贝出来。
3 S/ R% e0 n, f; M2 n工程中添加新的文件夹9 X. f+ R7 ]  B* t: E& G
0 X9 c: l- ?+ s0 `. g0 D
lwip/api:添加LwIP\src\api目录下的所有文件8 N! Z' T+ @* P

) l+ `/ d; c: W/ W9 w
20190505093456906.png
! g- ^6 X( k2 d9 {. B  G2 k5 i
& }! ~2 S9 X; X2 F, T7 j
lwip/core:添加LwIP\src\core目录下的文件,并包括ipv4文件夹下的文件6 K, C8 C; c9 l$ U0 w/ J% t

. }# a" ^! w$ G  |9 |: c" ^$ G3 D* f
2019050509354914.png
, w. G$ ~& L; M5 u( h0 I! }
1 y( ~2 |# L) [
lwip/netif:添加ethernet.c,sysarch.c
7 C- P3 z3 P" S" d8 i' @% U5 Q( J% N" g" E' I/ D' Z0 a' c
20190505093617351.png
0 u7 N0 `; x" c& L$ d3 \+ p9 ]

% H# I! Q& o+ ^  Glwip/port:添加ethernetif.c,lan8742.c(lan8720也可以用)( m. d2 l3 c* `7 c8 u+ P6 y" i

, _& D5 j# x1 D- o
20190505093754704.png
4 A9 P) K* e. `' R
; Y' O) m, y/ S- v3 d
移植准备工作就全部做完了,下一节修改工程报错
5 |9 i. f$ q1 q" S! b( w" g% }# b% @' F7 r  p, s* _

) v2 N; X) r7 L; F% O1 Y/ A; e/ F+ R! z+ W8 }9 v( j
赞 收藏 1 评论0 发布时间:2021-12-25 11:17

举报

0个回答

所属标签

相似技术帖

官网相关资源

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