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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍9 i* s' d7 @, U$ |5 {, r3 }& X
  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。. f) {3 S2 N2 k6 b/ I' x* n

" g0 f9 f+ s' t- l6 Y
AI[KPXW81}UWZ~_C_U1JBZR.png

5 l& V3 p! L$ e; E
5 v7 L8 a- h5 _* m( W安装rtthread_namo包: z3 I4 T6 S' z
在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack7 ^" V- z8 I1 _1 H0 `5 ]
# {8 _( k8 Y1 X4 A+ w3 R" S8 a
1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装
3 ?3 U6 m" |5 _  I) P* K
* o! j- G+ j: t8 A/ S
20190626221653457.png
9 }5 Y  ?" |0 ?+ C+ W0 H7 e

  H; g8 s# W2 P3 d6 i4 |
20190626222025313.png

5 r3 v8 d8 ?% X% Z7 _' E+ ], [& X' q2 e- U9 f9 k: o' `  [
2.在弹出的节目中选择Next,等待安装
) L, k# e1 {1 |% d2 o6 t1 B  K2 m! F
20190626222140363.png

0 s* c# f/ k$ x+ ^0 \% }7 K9 G& {/ S( d# J  l
3.安装成功后,Reload Packs即可。
8 B  `3 W* ?) F, H% K, y, p+ M6 c- t- Q2 D
20190626222321230.png

7 i+ @+ O  R0 Y7 O
" N( |" ^/ l7 ~: f- a创建工程
9 n* w) P  P% E1.选择芯片STM32F030F4P6
8 _! m2 p( c/ q5 \2 v, Y5 G0 R" c0 U9 m6 [
20190626222525565.png
7 l6 [$ K" R& R7 L6 z

4 N4 `. y- i% U  ]# }) Y: v2.Manage Run-Time Environment
$ ]% N2 V7 |2 J  h* S
8 W7 t0 w0 s8 r  n4 o8 }
20190626232949409.png
) C8 Q0 u9 X- A# l# ?0 _% d; w
+ G$ w. i6 [7 o* {0 z$ g% ^5 `
   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。
0 G, c4 Q2 L9 m4 n! Q- F3 m4 q8 G( Y% N1 w
3.Start STM32CubeMX1 ?8 ?, ]7 z% K  n; {; v
/ H. W4 E7 h! E
20190626223125381.png
3 j( w3 T3 L  w0 P7 i9 n

* T1 u. O4 V& |" o   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。
1 B* J& Z+ z) \+ C; O6 d( T; o0 `3 o3 f  a; w6 o
4.STM32CubeMX配置Pinout&Configuration
5 S3 O" Z$ c3 A+ r4 J7 Z' ?5 H+ Q
2019062622382861.png

: u  |4 C/ \0 ~" F
20190626224105362.png

" N7 g/ Z/ B7 q' I1 O: b% [, {
20190626224233634.png
  }2 X9 i( }; B) h, B6 W1 j

+ a. m, J7 {, ?2 J5 W' V0 y5.配置时钟# K' ]  C1 L8 k2 n. L: J' R4 }6 i+ \

6 ]2 G2 k5 T1 T; L+ [4 `
20190626224701758.png

' y& g# F& o/ ]1 |8 z& n7 Y) S3 M6 r& G! u' T
6.单击生成代码
4 }: ?  m# }) n  T0 l9 M# ]4 d0 [5 e1 r! q$ i3 K3 w
20190626224854251.png
) S# Q: i, G; b& M6 ?, f
3 _. b9 g7 Q# W+ C6 l: d2 x
7.生成代码如下0 n8 c7 N3 E0 J: G

5 T; t9 u3 G: ]% K; J- o+ Y0 w- G
20190626225932442.png
. Y+ @' t3 Z+ R% k1 j
7 {- ]' r4 r$ E2 R& `/ Q
配置工程
" h/ f. ?# _7 g/ m1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置! i: J2 I, Z- C# ]
" w0 b! m! ~% D; q
20190627004726239.png

! D0 e. W$ R. M( f
9 R7 Y2 f  J/ N( c! T2.内存管理设置6 l: i8 b: P5 l2 Z

* @, H- z( \4 P* S! x0 _
20190626232130606.png

9 t1 D/ {% h, q+ X6 }  ?. E/ I. \! z$ U. q; _3 F: ]  v
   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。8 w" m* A, }0 O1 O& [" v/ t7 V
2 l  _" k0 E3 ]( i0 @4 F+ o) ~
3.关闭console和Finsh
8 L! s+ c* w$ k. d* S2 j# x3 v( w1 N$ M. b: ]# B
20190626235930620.png
8 G/ H0 g5 T# Q& o: n( y
1 x( U3 W, F; Z* q
   由于我们并没有接出串口,所以关闭串口相关的内容。
& c$ |3 y( r2 ?8 z% K
4 `: M; j# p/ l% V/ Q# C修改代码,测试
3 p) \( e& W* a+ p$ `修改stm32f0xx_it.c文件' J5 x4 r' [( O- F
   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。
$ U6 O5 L) d- [! ^! i
  1. /**
    $ W+ a  \( C0 n4 e, i! A
  2.   * @brief This function handles Hard fault interrupt.
    : U! V! P" i* e9 j# _, g
  3.   */
    ' [$ l  C, H% d
  4. __weak void HardFault_Handler(void)
    0 u+ G5 c& o- B( o
  5. {
    5 P( H7 A+ i' J4 X
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */) e; ~$ L: v* O* q3 g, H

  7. ) L* y/ H; F9 U/ H
  8.   /* USER CODE END HardFault_IRQn 0 */
    8 G& N. K% S! K8 F
  9.   while (1), T! b: J* g' Y6 u
  10.   {( ]% G! Q! W7 ]5 U! T4 Q5 j8 Y
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    6 o; p5 p# \+ l- W- `% b, U. X
  12.     /* USER CODE END W1_HardFault_IRQn 0 */
    + X: b6 L) O; v9 X  i1 ?
  13.   }0 a) a3 _% V* ?" y9 {) }1 h, U" [9 _
  14. }
    4 z- W% ]# Z$ C* g: z
  15. ; p  h1 |8 [) j6 T: e
  16. __weak void PendSV_Handler(void)
    8 E& Q* n' F2 ?
  17. {
    : q8 z+ O5 G7 s; b) {
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */* Q: J+ Z* W1 F. i4 l
  19. 6 T! l; u% x& D8 t' i
  20.   /* USER CODE END PendSV_IRQn 0 */
    2 J, \. S: b4 Q) Z& b: _
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    - [$ P* q  `2 Y3 Y6 c1 N
  22. 5 f$ C2 U: S) i9 w3 G" F
  23.   /* USER CODE END PendSV_IRQn 1 */
    # K) _5 n0 Y/ W5 P
  24. }
    ' f1 E7 G$ x7 R: e! _8 E
  25. . ]1 T  Z' ~& c
  26. __weak void SysTick_Handler(void)
      L& h; O9 K- x* [9 P; a3 |
  27. {
    9 d. l/ P( A4 [( l% U/ `- u3 o
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */. g8 w+ a  K% d

  29. # c7 k, I0 ^6 p0 E
  30.   /* USER CODE END SysTick_IRQn 0 */( W4 r; ?$ Q! {4 p
  31.   HAL_IncTick();
    * s& g& w/ e$ T' T5 e
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */  ^. x* B* {+ _* D

  33. # L% o0 T4 g. t3 q3 |' e4 M' O
  34.   /* USER CODE END SysTick_IRQn 1 */
    ) K1 s0 x; b. B/ V% }8 @+ l
  35. }
复制代码
/ H- T: n( E/ I- ]" F
修改时钟部分
( w& l/ F& B" v7 q& r1 N2 \   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。- E1 Y& H  v/ U& a1 u* M9 j
   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。
& i" E- }* ]4 p0 f, R' W* G& d  q" L
  1. void rt_hw_board_init()# }- `+ C8 f. k: T9 E" l
  2. {        , g$ Q1 S4 S* k9 Y% q- T4 T3 ]* Y3 G
  3.         /* System Clock Update */& @4 S9 Q+ L  n( X; Q( ]
  4.         //SystemCoreClockUpdate();
      i: m. J  b2 K# B; |2 s
  5.         HAL_Init();
    8 b% n- s! t* @
  6.         SystemClock_Config();
    7 U% ?% d" A& o6 V' @# K: K
  7.         
    5 E, h- g, P' h
  8.         /* System Tick Configuration */: e- s% f$ q  u: ?8 E3 @
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    " G1 E. A& D( E; D& u
  10. & h" b; P# l6 ~, a5 u
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */
    . m  S, Z$ {1 _
  12. #ifdef RT_USING_COMPONENTS_INIT7 Q0 F3 C, _% K% _
  13.     rt_components_board_init();0 l( ^, P3 _9 u7 H3 U7 l  d  n# l
  14. #endif' C: _: ?  ~+ _) _9 _$ b
  15. 6 Q/ \$ ~6 \; [& X5 c+ W
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)# \+ K1 y8 y6 z4 [2 ?
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
    - p" x4 m) k! g2 s
  18. #endif
    + q3 Q7 i; x. X5 R: V/ _
  19. / ]- ?, K/ k$ E$ `' p' k
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    0 Q9 s+ z' W* U9 ]+ D8 L
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
    1 ]- }, e8 E" G8 l/ b2 f6 c, ~7 |" z" ~
  22. #endif5 a) w" y9 Q4 k' z2 f, K0 U
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。, {4 h5 D- x. `7 [5 Z
  1. void SysTick_Handler(void)
    / I+ J$ D* w5 m" S3 p
  2. {8 |3 @( V* Z: G8 a7 j- a* ]
  3.         /* enter interrupt */
    ( u- d* ~2 K) B  R
  4.         rt_interrupt_enter();
    4 P1 f7 o1 w" t0 X3 M6 Q

  5. . {- l- a" l1 m+ i" y
  6.         rt_tick_increase();1 V2 A8 W8 _# f+ G( |3 b
  7.         HAL_IncTick();% t9 v5 ?. Y% [: J3 Y
  8.         0 ?$ n8 C4 \6 z2 v. h, [
  9.         /* leave interrupt */- K% A) f" U' E2 y
  10.         rt_interrupt_leave();
    % A" [" B( H( U/ S8 T/ O5 e* G
  11. }
复制代码

2 f' ]2 |/ J# u3 v增加用户代码
4 J& X6 s# @/ N, e     
  1.          while (1)3 S8 D# y* t5 W% Q, b2 O) ^
  2.         {
    9 f2 ^: h, U# h4 I6 n) W4 |
  3.                  /* USER CODE END WHILE */
    2 T0 V7 A, k( B* h4 N8 s2 e
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);( j/ R9 w/ `+ s
  5.                 rt_thread_delay(500);  ) A' o& ]) ~5 @1 Y/ K. V& A5 w
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  1 i0 G: J5 o: R. P: [
  7.                 rt_thread_delay(500);  " ]+ N2 R$ A9 p$ p  M
  8.                 /* USER CODE BEGIN 3 */5 m% z: O0 j- q& q9 s$ M6 M+ r7 ?
  9.         }
复制代码

. p  M3 g: I! P8 }- S! F% {编译测试2 X# X% Y# t/ c* }) E( O% M
1.使用ARM Compiler version5 进行编译,结果如下:
7 x3 K) B$ y9 {; y6 p
2 x5 f$ Y# S5 C* @9 ^" Y7 A
20190627003559464.png

; L5 W2 G: V* _& E0 R0 T, k+ F6 Z( }* E
2. 使用ARM Compiler version6编译,结果如下:+ S$ b3 p  S( ^( x6 z+ I; H# w

. K8 J, F4 V% i5 C
20190627003658959.png
5 ?# f. i" y" O' d( f4 ~+ V

/ A; a5 n, x: u+ G& D$ ?  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。* p  k& u9 m* C2 `) D
" B5 O1 x$ u: c2 p

, ]+ l7 W/ P# P, N
赞 收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答

所属标签

相似技术帖

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