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

【经验分享】STM32F0移植RT_Thread_Nano, 使用STM32Cube

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍
4 M  v/ C6 N4 a1 t; q! p  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。
! J, B! I: C3 G5 E9 v& w( h2 h8 B( D1 F" X# f
AI[KPXW81}UWZ~_C_U1JBZR.png

8 n+ q% y, Y" p) ^( i, n$ k
/ N/ W1 }2 r. G. r6 x2 ?/ _1 @6 ?安装rtthread_namo包
% @9 L2 D# Y0 t8 k  h在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack- D7 y0 p# B, W9 |+ b

% h" i9 M" N, Z, i1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装3 @. U; b4 v* E( R2 ]3 A- I2 e

7 ]- e5 u" h5 `. ?
20190626221653457.png

' \# _( ]# U/ C6 Q
: U' B/ p9 s: S
20190626222025313.png

4 ]/ V( F  \$ d) p1 M
  X$ y+ f: e+ r3 j2.在弹出的节目中选择Next,等待安装
) x9 i3 |+ i: k
  s1 c, P* K: P5 a/ `0 n+ m
20190626222140363.png

7 `8 L6 l/ u' F, C; T0 L! v  b4 l& a& n* T
3.安装成功后,Reload Packs即可。6 G. W0 b' o8 K0 [
0 b+ D4 _4 P* K3 t( s
20190626222321230.png

& T, ?4 x- B/ D/ Z0 G* [
6 p& }' S7 h: U* a* q$ k创建工程5 q) o3 C9 n, S6 X% o) Z
1.选择芯片STM32F030F4P6* l# N3 T8 i6 g9 L! N& X

/ O3 w* e0 F/ G3 y$ E6 d# `' k3 A# }
20190626222525565.png

# T4 M% r2 z, H4 L* B3 T8 Q
8 t/ x0 S; Z- r9 ^( s7 J2.Manage Run-Time Environment/ [+ M# k' a: N% t- v  D

8 f6 ?: {- S5 }0 e8 L  J" X
20190626232949409.png
- o& T8 `3 e) {/ K8 l* ^6 U" N4 b- l
1 R8 \4 [) e) `3 r/ I5 h" D
   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。
0 x( \6 g% j' O3 M1 X% Q9 O( K" s5 n# z# `
3.Start STM32CubeMX* f# F# g  F" y4 Z% a

5 G% W. L4 N% x$ h* \6 v* }5 \# V
20190626223125381.png
8 }& |5 |* b4 }) R4 X
6 \9 e7 \$ @" i" `2 |. O+ w; T, ?
   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。" r6 k" a- ?' }3 i$ R6 h0 e& n( v

" t! c1 }7 ]- d9 F' P) K4 u, r7 H% y4.STM32CubeMX配置Pinout&Configuration
6 `; W2 D* A% d2 @1 B5 W( P
4 g0 l# q& F% H% v& u
2019062622382861.png

1 ^( r- r6 o1 S3 a! Y
20190626224105362.png

2 b6 Q* B' x& N: D1 m) C$ p
20190626224233634.png

. z3 j; p( r8 M; B$ q7 u( M' w$ e$ Q0 o3 ]. J1 l$ G7 l5 U- u0 _% h
5.配置时钟! U: [: C' ?; M+ D

/ G' V% q4 Z! U) V9 h  _
20190626224701758.png
, }( f8 Q6 Q9 q

" Z/ H# r( S# ~  X6.单击生成代码
2 c! s# o' ?/ d
7 j5 q1 G. a; }7 v' n
20190626224854251.png

4 @  |% B5 q; `
( D- f- q- G  J. i- Y$ b0 l% ]8 x7.生成代码如下% J% `4 _* a- S4 W! |- T
0 R8 i) e* L0 O# L: J
20190626225932442.png
5 s( k& D# Y- v3 L) `  S5 f% l

+ m/ L: o5 `; g" o0 W配置工程9 \, r9 F! ~) X
1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置
8 Y' X& `: c- V" v: p
# [! N: o# W# z8 v+ o3 J
20190627004726239.png

7 `" `! r& f1 g4 o3 X; [; h9 g: Q% R1 f1 r- v0 w+ O
2.内存管理设置
, ?$ q1 k8 [! |" ^: [/ p( y6 V7 t/ k
20190626232130606.png

1 `5 j. `$ ~( e/ l" T$ h$ g# A1 n8 J# [& d0 K& s0 i) L) F
   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。9 U7 m; v) M" t8 E- _- z$ p
" u/ A6 l" t+ @* s7 t/ B
3.关闭console和Finsh3 c- k% Y. _+ h: X

% V- o8 i9 r7 b
20190626235930620.png
2 U! b5 W, K3 M5 l5 _" v1 o

7 U8 y- w  X' R   由于我们并没有接出串口,所以关闭串口相关的内容。
4 O  S1 ^! k+ O/ }" r$ R) ?  F0 C$ V# H0 u5 j2 B" b
修改代码,测试3 w3 I7 z% j' H$ h
修改stm32f0xx_it.c文件
: g4 L% i% A" \7 P   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。- S4 _' Y9 r  [. h# {$ ~3 k- l$ R1 p
  1. /**6 k9 T4 B4 f+ A6 D$ A9 y1 O/ B
  2.   * @brief This function handles Hard fault interrupt./ ?) O; P: B! U
  3.   */
    & R3 {$ G1 b1 N: I
  4. __weak void HardFault_Handler(void)
    : U. ~. _( t8 J4 l
  5. {$ |, Z' j" K8 ?
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */+ [% s- L1 T$ U8 X1 o3 \

  7. ' I9 Y5 H) c- y, `0 f3 w
  8.   /* USER CODE END HardFault_IRQn 0 */
    ! U  x! _, p: [4 @8 r3 l' y
  9.   while (1)
    ' B  O& ^, h7 b" b
  10.   {6 @6 y/ V, D* l$ `8 U6 t# Y( s
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    ( i1 Y, r2 k; @; K+ a5 R" m. k
  12.     /* USER CODE END W1_HardFault_IRQn 0 */2 R  p: [  J: K3 p
  13.   }
    9 ~- X* q. T8 U# k) q, }
  14. }- Q& ?4 h6 ]) I# M. U& g

  15. / o) F( I0 I! Y- x
  16. __weak void PendSV_Handler(void)3 ]. P4 W3 I, V! C% j+ S* u
  17. {5 P6 E: f3 R* U& Y% a4 e/ h
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */
    / {4 o9 e$ A5 C/ o; U7 I& B5 @8 d

  19. : o7 s! a0 _* {
  20.   /* USER CODE END PendSV_IRQn 0 */
    * B% s/ i4 n# G+ K/ U' m
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    , }) t6 E- W- G! v, D* m! U
  22. - ~) f7 T( B1 ?# H( {- z
  23.   /* USER CODE END PendSV_IRQn 1 */- g: g5 z4 K4 Q
  24. }
    - l' O# f4 u$ }$ ~$ _

  25.   z% f6 `7 ~. F0 p
  26. __weak void SysTick_Handler(void)- z  m; ]6 |# y
  27. {
    5 h* j1 F$ j/ a9 Y# ~6 U) F. A3 o) ^
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */
    $ v! R& \, i; v( K' }
  29. 8 c  C0 D, y2 }1 H! i
  30.   /* USER CODE END SysTick_IRQn 0 */6 K$ r/ \2 q9 s9 }( N
  31.   HAL_IncTick();
    * t* ^: U5 ~1 }# f  S7 N) R% S& T
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */$ q# ?8 d! d+ b
  33. ( U+ H& H! `1 j# t4 y
  34.   /* USER CODE END SysTick_IRQn 1 */) h+ ~0 P5 v: v/ F8 g7 F- |
  35. }
复制代码
9 M7 I: H0 |' z4 P/ U# G3 Y3 p
修改时钟部分* y5 L5 E& X6 A
   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。
: M: {. p1 X7 Z$ x9 p3 G   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。6 c7 h2 r' |7 h5 g- u
  1. void rt_hw_board_init()! F) c: o& A2 Z% z1 c! X) W8 c- M
  2. {        + q5 p$ w' e& x
  3.         /* System Clock Update */6 s% T& p" h, B/ J3 z$ _
  4.         //SystemCoreClockUpdate();
    $ j6 \7 T8 s! [1 `: G
  5.         HAL_Init();8 v( h8 o* J$ I
  6.         SystemClock_Config();- s2 s7 q7 p# K  f, ~) q
  7.         
    3 ]; E( i0 a' g2 e  j! U8 Q1 x
  8.         /* System Tick Configuration */
    1 ]6 O' z7 L1 F8 G6 X
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    ) }( i' E5 k. F) {" S2 @! V4 t
  10. / Q4 U1 n0 j. \2 b4 x
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */
    1 a( @/ n/ F) W4 t+ R% l. W2 G
  12. #ifdef RT_USING_COMPONENTS_INIT
    , z4 [, v+ }# f+ J3 i: o& `
  13.     rt_components_board_init();" D' [' g/ q* d
  14. #endif  E- \& ^& @; }8 d0 o5 ^
  15. 8 ?* z& p( i& q* g/ ]1 [
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
      K) L( u7 U& _! Z+ q& o
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);9 S4 i) \0 V5 {+ G; o5 r
  18. #endif; d, S6 ?& {. Q+ ~# v- B! G( f2 I: r

  19. . P6 T! S7 f; N/ ], {+ Y
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)& o* k2 N3 ~) g" ?- y' W$ t8 u
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());# a. F  D6 X9 _0 [" |2 h- ]: h& P
  22. #endif
    . R- k2 {- S* {  o
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。, ~6 ?# k( a8 y( K# I% F
  1. void SysTick_Handler(void)
    : E1 z5 m+ r% c+ s
  2. {( p) _% ^0 m# q; G0 T. p
  3.         /* enter interrupt */7 y7 ^/ g& j* H
  4.         rt_interrupt_enter();3 j* |; ?1 [5 Z/ m/ U; o5 S

  5. 9 ?! a: Q4 G8 e4 X- y
  6.         rt_tick_increase();+ b2 l* x: o$ ]: O2 x
  7.         HAL_IncTick();; v5 V8 M* m% R4 ?0 ^3 B
  8.         
    ; a# V: X* g: W$ ?
  9.         /* leave interrupt */) w; p1 g" a4 t  K7 t6 }  Q9 ]4 @/ e3 {
  10.         rt_interrupt_leave();
    9 L. m3 T. U9 b+ \3 T" X3 q3 y# H
  11. }
复制代码

, a( m5 R/ P1 e. l' J  g+ |3 H- t增加用户代码
) d' k* j5 H0 a/ M     
  1.          while (1)
    3 @1 o' g8 _( ?/ z# o5 W' Q9 B- g
  2.         {
      ]& R; n: @* {% ^6 x; l
  3.                  /* USER CODE END WHILE */
    / R5 E2 R) X8 E  e) n$ t
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);
    : F/ f3 ^$ q2 g, n
  5.                 rt_thread_delay(500);  # {; i$ t, g* \4 w. ]' S
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  
    * j/ F5 j' R" Z, i' W6 k; w
  7.                 rt_thread_delay(500);  7 B4 j# {/ }' |$ L! O
  8.                 /* USER CODE BEGIN 3 */# Y) [  G3 ^& p2 @
  9.         }
复制代码
- t6 m  `1 {: k- z
编译测试3 t5 u1 Z1 C: X3 {
1.使用ARM Compiler version5 进行编译,结果如下:
: V5 t2 ^/ M8 f" w+ u
+ ^8 ~/ E0 n9 E8 Y! B
20190627003559464.png

7 y8 e  t0 _+ L& r, v( Q
1 a+ T; O8 r8 P/ o% v$ V) P2. 使用ARM Compiler version6编译,结果如下:
1 S" E1 ?* ?2 s$ i; f  i) O4 p2 Z& B$ D# G# b
20190627003658959.png
# \1 M( z1 }3 W2 t. f  I+ u

! X3 {$ r/ ]! {/ }. J9 p  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。( S# ~, q3 w7 \& W/ a/ J

/ E5 Y- B: y! Q% H3 ^: G7 C
9 }+ |- Z$ ]( Y' z5 Z2 z
收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版