请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍% G9 j; P. v7 L' P' B
  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。
+ h* r( C7 S9 H3 B2 ]: @: a! j# v4 D* }2 c. u5 |# l4 \
AI[KPXW81}UWZ~_C_U1JBZR.png
: r3 J7 B( b) X6 K

! o  T0 X% V/ D1 D; r) J: B4 h安装rtthread_namo包& c1 K6 w7 p6 @* @' \- k0 ^; N6 A/ A
在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack
5 K4 J! I5 I! c8 V$ B; ~: x, D/ w$ \* T3 q7 c/ s+ G
1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装
: I3 H! _4 F5 {
; c- O5 ]  d, G  V- P
20190626221653457.png
. P8 K9 U, N1 X$ D7 N/ N  @

* u9 r! y6 U& A9 e" ~' x3 b
20190626222025313.png
: a; P  p2 S( p4 Q, t% K

# u1 \4 k5 f: f7 G1 @6 b2.在弹出的节目中选择Next,等待安装: k! }& X2 L, W% U5 r) D! ^% U

9 l' n( b/ Z/ \' v
20190626222140363.png

6 n0 j* `/ Q9 [  z) ?- D) ^! ~+ c+ S3 U9 S# ~8 l
3.安装成功后,Reload Packs即可。
( p. h) h4 n7 G% w- f; s6 `4 p! V' c* L
20190626222321230.png
, H+ ]2 V9 \0 z; W- R2 J8 Y
0 \! P" }, P& x" x/ [5 b9 e
创建工程
# m1 N" z! ~) w9 N1 A8 H1.选择芯片STM32F030F4P6
) j8 q" Y( J+ X2 \# E9 h
; t4 y( }4 V1 e
20190626222525565.png

7 K. i8 a7 S/ i  J9 Y
) D7 @+ n: F) I4 y' r6 I* Z2.Manage Run-Time Environment6 j+ ?0 ]/ v2 d, g4 y/ y. L% r
( g9 s8 ~( W# z8 a
20190626232949409.png

' d; l9 R" I' Q. |$ I: X$ \2 {+ S/ s$ l9 ~
   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。5 {7 {- ~& s7 f3 Q* q$ x( ?( A
3 W. H$ \$ U; n8 P6 Z, I6 f
3.Start STM32CubeMX9 t1 s6 c3 v) b9 Y- o
& Q  ~4 S' N$ b
20190626223125381.png

( ?  x! [: R$ \$ P( F: e; h, X, f
/ a, ^+ q( S$ p( @5 s8 G$ F; `3 m   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。- j3 N- O+ x" m( K3 h1 M
" s% k7 ~; a1 l9 @5 q, w3 W) w$ g6 b* G
4.STM32CubeMX配置Pinout&Configuration
/ n' j5 j% u; z& `# M: \
! W2 ~7 ]! J6 F2 m
2019062622382861.png

8 T, g- m; y+ j3 o$ ]" z# r0 p& F
20190626224105362.png
, I$ A) w# Z; I: ?
20190626224233634.png
* E2 L6 m; `3 I8 a6 ?0 {
' F, e# O, y: J7 M# q: M8 _
5.配置时钟
2 j( |8 |4 a4 M+ L% w9 k1 z% V2 g# `8 E5 y5 V+ m' ]
20190626224701758.png
  t( f( B7 T& }# B
* x8 A4 R9 K2 A# I
6.单击生成代码
3 h; a& a/ K3 y4 h& ~- J5 F
  ]# y8 \4 |) G# J* w) g
20190626224854251.png

6 B9 n+ E5 O3 ~) E% H: D0 r* l
' {% g  i2 D# M4 ?5 N7.生成代码如下0 y* v! K+ s9 l+ d* P9 z

$ n4 Z. B& G& J
20190626225932442.png

0 @( F, l8 e4 Q: l8 G2 G1 @- s! l8 ]! _4 t: b5 J4 e, I
配置工程6 _! |9 @2 Y/ K  z" c- C+ K% @
1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置
, Y5 p( l; A) q5 m2 s
* F6 l$ e7 r2 d0 t, k) Y
20190627004726239.png
6 c' z2 i' {5 h" _1 ]
; V! y" X7 z. T4 s; y. M. ~; h" g
2.内存管理设置
3 f0 p2 g2 k9 o7 g$ U: R! b, E1 B" K
20190626232130606.png

+ C+ L" o& |) a2 ?/ J0 N4 x4 O& Y- e9 ^/ }
   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。
) u" R% J4 X. J8 S/ |9 O4 K6 b: w- f5 ]1 k# r6 V- J! D; M
3.关闭console和Finsh8 I5 B! K3 X/ T

8 N4 u, P: k4 J( _4 D* G7 K
20190626235930620.png
( K$ C3 c8 Q5 ?1 j. R6 ]# C: J  t  R- p# D
- l# t: l8 B% O; h! B9 [
   由于我们并没有接出串口,所以关闭串口相关的内容。
8 i% p+ H4 d$ H  |
, ^0 j8 R1 e+ \修改代码,测试
* S! B; a1 t: S修改stm32f0xx_it.c文件
- j9 |* J) T' P9 c! y8 @$ w: V   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。
1 R* V. v0 T) h4 v
  1. /**
    ( O. G$ X( i* \* V: ^, ?3 z
  2.   * @brief This function handles Hard fault interrupt.+ u: s$ E; p+ b7 W+ H# b& \
  3.   */+ C. w5 T3 c9 n8 `. R' B  t5 m& T
  4. __weak void HardFault_Handler(void)& R' ~$ t. ]- w5 T
  5. {6 @/ [* ~6 O% t
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */
    7 ~, Q$ o# e" T& o
  7. 3 |1 n9 v% y- g. V% q
  8.   /* USER CODE END HardFault_IRQn 0 */
    ' M: K6 x( }5 o8 w
  9.   while (1)% m3 m- q% j' Q3 u. E
  10.   {1 L$ @6 k0 E# ]: O6 [
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    0 E% B; F: Y0 C5 j
  12.     /* USER CODE END W1_HardFault_IRQn 0 */
      f5 b' ]* J. _" W5 G: Y
  13.   }( ?/ n8 W5 l+ B& B  {/ B' h
  14. }
    ) N7 ^/ k+ g0 n) x. O! a+ f4 O

  15. + o; m; H2 X9 }5 V: C* y- E
  16. __weak void PendSV_Handler(void)
    + z2 q& Q( H$ R4 G. G
  17. {; r/ q+ `% ~4 A. q
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */
    6 G2 E9 f5 q+ \( G/ n

  19. , D4 M! @8 z& s2 C9 i% Q; D) o
  20.   /* USER CODE END PendSV_IRQn 0 */
    - m0 q* }. F5 d' y/ c8 L0 n
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    8 r& L4 I  C% M9 `% n2 a
  22. ' q( ^! V' p8 p( {
  23.   /* USER CODE END PendSV_IRQn 1 */, g/ U: c' u% n) Z. O+ C
  24. }
    * R( w3 D/ c- }3 {4 o

  25. - ~/ \; @4 b  h& n& c
  26. __weak void SysTick_Handler(void)
    & q9 J8 i0 \; k5 K
  27. {- X; H; M3 i- X) K, K
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */1 b' Z, g/ J' ?8 ?, ^) f( G. p* B4 H
  29. 5 _2 c# o5 e2 x  l+ k! k5 I  m
  30.   /* USER CODE END SysTick_IRQn 0 */
    6 m1 ?9 U1 o" M, i3 V3 q/ h( z
  31.   HAL_IncTick();7 Z8 ~* v! j( E0 B. w
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */
    : W1 v" ^# F3 ^9 Q

  33. / R7 j4 G. O# I. M/ z: C; ?
  34.   /* USER CODE END SysTick_IRQn 1 */6 \+ ~7 y7 f) B( A( {
  35. }
复制代码

' m& u% @# P+ ?& A修改时钟部分& z# b/ r1 \4 T$ R  i1 p
   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。
7 [! [5 T6 I' z% q* @3 Q   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。7 b  `5 Y/ @0 x9 Q
  1. void rt_hw_board_init()7 F# T( h% x  G8 A( ]8 e
  2. {        5 m$ J/ a- o# P, j
  3.         /* System Clock Update */. ^7 B! |9 T+ N: J# B' i9 a( ~) ~/ P
  4.         //SystemCoreClockUpdate();; j, J/ t2 }7 t2 W0 t
  5.         HAL_Init();; ~+ J7 j/ {+ `2 `8 l# p0 G# H" Z
  6.         SystemClock_Config();+ U9 ], H2 m9 h; H9 k7 l+ S
  7.         
    % H- G3 z5 j0 @" I
  8.         /* System Tick Configuration */
    / g( o2 p3 T* P, C, V/ t% W3 X
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    $ L: A1 u! `- e7 n
  10. 8 n9 L9 \" s: c7 j, c) [
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */
    6 K& b: c4 P  Y5 q' n
  12. #ifdef RT_USING_COMPONENTS_INIT
    + B) L$ K+ H- i9 s$ D
  13.     rt_components_board_init();
    ! U7 e! F  }8 V# T, z( l
  14. #endif
    ; b8 S( k( C# ^$ K
  15. : q3 h* D5 N3 \* t
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)/ v: y4 y) ^1 {4 V/ g/ A( U2 _0 z
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
    5 T1 Z# B1 v1 K6 H
  18. #endif
    : E. C  I9 q0 Y& J; B- ~; q6 }  N

  19. . ^& N+ W' K' W/ x$ g. _
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)& n; I5 J$ v- Z, f
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
    : @7 ?* @/ q4 B! S7 `2 c
  22. #endif& `0 \  r# `1 W" q+ w( G2 C; {
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。5 {# x. A9 B: g3 t! h
  1. void SysTick_Handler(void)
    5 N. m% e5 o% v, T8 _
  2. {
    ' k8 I3 r1 W1 S9 B1 b7 j
  3.         /* enter interrupt */
    , W3 p. m9 b2 ]2 O# c7 {9 l
  4.         rt_interrupt_enter();
    - B& ^* e/ i; }) q) l

  5. / f! Y, |7 I7 B, F/ u
  6.         rt_tick_increase();
    - K5 A! ?2 q$ ?  N0 X: h
  7.         HAL_IncTick();
    1 q/ |6 ^/ c9 _
  8.         / x6 A: D4 I0 B2 C
  9.         /* leave interrupt */% G. Q; U" h# |9 c4 T( W# v
  10.         rt_interrupt_leave();
    ' w  E6 j/ d1 d1 U+ a0 l
  11. }
复制代码

3 ]) z# q* W  I增加用户代码
3 {3 ?% O  Y$ z2 \     
  1.          while (1)
    ) t+ ~" @' l/ ?- `4 S# b) W
  2.         {
    + Q+ P. `: C. r6 C
  3.                  /* USER CODE END WHILE */4 n8 Q; F9 U  Q& m# B
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);
      _" v4 ?2 ]% D1 k" r- x5 ]
  5.                 rt_thread_delay(500);  
    ! |6 `/ P1 O3 v1 m' q
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  
    5 v8 H! U3 `1 K( A
  7.                 rt_thread_delay(500);  ) ~. q+ n& S# y8 q
  8.                 /* USER CODE BEGIN 3 */$ X% ^/ _! n$ ^' K" p4 v  g
  9.         }
复制代码

4 e2 f( o: l% j, W; U- D& ]: R6 A编译测试
8 _* t( [5 y: `' X1 t+ Q7 z& D) [1.使用ARM Compiler version5 进行编译,结果如下:
& l1 }& \5 a( [+ g2 s
! _' A: s& h& I4 I! k
20190627003559464.png
  k6 ~; R, `% N6 }- W7 F) _

9 w# c' L5 |% ], x; `2. 使用ARM Compiler version6编译,结果如下:) P* J, b4 ~# ?. P6 y+ _( E+ t' d+ U
3 ^) L( {$ E$ B4 W7 D
20190627003658959.png
1 f8 C/ |0 y3 l

9 V8 s* g0 X0 `! `6 K9 }  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。
: Z' ?* c: E# ~. H& r7 V7 s/ G
# ^. m, k1 B& I& i% d" x1 Z6 T# c1 I' O* q; `  E9 b4 @; D$ [
收藏 评论0 发布时间:2021-11-25 16:00

举报

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