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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍" \  r( d$ C: _! c
  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。
" j; `# H" I+ q  J! |- l8 U2 W; h0 V2 c# M4 o. N
AI[KPXW81}UWZ~_C_U1JBZR.png
& [7 y0 C  T1 N; j
6 s# M6 p* v* x- W2 n$ u4 E
安装rtthread_namo包! b) S$ m/ @" P9 J; T& Q  n& P
在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack
1 Z- E1 o* G3 |8 m7 a, ?
# g! i! r# n9 K2 O6 v5 o1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装; u! n% a+ Y5 K2 R) T% J) p0 e& F5 Q
( N7 h7 ?8 j3 {& u3 Q
20190626221653457.png

) [4 R* g! K" R3 }8 O  u! F& d- E4 q$ }
20190626222025313.png

8 x4 `7 W0 ]1 k. X( k
3 H& V! i' v6 [- c2.在弹出的节目中选择Next,等待安装
) t4 u8 S8 m" s2 C0 H
: J+ P$ ~' f0 o
20190626222140363.png
0 s, L9 e# w( Q0 ~; Y6 `6 q
' ~( p0 W( K8 \8 ~9 z
3.安装成功后,Reload Packs即可。3 x' E4 g! n/ _! v3 B' Y6 d- h

/ @8 F" {% L  \: o# s
20190626222321230.png
. e7 }! w: x# A4 E; M& F

, z! p  h0 a! f: T; [创建工程
/ n/ a. w" \9 u2 Z1.选择芯片STM32F030F4P6
- Y8 p* T' P7 n) k: O8 x& V6 k7 S+ \7 A* E. E) I' m& H
20190626222525565.png
- l: D$ m% Z! z; @; A

! M$ H. m; A  O) H& L" A: Y2.Manage Run-Time Environment5 J9 t) g0 q6 p

; Z/ b* c. N; ?, W6 O( g- t0 c
20190626232949409.png
3 W6 Y9 M7 u  E( `
7 ?! `  K% j( D0 \$ u/ I
   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。
: O7 Z: f+ {/ X. U. B4 j6 s3 S9 m* |( t( U' h, b# o3 f! J
3.Start STM32CubeMX
) H5 g/ v8 S3 {; E, Q9 j" f
, J- E" o* c1 F* e9 D. L1 {. i
20190626223125381.png

4 ]9 f" r; e$ N5 q) f5 W8 S0 Z# m- z5 W) r: n4 T  c" e
   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。: e6 L5 m  P; P* f. y+ z) p0 x, i
  ?: i: x8 Z$ v; t+ |  f8 u( d/ _
4.STM32CubeMX配置Pinout&Configuration' X1 q! z" x/ g% C9 L
& C9 w' \, C/ m# N) h6 P
2019062622382861.png

. b8 T. Q, b2 b' r3 p, I* X
20190626224105362.png

2 a3 t% K- G; [% }
20190626224233634.png
/ g7 h. ]* I" f9 v4 I
- w8 s" T, f$ Q3 r* K
5.配置时钟
( D. K& F2 ]) I' n6 k
/ v$ f/ C# u- L# X0 h$ q
20190626224701758.png
6 w8 ]3 s; ~6 u
$ I/ |, p5 ]$ g
6.单击生成代码
/ T+ ?; Y# r& J$ Q2 e) F& a
) c  I0 x3 P; i% K
20190626224854251.png

, D: b, ?3 [1 i- b: g& M. i
$ O, D6 z+ ^2 S4 T, U+ i9 ~7.生成代码如下7 r8 j" c% X# m+ d/ b
( J3 L% n/ C7 b& U2 j' q
20190626225932442.png
* t/ k4 |; J2 F
5 f0 h# l8 `+ O! T9 y  Z
配置工程
; q: F* @$ Y- K; P# t2 f$ N7 x1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置8 l1 O1 t$ J, m7 ?" H1 v! m
2 A# L  \8 S1 W8 b$ D) r
20190627004726239.png

* \6 J0 D; g! A5 r6 W% i) y. t( A9 Q) t; a( K% Z; A& o4 t1 Q( Z
2.内存管理设置6 v' H2 x7 x# W' k: {( b1 I

! t1 R  u0 ^& G  j6 B; E9 X, G
20190626232130606.png
$ S' X6 h/ V, R4 [
7 U: U# z) u1 h$ Q( D/ q! U
   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。' J0 h  Z$ [$ m% v1 ^7 h

! b* l* j3 K, z' L# V5 J7 R3.关闭console和Finsh& u! R4 @% ]7 _4 ]- r7 ~

, E& y! I% [* X/ H* l/ g
20190626235930620.png

8 P& x4 o; P) c. j, Y6 s
$ `1 a" @5 F2 d1 G6 L: C   由于我们并没有接出串口,所以关闭串口相关的内容。
  n+ ^$ g3 ?4 R; J& \" b2 b3 a& x
6 r/ y: R( v7 [7 [修改代码,测试9 ^" g: ~2 x! a% v6 x
修改stm32f0xx_it.c文件, P) v) w3 U* @. c
   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。
0 O$ r/ `  j1 `% p& U5 [0 f% Y
  1. /**' R  u8 S! ]! Y
  2.   * @brief This function handles Hard fault interrupt.1 I9 \6 q. M3 C2 S4 h
  3.   */1 @4 y4 L- [1 d+ _' ~
  4. __weak void HardFault_Handler(void)9 x6 e3 d& W% \' O6 P
  5. {. r% N- e! r4 N
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */
    / A4 i5 p8 c# c0 {
  7. - y+ g5 Y' N5 B; a
  8.   /* USER CODE END HardFault_IRQn 0 */
    3 ?0 R5 n7 i- q) C
  9.   while (1)
    8 S: ~. _/ _  l% h$ F; v& j
  10.   {' d  P6 Z, `& r) K
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    : z$ \+ {' |! G
  12.     /* USER CODE END W1_HardFault_IRQn 0 */
    # Y4 H9 R+ i5 ~4 E7 x
  13.   }
    5 G. W# ~0 ?; U6 u
  14. }
    & E$ V8 N( e; q, S, W2 F' w. s

  15. ' V% j% Y3 t  L# [
  16. __weak void PendSV_Handler(void)1 B1 `8 D! S6 f, M4 P2 J2 J
  17. {& \0 A" b% W2 O) X8 M, P
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */
    6 l/ ^# F: T6 E5 z4 A2 z1 T7 K
  19. 4 O- X1 J) U4 ]
  20.   /* USER CODE END PendSV_IRQn 0 */  [$ D7 n7 ?& M
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    * M; S) v: ?- I  z

  22. & M  H3 n" d. Q1 M+ [5 _: C
  23.   /* USER CODE END PendSV_IRQn 1 */
    2 d. j1 w! ~; y" q; \1 s/ o6 h
  24. }* @2 @% ~+ a2 S. X) q4 Y( [

  25. % _8 M4 h+ n) N! y! R6 T! L  {" ~
  26. __weak void SysTick_Handler(void)
    % y7 P" ^. d  q- w1 s
  27. {
    9 s  [/ }1 M' ?& ?( c7 }) G' s
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */% M3 V  j$ ^/ Z' E3 j
  29. 6 Y3 ^0 Q. T$ p0 a
  30.   /* USER CODE END SysTick_IRQn 0 */
    7 e4 ]7 c) t$ W& T' @7 H
  31.   HAL_IncTick();
    4 H, {, k2 H8 }. W# n
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */
    9 h: i. b% [5 M8 q; U; a

  33. , ?" f1 c  ~2 r4 V: M
  34.   /* USER CODE END SysTick_IRQn 1 */8 ]" |6 j- Z$ g( @+ w, C( ~
  35. }
复制代码

4 d3 ~4 n* |! q: r修改时钟部分" E! x$ ]2 [& u7 O  \
   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。/ a' S. J6 q; {$ ^2 K- y
   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。
$ z4 }9 W- E  E5 l1 C; e
  1. void rt_hw_board_init()
    0 I$ u; T0 i, x/ o' L# u6 X' C% U
  2. {        & Y5 c( q, ^! O7 W) q( |, P; ?
  3.         /* System Clock Update */, G6 {( z( O$ A( K; j( `
  4.         //SystemCoreClockUpdate();2 K' N) J. B$ N' V9 I' `5 O+ U
  5.         HAL_Init();
    : }9 P$ b& j$ L7 G0 Q) {
  6.         SystemClock_Config();
    ' \2 J: F6 @8 H! r, \& N- k0 n, Y
  7.         # @) j5 i3 U1 j; T0 J
  8.         /* System Tick Configuration */
    , y7 {- u& Y* i8 U3 M
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    5 e: j' Z/ s! ^
  10. 2 {& X8 {  y( q0 k. s6 y
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */
    ' t5 H3 o* d1 y- ^( \! Z7 p
  12. #ifdef RT_USING_COMPONENTS_INIT
    1 p* |" ?' J0 s5 k) S
  13.     rt_components_board_init();
    ' i# Y: `& R# z& P3 G  t  T* ?
  14. #endif2 i0 c9 G7 R! y0 q/ W. s

  15. , R1 H2 a1 v7 ?0 V" H* N
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
    + x+ {! P( L. V$ G% T
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
    7 j* n- k, u9 P" ]) a9 B% }
  18. #endif) i  @3 y& j; {) p+ ?5 Q. T4 u

  19. ( ?7 _6 c, }0 t0 T% K9 n
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)1 K0 ^6 i; m: A5 r- C
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());7 i+ w, G0 b6 T2 u3 f% v
  22. #endif
    + k0 z8 ^$ L6 o" C! D! S
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。* _& p" s9 [, J( Y- ~/ p: n
  1. void SysTick_Handler(void)0 q- ~7 x" T+ y3 T! A! _+ i$ U
  2. {6 ~% a5 c( g( h$ l
  3.         /* enter interrupt */
    5 \5 \. F( _  E6 q
  4.         rt_interrupt_enter();
    " i) ]6 l4 y% [# Q, m

  5. & n7 k* S, O! G4 W3 p. [7 j  K
  6.         rt_tick_increase();
    1 u4 g' U3 P. x0 w( ~" a
  7.         HAL_IncTick();
    5 Z; R) ?/ H  W
  8.         
    % r0 g, M# O! `4 |: p' d& Q* q
  9.         /* leave interrupt */1 w8 T. a' v$ `1 T$ g+ T
  10.         rt_interrupt_leave();+ i  t) B3 M6 }+ A: h4 Z
  11. }
复制代码
. R# c- X) `2 X4 k; W
增加用户代码- L* r0 p9 X" R7 X! a4 L  t: R9 l
     
  1.          while (1)
    " D$ S  ?5 f6 s
  2.         {5 {+ S- o: j0 \9 L8 q' T3 C
  3.                  /* USER CODE END WHILE */6 z, a& l7 J2 ^
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);
    # C# l' m9 q2 {5 T/ S
  5.                 rt_thread_delay(500);  0 s) X# Q" h7 Q- M) ~7 [
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  
    ( B5 D. z% @" ~6 D! p
  7.                 rt_thread_delay(500);  
    9 q+ u  `, D. B# T' }' B% R& K, s( G
  8.                 /* USER CODE BEGIN 3 */
    2 V- l, Q0 R' V2 m( x8 o. Q
  9.         }
复制代码

- H! b8 O4 D$ c# r编译测试
. J4 ?: h2 I5 f2 N$ H: T1.使用ARM Compiler version5 进行编译,结果如下:
! Z' U' {' ]. f( I
; Q% {9 J5 j1 q. G/ s5 S
20190627003559464.png
# N8 x) |- V' l' j$ Z( q/ w$ `
1 d: l; j% b. b& U2 b- j
2. 使用ARM Compiler version6编译,结果如下:
" o4 u9 L6 ]' _9 ^" a4 c" S
+ M- ?. `: ^/ j% u/ `- @
20190627003658959.png
2 g  e4 m; @& y) z, `+ E
7 r( i, G4 V2 l
  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。6 C+ E* ^* Q: ]% r9 Y
( g+ o: V: }' e7 d0 M5 z
- d8 T1 l6 Z4 \
赞 收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答

所属标签

相似技术帖

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