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

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

[复制链接]
STMCU小助手 发布时间:2021-12-25 11:17
一,写在前面7 y8 y; b& g2 ]* Y% O% P8 k
STM32H7目前还是一个比较新的MCU,网上的资料相对于F1 F4系列相对来说就很少了,我自己在移植这个LWIP的时候走了不少弯路,得到了不少人帮助。写这篇文章也是对我自己移植的一个总结,也是希望后来人能少走弯路。
# K7 N9 g% t' d  M+ p$ J/ v# `9 [这篇文章有由个人编辑并整理,如有错误,欢迎拍砖。
3 A9 p7 L% @: ^3 j1 Z+ J9 J- L6 z* p
9 U# b% F4 k7 T3 u6 R1 y" M二,RT-Thread,STM32H7,LWIP简介
0 O5 z, H* e( n' hRT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是运行于MIPS32、ARM Cortex-A系列处理器上功能丰富系统。1 [( `4 f# I# s8 Z# `. E, m6 F

0 e  d( o( e. w5 I0 hSTM32H7是ST意法半导体Cortex_M系列最高性能处理器。主频高达400M,FLASH高达2Mbytes,SRAM高达1Mbytes,采用六级流水线,自带 指令 和数据 Cache、集成 JPEG编解码器、编解码器、集成 双精度硬件浮点计算单元( DPFPU)和 DSP指令。
. M! z+ I4 @% b& ^. S4 Y5 N+ z$ E- z) K, m) Q9 I1 G. X4 t
LWIP是瑞典计算机科学院(SICS)的Adam Dunkels开发的一个小型开源的TCP/IP协议栈。! z* d+ K1 |7 V3 C" z) s; T

* w1 V( f2 h$ F: Y三,STM32H7的特殊性
3 ?6 L* Z+ L7 Y0 f# z2 m1 A8 S0 b+ _这里的特殊性,仅仅只是对比F1 F4系列:. M4 k  s2 z; M8 Q* j2 u

5 O, U: w# f: {# I( R( `) |. tRAM) B3 F% ]$ Q( I" |/ i6 Q, m. p8 P) d
F1 F4系列只有一块RAM,在使用RTOS的时候直接分配给RTOS做堆就可以了。
3 h* @% T9 Q2 D' TH7的RAM构成看下表:
) A* I1 @0 ?2 e3 u6 q
20190504165951455.png
! h5 u7 ~1 X; p% X! ~6 ~+ W
- ^! W: @& B/ t; i' l/ f3 B2 b
DTCM的速度是400M,但是DMA无法进行访问。/ [* j: [2 D, v. S2 J: D
AXI SRAM的速度是200M,DMA可以进行访问。
; I& [2 Z" v6 K0 w$ H. PSRAM3是以太网和USB的缓冲区。7 w. a8 R' I" h+ J; x

. y* j" s2 p3 e6 w5 SCACHE! U* L0 j3 x; o( y6 C$ ]' x
H7比F1 F4多了一个L1 CACHE一级缓存,这个缓存在为低速存储器带来加速的同时,也为程序带 来了一些问题,其中最为主要的时数据一致性的问题。
! a) W, F3 j: C: ?' T2 P. }+ t  \4 `% K2 \
DMA
6 ?. ]+ a& S' K/ U" _4 o2 y# pH7的DAM分为DMA1,DAM2,BDMA,MDMA。其中SDIO和ETH的DMA又是独立的,就是说他们有专用的DMA和其他的DAM之间使用不冲突,无须额外使能,只需要开启中断就默认使用DMA模式。
# Y* n$ I3 X2 Y5 O3 z7 I" W. @. T. z9 g5 v
20190504172355726.png
- W# N: `0 F6 G) J( b0 [1 h: p& o

" P4 z) c) c/ Y* |四 ,移植前的准备工作
4 i9 H6 k; h! z+ L确保有一个可以在开发板上能正常运行RT_Thread的工程,目前RT_Thread已经有了正点原子H743的BSP,通过ENV工具使用scons --dist来把这个工程拿出来,复制出dist文件夹下的工程就可以直接使用了;
5 e" \4 o2 h  [3 ~& B4 ?: Q+ |$ V使用ENV工具,开启软件模拟IIC,因为正点原子的开发板的PHY复位接到了pcf8574的7号引脚,然后生成工程肯定会报错,这个时候从别的BSP目录下拷贝出pcf8574.c pcf8574.h phy_reset.c,放到工程里,然后在rtconfig.h加入以下代码来启用模拟IIC
* t# r$ @8 V7 ~& D, Q7 o4 ]. C/ w
  1. #define BSP_USING_I2C22 c! }$ h" Y- @

  2. % s2 a8 t8 V* g. ~
  3. #define BSP_I2C2_SCL_PIN 116
    4 ^3 K  N. o2 L, @* q* {
  4. #define BSP_I2C2_SDA_PIN 117
复制代码

' A2 {2 c2 `! v& `8 p这里的引脚号由硬件决定,如果不是原子的开发板可以省略这一步, j; N5 h& n- R
5 A4 W4 ?/ y8 X
因为RT-Thread目录下的STM32BSP是依赖CUBEMX,所以还需要在CUBEMX里面开启ETH的引脚,这个请和自己的板子一致;3 ^* S* I! i; R% S% [, V2 U4 ^

* c: l% P: x: Z
20190504230500122.png

$ l* O: ]9 M2 e1 F- U- [0 b4 ?/ s6 U" ]8 T3 `9 B% b
开启RMII模式,注意这里的PC1引脚无法选择成高电平,需要在生成的使msp.c里面自己修改为高电平,并开启中断。. t. \9 \1 ~. a* r( A

, S* C/ B* E, {8 s; x检查是否开启了I_CACHE和D_CACHE. x+ M( S) I. Y* t+ T8 V" D

7 L3 s. _, E9 O8 q) g' i, w
20190504230946919.png

" f. d) c* H$ z9 c: o3 G0 l9 s4 \. r  T5 Y, b. @: ~0 d
这里一定要开启,里面由依赖关系,不然会导致cache无法正确运行。
" t' y/ [4 i8 E  C9 F1 a* K  @1 W
然后通过CUBEMX生成工程并把时钟初始化部分拷贝出来复制到board.c中3 P6 o9 d& F4 G3 Z, _$ J) C

& r. b% X( U5 J6 K( T" i; ]0 H在drv_mpu.c中加入MPU配置
0 \2 M) `% A4 M" w( z, O, P8 f以太网DMA描述符区,只能配置为Strongly - order或者Device。
: X' z4 K$ }) C1 f! ?1 K  E- G% d
  1.   MPU_Region_InitTypeDef MPU_InitStruct;
    : s8 J% w" V* V

  2. / g6 f8 b. I$ [7 E% W5 Z
  3.   /* Disable the MPU */% e4 i+ H, F/ a1 i0 ^
  4.   HAL_MPU_Disable();1 R! `; {; K* d4 y  j
  5. - Q0 {2 [9 K; W  c2 R# n' T/ m" s9 r
  6.   /* Configure the MPU attributes as Device not cacheable
    * {2 g* q+ Z- a5 w) R
  7.      for ETH DMA descriptors */" u+ d& V* |! t* r
  8.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;+ K4 R8 {/ }  q! M: p5 z
  9.   MPU_InitStruct.BaseAddress = 0x30040000;9 b2 b) o6 ?7 B# T2 K4 z; U
  10.   MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
    : S: I5 \. V* [) F/ [0 _- d) Q" z' ^
  11.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    , D; Q$ H- g! D
  12.   MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;5 p/ `7 e  J+ U: U
  13.   MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;% a, K0 l8 M! s
  14.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    6 P5 l: }8 _0 C/ `# s
  15.   MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    ( X, {4 k7 B' y+ _0 f
  16.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    3 t: ~7 x0 x$ R* V% Q
  17.   MPU_InitStruct.SubRegionDisable = 0x00;
    $ s5 n' ]2 D) i& _9 D
  18.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;; p' W: [3 p- D2 {  y. b( }
  19. * A2 W# V2 y/ P* m1 y6 S
  20.   HAL_MPU_ConfigRegion(&MPU_InitStruct);
    1 z, R, f& c5 a5 r7 U
  21. # R+ h/ J; S5 P+ j: G  V
  22.   /* Configure the MPU attributes as Cacheable write through 8 A  f& _6 U$ H9 P& O
  23.      for LwIP RAM heap which contains the Tx buffers */% q+ X4 l) Q4 k0 j6 Y7 y
  24.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    2 u4 D, T% P6 e/ U( _6 w9 P. }0 j
  25.   MPU_InitStruct.BaseAddress = 0x30044000;" G9 L+ W; A: S2 T( p; ?: N' {
  26.   MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;  i! Q6 S  _/ T  T' Y2 S& K
  27.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;# M, q) G, r. s9 b- G; s
  28.   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    & k( C; C* y, U0 p
  29.   MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
    : x6 p/ S7 |" v* b
  30.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;$ Q" [- R/ A" b
  31.   MPU_InitStruct.Number = MPU_REGION_NUMBER1;0 Z7 u( ]& O6 b3 v; \5 S/ G7 l
  32.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;! n! v' Q& d- D* R* W2 j* Y
  33.   MPU_InitStruct.SubRegionDisable = 0x00;
    2 t8 I2 f4 g( H8 J2 q  n. D. q& F$ e
  34.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;4 c4 o! r$ @6 w; ]1 H6 r

  35. 3 e% T, l+ Q" j' t
  36.   HAL_MPU_ConfigRegion(&MPU_InitStruct);
    7 e0 L9 T6 U6 f4 r$ F! I0 W( K

  37. . C% [' W( R3 V0 [9 K% \7 m
  38.   /* Enable the MPU */2 B4 I1 C3 f' u5 J* V3 e& p! m. f
  39.   HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    + c! G& j8 C6 D+ h4 o1 ]6 S
复制代码
) g$ R% B; ], k: D  \; V( E0 N/ g4 F9 p
在工程中添加ETH库函数,stm32h7xx_hal_eth.c和stm32h7xx_hal_eth_ex.c6 ~; a/ P( D4 o9 L" n4 X. |

) H, p3 j" @1 Q" s' m0 T五,LWIP协议栈的移植

" Z. e1 }. M& F2 I( W8 S4 ~7 g. O# H该移植参考思路,移植也可以通过git log的方式参考这个移植步骤,但是这里移植里面有几处错误后文会提出。后来发现这个移植与STM32Cube\Repository\STM32Cube_FW_H7_V1.3.2\Projects\STM32H743ZI-Nucleo\Applications\LwIP,基本一致。5 P, [( x' @; _& U+ k

) O( d. X  Z6 Z3 ^  oLWIP协议栈的源码
1 _$ ?; r0 m1 g3 b如果你有安装CUBEMX,那么直接从STM32Cube\Repository\STM32Cube_FW_H7_V1.3.2\Middlewares\Third_Party\LwIPP的目录下把LWIP的源码拷贝出来就可以了。或者下载参考思路里面的链接把LWIP源码拷贝出来。( ^- r& f. E6 A. ~. j+ P
工程中添加新的文件夹
; Z$ D, P6 {8 p( _5 d  v% K
$ C1 C; ^( ?# s$ @lwip/api:添加LwIP\src\api目录下的所有文件5 e" s' {" V' L2 L! O
% P2 P! b- {4 k' q
20190505093456906.png

+ i+ {7 {7 d# N( D- q* s6 h; w1 {6 O$ f& L' f' R* W
lwip/core:添加LwIP\src\core目录下的文件,并包括ipv4文件夹下的文件. d: \# Q. w% p3 |3 W9 {

% C. _) B: _0 Y5 G. ~7 F
2019050509354914.png

# R4 N! e) N7 m, F) I+ q( G- J, o/ Z  T% M$ h: T# ~; g
lwip/netif:添加ethernet.c,sysarch.c
' ~* L3 B0 Z* T
. ^" I- D: t, D& _* s" }; f3 C
20190505093617351.png

  c* S9 ]6 ?" \( J- I2 \
: d) a% h3 ]# Clwip/port:添加ethernetif.c,lan8742.c(lan8720也可以用)3 t: m& V2 f" v, F, K
6 \0 f, }  p& F
20190505093754704.png

( v  s( \" `! q) O# ?
$ f! w! ^, [; _0 s8 C, q) A移植准备工作就全部做完了,下一节修改工程报错+ C& z. M; k5 m& b' E) \" g' P) w
1 m& u" n1 ?# }2 v0 Q) V

. s' U, F8 _& Z( s% }0 x  |
( G+ c* K2 l3 f& [
收藏 1 评论0 发布时间:2021-12-25 11:17

举报

0个回答

所属标签

相似技术帖

官网相关资源

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