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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍
3 B2 ~7 t9 @) o% \" E  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。
$ y8 b! w, E9 _" S0 ?: T& w' j
% D- c  U" u6 r! |, H: |
AI[KPXW81}UWZ~_C_U1JBZR.png
+ a7 K7 u0 @/ y
+ Y" y. Z8 S* V0 V0 |2 b$ B3 ~
安装rtthread_namo包
( |. v8 f) l; r$ ?! n在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack, A# v( d5 I9 a3 Q; m

# S9 o) E+ q: G) `! k) u' d( {1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装# e( k* i- @8 @' w8 q- I" g' |5 G
6 c$ K& ?; q2 C8 \- v6 S9 r% i
20190626221653457.png

$ v# F( Q4 f0 s5 M5 [! B9 t' P8 C. u% u! d) h) ~
20190626222025313.png
2 a2 L6 }( i: T, q5 n0 M

8 P( P. X7 p* d2.在弹出的节目中选择Next,等待安装
% e) W, V7 U( H% A+ r& C, [% ?  T- G; v" b
20190626222140363.png

8 V9 V$ X5 I9 s6 ?8 r1 G& F0 D7 B: e; w, P
3.安装成功后,Reload Packs即可。
2 `. [5 O  i7 L7 ?2 T: \8 o7 q' v2 e) b% p& M  C
20190626222321230.png

7 x* ?" f& w5 b
0 }4 G$ Q* Y# |7 Y6 L9 E创建工程
9 j( G/ p8 [- ~0 d1.选择芯片STM32F030F4P6" b& O* w( y& P( g
  d, P" T! B% }3 V7 ]
20190626222525565.png
9 |7 |- d6 K# [6 q- B5 F

; v5 a4 t  o3 v3 C% D. k2.Manage Run-Time Environment
" t+ D. }+ {) E+ h2 W: m/ N+ u$ v: s
20190626232949409.png
$ ?7 G6 r; k9 o$ b- Q. R# l2 G

0 @6 }" s- |$ k' f7 M6 g   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。
6 n( n* c- p" {$ o3 s! h& \
( k6 C% D- H8 y1 b3.Start STM32CubeMX
1 i5 z% g1 {$ z. O) e& t3 d0 E, g+ B; R- Z7 F) |7 R5 N# m
20190626223125381.png
% r$ O7 t  v( k9 E+ m

" }3 c% h) D6 b$ x5 D" F" V2 R   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。6 n( B- O2 z0 g% y6 I

$ J# a( f' ]! w/ ~4.STM32CubeMX配置Pinout&Configuration
: S+ `% l& E! o: a  ^" S  X0 m# ]
& u$ h4 t( V; J3 g
2019062622382861.png

6 v+ L7 s0 P1 |- e# D' B
20190626224105362.png
, j, h+ h8 ?9 w. j* y) m
20190626224233634.png

- [. X: T7 o9 s
0 |. Q. F+ u+ M9 p& c5.配置时钟
9 E+ [4 y, E" {# h+ A- C6 f% G, M
9 A1 s( q7 i1 u  V  G1 o, {, f2 d
20190626224701758.png

/ U1 X' U; [8 D7 G) e* [7 Y  ^6 O9 ]: v' C: |% R
6.单击生成代码
3 P, r$ T- \, y" \+ D6 r4 Z" b6 r$ b- ~9 S/ b5 z$ K* _! s6 ^
20190626224854251.png

4 k! |) q; L9 Y3 Y' C" |7 |. w! |. ~# `% m0 D9 B9 y) N9 q
7.生成代码如下! q8 k- A) y" u) v: @

/ M1 \0 M; S" s& e2 W
20190626225932442.png

! W/ W  `% ], F" T3 }2 S3 P+ V* R- \! b1 {* @. C- v0 \6 o! I. W
配置工程
) p6 j, @5 W, L: c1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置/ i+ t' b4 J) v, R0 _
( G2 x) u. u( s0 N) ]
20190627004726239.png

6 N$ t+ d, E' q* A+ X
0 ?: U  c2 H; |- @" n2.内存管理设置8 Y- S) x6 x' r6 m$ X( c

( |! D3 P) ^" u
20190626232130606.png

- U& y* D* V8 I6 y
1 _: d5 ~6 W& q1 u* _5 J7 `5 Q   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。
. Z9 q$ m5 `. [/ M. _" e. A4 j- \9 W$ Q5 z* n+ s
3.关闭console和Finsh
9 R8 i2 _6 e% R; v( O" x% e3 }+ Q9 _$ `3 l/ ?4 a  S
20190626235930620.png
  x4 B0 v6 U" h5 I7 b/ k+ E  C

8 d$ S0 p3 ~1 m' Z   由于我们并没有接出串口,所以关闭串口相关的内容。
  k% l! s' X* z( ^+ B. s9 F; T8 d5 I1 ~9 `
修改代码,测试
* B+ u' |+ u/ ?修改stm32f0xx_it.c文件. A4 p6 V+ ~7 n$ U
   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。
* f- t( t$ j5 [0 g' k+ ?+ L) ?0 C
  1. /**
    . W* W* Z: q2 j9 g& i1 H+ O  g
  2.   * @brief This function handles Hard fault interrupt.. p* J! e1 D( I0 }5 w# o4 _
  3.   */; X/ `: V3 A+ V; M0 H. s! k
  4. __weak void HardFault_Handler(void)3 I3 d6 u( b0 u& e4 k
  5. {
    : `  D, g  C9 G- d
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */
    , N; \) i- K8 P& k% N: z

  7. * `0 s1 C4 d- X: p" _# G
  8.   /* USER CODE END HardFault_IRQn 0 */
    6 {- a0 H, Y1 L6 }' I1 E1 ?
  9.   while (1)
    8 |& b: B- Y7 i7 B; F, k
  10.   {
    $ K5 W4 T" e8 f6 S# ?
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    4 X# r  [: y, l: D4 M* V: ]  i0 q
  12.     /* USER CODE END W1_HardFault_IRQn 0 */3 Q: J- p3 o, A+ k4 w
  13.   }
    + F0 w: \) h2 h* w& @- N, A5 {& \; \
  14. }5 M; E# @( \8 `" R& D2 T
  15. 1 l6 H8 M9 d/ p
  16. __weak void PendSV_Handler(void)
    * E! O6 }7 ?. e) Q4 s
  17. {
    - v9 m- Z. u/ q
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */. N% g7 S) q. c3 X

  19. 7 G& E2 S7 _# K
  20.   /* USER CODE END PendSV_IRQn 0 */8 E( \2 `4 C6 @
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */  N2 L7 ]/ G0 U% R
  22. 5 I9 }& w/ e  u9 g5 x. ?' \# T6 D
  23.   /* USER CODE END PendSV_IRQn 1 */% w1 j0 V/ \* M7 A* ]% N8 W5 j
  24. }
    9 V3 {- h+ D0 `: p6 u6 j4 ^# y& m

  25. 3 V9 w. b9 P, ]' G$ q: }% H
  26. __weak void SysTick_Handler(void)
    : ?% S5 J: @. p7 G
  27. {& M5 ]4 s) _. h: {
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */
    ( ~& [- r0 W2 ]6 R  m- e* A

  29. , Y, ?2 _" I( M; W/ \  y0 W
  30.   /* USER CODE END SysTick_IRQn 0 */( S1 J8 u+ p5 i; M
  31.   HAL_IncTick();
    ! D# ~3 W; K" @2 _7 R  b  A
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */
    4 P; }5 O' k% {$ C/ `

  33. ' ?& ?: t, w" P9 |1 J
  34.   /* USER CODE END SysTick_IRQn 1 */
    5 R) T& x2 x1 j2 B1 D5 l3 ^
  35. }
复制代码

' H. T8 r% z3 U/ q" S5 T修改时钟部分& e8 y: a7 g1 g4 }4 P. X. i$ K
   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。: @* w! s1 O9 _8 D8 p: O/ M, |+ G
   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。
9 @, I! M) N: s9 ?+ q
  1. void rt_hw_board_init()4 S3 u( p3 v  ]) \8 y
  2. {        
    3 p* M/ w; A: {9 C4 r
  3.         /* System Clock Update */
      K) U; u+ g& L2 \- Z
  4.         //SystemCoreClockUpdate();
    & C4 z9 g3 n+ s0 m; [! u4 F
  5.         HAL_Init();" Y2 ?/ c! H- P, Y* K/ p% K
  6.         SystemClock_Config();
    : Y1 P2 E4 o9 w' F% Q. |
  7.         
    % x: T/ e8 y1 E
  8.         /* System Tick Configuration */3 Z! t2 _8 y  S$ p% H5 k$ K! {, s
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);5 f- {8 a; R' _" _9 V3 r
  10. / D/ a: G, I& M+ z* T
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */  A: X+ l4 ?$ V1 t# G8 A+ R2 N: C5 o
  12. #ifdef RT_USING_COMPONENTS_INIT
    + o) Z% p; S9 J, ?1 ^6 ?
  13.     rt_components_board_init();
    0 f* H5 c. l: \* x3 B' |
  14. #endif
    3 Q# ]  ~7 D( P% T3 q6 z& ~4 }% \
  15. , m' L' T' s/ _+ j  y0 ]
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
    ' v* m+ O4 a" U! o/ V& l5 n  N$ Y8 N  d
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
    $ t. g) \8 s0 e- F3 P* r; j
  18. #endif
    8 A9 S7 H, w& Z4 U0 b* ^! n# [
  19. ( I9 j! y/ h5 s: H* E( R5 x$ o
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)* |+ u5 f! F( d
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
    $ z4 E1 |& q8 x
  22. #endif
    . {. Y& W' r- Y; u( A2 U
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。0 s; |9 X3 d/ f4 S2 s" G: q
  1. void SysTick_Handler(void)
    5 @& e: V( k/ |8 C+ i0 o% C
  2. {
    7 Q8 F8 M% j0 @4 P" K
  3.         /* enter interrupt */0 \( ]7 ^' o' z
  4.         rt_interrupt_enter();" {( o9 Y5 @- |4 K7 l
  5.   G8 Q/ [4 a% I$ m6 V
  6.         rt_tick_increase();
      {" ?+ l; H' c2 j3 Z4 f8 M2 A
  7.         HAL_IncTick();, o# k' |- `7 F
  8.         ; R* ^. f# X/ t
  9.         /* leave interrupt */
    ; Z" B4 @$ G5 A7 B1 n- a
  10.         rt_interrupt_leave();% _3 \% [; M9 \' r- K
  11. }
复制代码
9 E. m' q* {$ q+ J( z5 k
增加用户代码
  E- m# a9 n. ~9 G' X     
  1.          while (1)' ?7 S: U" ?) T9 G) n# e
  2.         {$ a& g5 u" |, ^2 `+ U# K; ?5 z
  3.                  /* USER CODE END WHILE */
    7 H$ r2 m, X& U( ^6 ?+ v) ~
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);
    7 P$ z; X7 w7 I3 i- @5 f* M
  5.                 rt_thread_delay(500);  ) q1 l6 s3 T7 x5 A, F2 B
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  ! j- v1 ~, }" U  O3 t+ J1 Y
  7.                 rt_thread_delay(500);  
    # |, U, H, F% C/ B0 I. z
  8.                 /* USER CODE BEGIN 3 */
    5 e+ i1 w( {8 Z
  9.         }
复制代码

# b! f0 n/ z6 b6 a编译测试
4 B9 V/ u- G% H% v1.使用ARM Compiler version5 进行编译,结果如下:: J+ r; n, O. V* I. Y* n$ g- T

' y" ?2 v9 @8 r8 s
20190627003559464.png
& \9 E! {3 D* d3 E3 R8 |8 F
' }0 q' C% q; c2 g$ w) k7 v' S
2. 使用ARM Compiler version6编译,结果如下:
( g+ L  \' L* ^( S3 a- n
& |! [, Z0 o; o7 k
20190627003658959.png

0 x! v4 @, M7 \  K
( J, I% y. q1 P0 {: F! v+ [0 c  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。
1 {: D( y# Y: F, M5 w6 Q
# |  L$ b- i' m7 m
. G. K  e; f/ ]4 R* v. V
收藏 评论0 发布时间:2021-11-25 16:00

举报

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