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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍3 r9 t8 a* z$ S& t/ T( g
  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。' I/ u+ N- i0 T0 C  Y
( U! u1 a+ |/ \3 \  u  S) N# D
AI[KPXW81}UWZ~_C_U1JBZR.png
, e4 L5 g/ @4 C/ @* b# E
; E$ x. r7 }. C
安装rtthread_namo包2 U4 F: `4 |: `  Z- M
在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack
6 \! t% z" A! V0 x0 ~) r& n$ j
7 N4 Y- P* ^# s( I2 e# }; [1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装' w* T# a/ ^0 _

+ X2 ~* R, z: [% B0 p" |
20190626221653457.png

! K" v0 e; @. F* j8 O7 q9 C' a8 f- O2 _) d0 i. @
20190626222025313.png

* ]. t/ s5 ^" P/ i/ L' x  a# d' ^- _) q. S! g
2.在弹出的节目中选择Next,等待安装
# w8 l1 f7 H: l, J. m
$ h5 Y+ N9 q& y/ Y! ~. f: }
20190626222140363.png
, S% ~9 F4 D+ i

% J0 d$ {' g  x/ b& Y; X3.安装成功后,Reload Packs即可。0 x* \# r( f) ]7 P0 ]+ ~7 q9 I

. s0 Y% T9 z' j9 p2 D
20190626222321230.png
5 k  D2 y) j/ l) [) i4 o
! D7 L! ^( Y/ @7 e) e9 n" j
创建工程- X( u3 C# }1 V: T* v* Y* M+ p
1.选择芯片STM32F030F4P6) z1 ]& U  Q  H2 m3 Q

6 F0 B. Q  u4 M/ C1 v9 d
20190626222525565.png
! E/ B! ]1 c" D! r" D. c
0 E- g  V. O! W6 r
2.Manage Run-Time Environment
" E5 Q3 D1 q5 f. n
, P5 C) o. Q" q- O$ F
20190626232949409.png
" b* R4 @, \1 {, D4 D

& E0 _" a! ]5 h" O  y- G   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。, N1 N0 k  U: _+ S

) N$ D0 r/ d/ J+ E; i( z0 C8 }3.Start STM32CubeMX4 i4 N! g- g, N$ Y: r
5 ]% v7 n2 K; Y0 l
20190626223125381.png
3 V# X6 r+ b! l3 _
" F+ ^# D- q# \0 x5 a
   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。& g4 n- T  a9 i9 S2 }8 S' {
3 {+ G! H, J6 k7 Q! x
4.STM32CubeMX配置Pinout&Configuration
4 v& R. K3 O- S9 d" A0 v. I# Y0 F3 v* j  t/ e% E/ i# h* d
2019062622382861.png

, u% t; r* I: q
20190626224105362.png

% x, W1 K5 W  s9 {) l4 q
20190626224233634.png
/ s# f& L, R3 ~1 [
8 G0 c, h6 M& ]: H7 d) P
5.配置时钟
! a8 x0 a3 Q9 Q6 _! a& v9 \( F9 g
20190626224701758.png
0 O; X) v0 c  [' L8 j/ ^" c

6 O$ W% E5 r( D6.单击生成代码" E; c7 z5 W2 L8 Y" L: {
4 q& t: V: P1 N* u; e
20190626224854251.png

1 m& m5 b1 V+ p3 X9 X
$ \* C" {) y' d7.生成代码如下, `& i" f: Y( j* a5 k
# i; R8 r" i5 a% K( `
20190626225932442.png
. U( V0 H; g8 J
1 `) A5 V" h: L6 e( J6 r
配置工程. X, C1 i  |/ S* a4 ?" |3 J- q! E
1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置; r, i: d$ A* Y# [. G
% R6 U! c6 H# G5 o
20190627004726239.png
8 V* K; O$ B7 X  R+ k
. ^" ~  {4 a; D% U- R% L, T  e
2.内存管理设置
7 O0 D. n0 o' \: ~% E6 T; Z1 \
& O# }& }( ]! C. V# t
20190626232130606.png

! Q( N# p9 i4 S- f! F) e' m7 k+ u
. Y3 y. @- \. i1 e5 B8 L  L8 L   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。
$ z9 ]/ `) S9 T6 I+ j8 b
3 a9 H5 V; r6 ?$ o* F) S% b3.关闭console和Finsh
# W/ M$ h+ j! Y" _, g4 N& V  P4 I$ N8 F' Z- |7 z
20190626235930620.png
. n+ w% A, c+ w" z, m8 D
9 j9 ^0 Y: U9 P: B: S
   由于我们并没有接出串口,所以关闭串口相关的内容。* N3 @0 _) }6 P: V* A  Q

2 c. W6 `% q; y* C5 @9 m( B5 K4 D修改代码,测试4 }. R( X: D3 ~4 Q! G2 A0 H' L, |/ `
修改stm32f0xx_it.c文件1 V( T2 N# P9 }+ g$ K1 D6 c# L
   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。
4 p4 ]: u+ O& c3 I  ?
  1. /**
    & Q! |* R; m" N4 a1 j% A+ v
  2.   * @brief This function handles Hard fault interrupt.
    ; g% C+ j$ q0 H* F$ Q% h5 s
  3.   */
    - V# Y: O. h  X; t- o" Y
  4. __weak void HardFault_Handler(void)
    + g9 l/ n8 {' l7 q2 k) B
  5. {1 `9 `2 z% h2 Z6 i" j# j
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */
    . F- Y* n: \3 ?" w
  7. 8 B3 U; N% z1 A9 t0 g9 v0 n2 a+ t
  8.   /* USER CODE END HardFault_IRQn 0 */
    & H7 `! }) I0 \8 I3 m' n
  9.   while (1)
    : d( b) t( z0 b( n" [& Y
  10.   {2 W  P2 B- H* x4 {" A
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    9 I5 P, j- C# }0 l6 G( Z
  12.     /* USER CODE END W1_HardFault_IRQn 0 */
    " v% E1 X, N1 U7 f" j2 P
  13.   }
    * X9 z' n8 N: w! c$ Y- ^
  14. }
    & w0 W  W  g8 D% c" k" v

  15.   v+ r# s% @. j& B
  16. __weak void PendSV_Handler(void)
    ) H& M' m: k7 n. X  N5 U6 C
  17. {
    9 g6 O, {+ j& u- a  w  U* ~$ T
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */
      n6 Q7 I4 z9 k1 a, d

  19. ! D) V4 ~2 R/ L- j/ A1 p
  20.   /* USER CODE END PendSV_IRQn 0 */; V8 {( q0 [' T6 d8 u% \2 e
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    0 s- z. ^0 i) }. m  c5 g! L

  22. 3 `3 m5 W2 F% x2 g; j
  23.   /* USER CODE END PendSV_IRQn 1 */
    2 E+ b! ^5 ]& d4 b( R% u1 f
  24. }2 R/ ^( f5 T6 P+ S) d$ \% N
  25. 4 m3 j  d/ [" b; E! f2 V
  26. __weak void SysTick_Handler(void)8 c; g+ ?+ U! e$ e1 @. Z
  27. {
    ) W$ G' G1 s. i3 d3 h- k) {/ w" j' H
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */
    ) T. s. s/ ?9 S* C+ c" z

  29. ) h7 f! X" l' R" ?
  30.   /* USER CODE END SysTick_IRQn 0 */
    5 S' q7 \+ h6 f0 N/ o: F
  31.   HAL_IncTick();% X+ q1 p+ E6 Q% O8 Y  s$ c
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */+ U3 P) N; S; h  o! R

  33. 5 |3 T, M0 m+ N- k0 P
  34.   /* USER CODE END SysTick_IRQn 1 */
    , H* y/ d6 f4 c$ [  A
  35. }
复制代码

* Q# F" x: Z) `. v修改时钟部分
) l/ P+ ^7 h3 v6 i* K5 n   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。2 G; h/ V( m2 U8 u
   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。
7 i5 g6 d, }. @& a6 M9 i
  1. void rt_hw_board_init()1 a( i7 |- y( Z
  2. {        / {% Y7 t* Q) z) l9 Y5 N5 A1 `) l6 t
  3.         /* System Clock Update */
    5 `7 l1 ]( P5 c# `
  4.         //SystemCoreClockUpdate();+ X: b( O3 ?3 U  R8 W, r
  5.         HAL_Init();
    ! Z+ G( t' A/ b8 T
  6.         SystemClock_Config();. O( C; A: j" b1 }
  7.         . x, v$ N! |2 T1 _& P$ c
  8.         /* System Tick Configuration */
    ! g/ I( j! m6 B
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);. z9 h, M3 Q2 [  i. y; K

  10. ) Y; D1 b2 [' c; _& K8 x0 T" M# w
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */7 I+ g: Y6 I* s
  12. #ifdef RT_USING_COMPONENTS_INIT7 y5 J! ^; W. {7 v8 z  F' z
  13.     rt_components_board_init();1 D5 e+ F  Y3 z/ @7 e
  14. #endif% ~/ A2 N* m/ u, H5 \. b' n

  15. : Z( \7 s, j9 X* s7 [' ^
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
      z- ^+ m7 u; T8 }  k
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);1 h  y3 R2 k1 F9 F. t- N1 A
  18. #endif: T% H% y: J( y0 e& z2 H
  19. 5 O; B8 Z5 G& R
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    " U! \2 X8 T& R7 A7 K: d
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
    : H5 E9 V* U2 d" K* z# F' [" U
  22. #endif
    . `0 ?4 |' G8 T  l. _* H
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。
  a& V% a4 ]3 O# W' h0 G
  1. void SysTick_Handler(void)
      J* N$ S1 p" W8 r5 Q
  2. {% T4 h, ]6 I9 G
  3.         /* enter interrupt */6 p& L) b: [0 w" C/ R9 g7 R
  4.         rt_interrupt_enter();
    . }+ v9 E4 g! Q7 n; |( h6 U

  5. 1 {0 B, g6 U  Y
  6.         rt_tick_increase();; R" T8 \9 f) q/ b9 j: J6 k* i$ J
  7.         HAL_IncTick();
    1 m- J. S* C" H' y2 R
  8.         ( s. i' h; f8 Q. P7 `9 v# |
  9.         /* leave interrupt */
      x$ {5 a8 N2 P9 C6 u
  10.         rt_interrupt_leave();
    6 ]- R: w& q% l1 z" y( S
  11. }
复制代码
1 [" F: Z" Q" c
增加用户代码
. I1 W1 q- ^1 _# j% m     
  1.          while (1)
    : e7 y- {( e5 J# J" g( E
  2.         {
    ; s3 G8 P. L0 k1 A2 l# M
  3.                  /* USER CODE END WHILE */
    7 {3 S; I- z, R) T4 x4 n
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);
    " a' r$ o" S5 @
  5.                 rt_thread_delay(500);  
    4 l' Q. S& |1 i/ }9 ~
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  2 G- ?. M9 u. s" q$ Y. e" `
  7.                 rt_thread_delay(500);  ; D' A" k5 G5 x' Z4 N6 ?
  8.                 /* USER CODE BEGIN 3 */
    + O1 N+ ]! ?* Q# N
  9.         }
复制代码

# ]) q7 \$ P% I, M; v* h0 i编译测试3 P* {& ^4 Y% q- c
1.使用ARM Compiler version5 进行编译,结果如下:
8 E9 E' Z% A3 @0 I6 D0 n4 ]  R- X) U2 E, B* ?
20190627003559464.png

% C3 i* `. F  C* p
1 O2 z( |, H  m2. 使用ARM Compiler version6编译,结果如下:8 M+ U+ c2 g5 e: A

5 U9 X# t) J+ M; f$ C
20190627003658959.png
" s1 q4 B1 {) i# A

1 u4 r3 u# j* g5 z/ q$ Y. C0 h  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。
( `/ K) [* T" v/ ]+ I: f0 J# [9 O% b+ e4 r

: t0 S' i1 y8 ^% G. z! {
收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版