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

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

[复制链接]
STMCU小助手 发布时间:2021-12-25 11:17
一,写在前面- @  n, Q; U% z3 g3 ]
STM32H7目前还是一个比较新的MCU,网上的资料相对于F1 F4系列相对来说就很少了,我自己在移植这个LWIP的时候走了不少弯路,得到了不少人帮助。写这篇文章也是对我自己移植的一个总结,也是希望后来人能少走弯路。1 p& Q; p( M& Y3 b3 W2 e
这篇文章有由个人编辑并整理,如有错误,欢迎拍砖。
; ^# P2 n  `/ @
4 c4 H  b  B9 B; M9 e9 M二,RT-Thread,STM32H7,LWIP简介8 v: e" x  ?/ [: P, M
RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是运行于MIPS32、ARM Cortex-A系列处理器上功能丰富系统。
# w% v: k+ y9 p- X" @- q! \5 X/ b% n& d+ P. {4 q
STM32H7是ST意法半导体Cortex_M系列最高性能处理器。主频高达400M,FLASH高达2Mbytes,SRAM高达1Mbytes,采用六级流水线,自带 指令 和数据 Cache、集成 JPEG编解码器、编解码器、集成 双精度硬件浮点计算单元( DPFPU)和 DSP指令。
/ T/ e( H. @" T$ `* K7 t2 J( J7 D( a% z$ V
LWIP是瑞典计算机科学院(SICS)的Adam Dunkels开发的一个小型开源的TCP/IP协议栈。( C8 A2 G4 U' V* V) B& D
0 G, }1 l4 e% F- N* G! A
三,STM32H7的特殊性
& o% g  ^: D8 x7 ]这里的特殊性,仅仅只是对比F1 F4系列:
/ F) |3 @( C% _! W$ l
  w" |$ B" g0 D7 f% W0 M, qRAM1 t8 @. E, `; y8 G; `, z. H- q! b
F1 F4系列只有一块RAM,在使用RTOS的时候直接分配给RTOS做堆就可以了。. r& G0 t+ Q3 b8 ~
H7的RAM构成看下表:" _5 Y: r+ J) I  f
20190504165951455.png
4 }- ?: y( d8 q9 U6 Q/ j- u5 u+ L9 J

! X" ?+ }( y. H! b8 `DTCM的速度是400M,但是DMA无法进行访问。
% A+ i2 }5 }9 |2 q  K" l8 U/ m  @AXI SRAM的速度是200M,DMA可以进行访问。
& O9 h- f( R( nSRAM3是以太网和USB的缓冲区。
/ o# _3 b, Q. G- U* @" I+ a6 ^, z8 V# h) F  B9 k
CACHE/ O& b' k$ ~9 O8 W, q
H7比F1 F4多了一个L1 CACHE一级缓存,这个缓存在为低速存储器带来加速的同时,也为程序带 来了一些问题,其中最为主要的时数据一致性的问题。
0 A& l6 n8 U$ z, h% V1 i" ~. O# F  H3 S
DMA' J! }+ x( d  m/ v! \; C+ V6 q7 G
H7的DAM分为DMA1,DAM2,BDMA,MDMA。其中SDIO和ETH的DMA又是独立的,就是说他们有专用的DMA和其他的DAM之间使用不冲突,无须额外使能,只需要开启中断就默认使用DMA模式。/ M2 n% L" H9 }
( ?- G  n7 M4 p* Y
20190504172355726.png

: K0 I+ k( @: E+ v4 u& J( j- N, X* Q
四 ,移植前的准备工作3 j$ U8 c9 h/ E6 U3 }( e
确保有一个可以在开发板上能正常运行RT_Thread的工程,目前RT_Thread已经有了正点原子H743的BSP,通过ENV工具使用scons --dist来把这个工程拿出来,复制出dist文件夹下的工程就可以直接使用了;1 V9 ~0 ^6 K2 P" j7 l- C: x
使用ENV工具,开启软件模拟IIC,因为正点原子的开发板的PHY复位接到了pcf8574的7号引脚,然后生成工程肯定会报错,这个时候从别的BSP目录下拷贝出pcf8574.c pcf8574.h phy_reset.c,放到工程里,然后在rtconfig.h加入以下代码来启用模拟IIC
- s# v$ `# R6 H; L( d. k# h
  1. #define BSP_USING_I2C25 J! i7 z9 @6 `5 ]/ K
  2. # \# `% F( u6 e( Q" k$ w
  3. #define BSP_I2C2_SCL_PIN 116
    : ?- T" B  {8 P- j) }3 H
  4. #define BSP_I2C2_SDA_PIN 117
复制代码
- Q; T/ c( g, s# C7 `8 I9 a- C
这里的引脚号由硬件决定,如果不是原子的开发板可以省略这一步5 Y, r" ^1 p7 m6 Z

" O+ e# p3 z5 W因为RT-Thread目录下的STM32BSP是依赖CUBEMX,所以还需要在CUBEMX里面开启ETH的引脚,这个请和自己的板子一致;9 ]9 N1 X: P' Z
1 F  V5 l+ K* G" f% I; o
20190504230500122.png

' C  {) h/ Q* e6 _9 b/ q: I- e  }, ]: I( Q
开启RMII模式,注意这里的PC1引脚无法选择成高电平,需要在生成的使msp.c里面自己修改为高电平,并开启中断。
( v. |& K  |* L" T2 M; h+ W
2 h- g) i( B1 \$ t+ y3 k9 \检查是否开启了I_CACHE和D_CACHE
# f" z4 q; U* @  S+ L6 `4 @  g8 a7 [/ B5 @( ~  p
20190504230946919.png
5 M% f4 k" E$ [4 i( D# F' ?
* j! y  v. W% ?. [
这里一定要开启,里面由依赖关系,不然会导致cache无法正确运行。: E, [9 s5 m- I8 I: P6 T2 M0 n

, F0 i+ `% {+ e- ~6 c0 O然后通过CUBEMX生成工程并把时钟初始化部分拷贝出来复制到board.c中
* D0 w: T0 p  R, u9 Y
0 H8 o7 B, Z9 ^3 N3 t' J# Q* y在drv_mpu.c中加入MPU配置9 F" Z0 c1 [- {) s* k
以太网DMA描述符区,只能配置为Strongly - order或者Device。( e/ p: t' {) X9 y& ?8 T2 D; D1 ?
  1.   MPU_Region_InitTypeDef MPU_InitStruct;
    4 h3 i, f" r; e% e! L" [& U
  2. 3 ^" h% L4 n: s
  3.   /* Disable the MPU */! H- r) u& n1 E/ [
  4.   HAL_MPU_Disable();
    ! D$ m9 r* T/ @1 @7 Z
  5.   q8 x& U& ~4 ~8 k7 D2 X" \
  6.   /* Configure the MPU attributes as Device not cacheable ; f7 [+ Z7 @- e2 S6 K1 x
  7.      for ETH DMA descriptors */
    " ^3 g. t3 B# U$ p% M0 k2 B8 d6 A% z
  8.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    ( C- E( v( ]5 t! ]% m8 n, v
  9.   MPU_InitStruct.BaseAddress = 0x30040000;
    ' v% S8 R6 B+ ]: L1 h* @
  10.   MPU_InitStruct.Size = MPU_REGION_SIZE_256B;+ L; S. l8 c3 w8 g8 }# q  z/ l
  11.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    ! c2 _/ y2 z8 J- l3 H! v
  12.   MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;& n' @/ X) ?" d  c' V2 v3 O
  13.   MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;4 \5 V+ ?2 T# ?7 z( z- E/ d" I
  14.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;) o* ^$ c+ H, d4 j! e. z
  15.   MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    9 D' v* z  c% y
  16.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;, i* q9 u4 t( r# }: d% \
  17.   MPU_InitStruct.SubRegionDisable = 0x00;  m5 I2 ?+ |2 \* p3 Q9 L, W6 L
  18.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;& O- `7 z. \7 r8 K+ x+ [
  19. ) O' i2 e1 o8 u% y
  20.   HAL_MPU_ConfigRegion(&MPU_InitStruct);$ s8 e9 |' R' {& T0 }' T
  21. . s" B' E( I' d3 |* E& X4 d
  22.   /* Configure the MPU attributes as Cacheable write through
    & v( b( ^. S) L: L
  23.      for LwIP RAM heap which contains the Tx buffers */
    % W) \! T, Y  U
  24.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;  g9 l! }$ _/ Q6 V( R5 K
  25.   MPU_InitStruct.BaseAddress = 0x30044000;
    3 ^) D6 A6 I( r; J8 d/ N
  26.   MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
    + L: ~; n+ k/ l% g4 Q, \
  27.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;* |: n0 q* b" H& j  l* X, [( `
  28.   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;. n% b! X7 a) \
  29.   MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;9 V/ \5 o% T6 @2 a6 G
  30.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    . t5 ]* j( A' B& S3 k
  31.   MPU_InitStruct.Number = MPU_REGION_NUMBER1;* z4 N1 r1 m3 U" [
  32.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;8 y7 C  c- ~9 n# P# y6 c
  33.   MPU_InitStruct.SubRegionDisable = 0x00;
    0 g6 K' o( [1 r4 y: V2 o
  34.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;, M6 D. V2 s7 I; |) P! T* p1 X- z

  35. , Y7 W& l0 ^- I+ Q) |6 l) P
  36.   HAL_MPU_ConfigRegion(&MPU_InitStruct);
    ! _5 ?- c7 ~% E  C9 \' i5 n

  37. ) }. R, ~8 k$ @5 w) c' y
  38.   /* Enable the MPU */& D3 l: P, U7 X- r, ^
  39.   HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    * B) H9 b# G8 S* h, k1 Y
复制代码
3 Q! D6 r) M+ Q
在工程中添加ETH库函数,stm32h7xx_hal_eth.c和stm32h7xx_hal_eth_ex.c
: Q9 |; {2 y( u/ F0 G1 k7 P0 M% t
$ a* v% O$ N3 |) K* ?! `( t' L* `1 |6 t五,LWIP协议栈的移植
. b$ r( H( l+ V& o  m. `
该移植参考思路,移植也可以通过git log的方式参考这个移植步骤,但是这里移植里面有几处错误后文会提出。后来发现这个移植与STM32Cube\Repository\STM32Cube_FW_H7_V1.3.2\Projects\STM32H743ZI-Nucleo\Applications\LwIP,基本一致。
3 T$ g6 Z) Y" [; r" G5 }3 q
; a( b, S, |- O6 V. I. A, L: WLWIP协议栈的源码( D6 F7 H" X8 q
如果你有安装CUBEMX,那么直接从STM32Cube\Repository\STM32Cube_FW_H7_V1.3.2\Middlewares\Third_Party\LwIPP的目录下把LWIP的源码拷贝出来就可以了。或者下载参考思路里面的链接把LWIP源码拷贝出来。
+ f6 `; V: V7 k) c- o- I  `工程中添加新的文件夹4 _# I7 Q6 D, d0 o3 x+ X$ v) q

+ k9 A/ j, Q4 \/ ]% Klwip/api:添加LwIP\src\api目录下的所有文件
3 z' Y' `3 c5 g  R+ _; _+ P( F7 T! T) k+ o0 k3 L+ \* L
20190505093456906.png
8 I5 |* E/ u9 F' l( W
' z6 _1 }$ M9 C
lwip/core:添加LwIP\src\core目录下的文件,并包括ipv4文件夹下的文件) `6 S  d7 Q4 M8 C$ u

5 D; Q. P* x3 W5 @
2019050509354914.png
$ Y8 k2 z  _4 k+ H% t) D# h  n
& d* c3 t( o3 b( K
lwip/netif:添加ethernet.c,sysarch.c
5 j1 u& i# f; H$ v" q5 M: j. T1 A  r/ ]; b3 }8 _$ R5 v
20190505093617351.png

, B- i  e: U: O' A& _' b
( F, M9 S1 m/ p6 Mlwip/port:添加ethernetif.c,lan8742.c(lan8720也可以用)+ X# a! u$ c4 p) {: h
2 Q7 |" f; F+ G3 m* z
20190505093754704.png

, ~; ~- A5 o% K3 U7 @- w- R  t* I0 \% W1 |
移植准备工作就全部做完了,下一节修改工程报错
  R' T5 X0 z+ A9 H8 K8 I- N# D+ W/ B- {
  J( Y" q6 {6 N( U  `

  @$ |+ l, \. _5 }9 I
收藏 1 评论0 发布时间:2021-12-25 11:17

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版