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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍
: F( I2 S5 |! @: v/ ~: u2 f  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。9 q$ @/ _3 J& p0 {" R1 h( x
' y0 C+ `* F- E# K/ [( V# ~
AI[KPXW81}UWZ~_C_U1JBZR.png

% n2 g; U/ p0 {' B6 W0 r4 f3 _1 n& ?) m2 i; Z( z
安装rtthread_namo包
. w9 R1 ]# h$ A/ ~$ P+ M/ {在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack
( J7 {5 N- `' W7 k  W, e% J
9 x7 U2 I- |' w& J. q1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装; N& i1 j* B3 j' X/ G7 T- D# @
9 s' U' Q( j6 s5 i6 ?
20190626221653457.png
3 D+ @  K  J# S
5 q  x8 W0 G0 I# L
20190626222025313.png
- l. }# a& {: N) m
! [1 u$ J* ]7 R% M, Y7 n
2.在弹出的节目中选择Next,等待安装
9 L6 z& F1 D: I# }0 {7 [  y3 [$ v% s: B$ n5 G
20190626222140363.png
3 ~7 [# m% t% B" k! z, C7 r2 c
. D6 X& F4 k! N. o9 a7 C
3.安装成功后,Reload Packs即可。+ ]; \! B3 Z0 |  O' U1 ^, a5 b* @
( k' N- t. j3 _; H9 j4 G) _# }
20190626222321230.png
5 _2 b# \& L' Z2 D; g

- D1 u% ~1 c- S' Y# z$ q创建工程
6 s. U: u4 s* {4 ?1.选择芯片STM32F030F4P62 g8 N2 T6 c+ P4 ^
0 J+ J  F2 l3 l
20190626222525565.png
* d' B2 r: ]+ E% s

7 o; A) e5 s5 ~" x& l. Y7 z2.Manage Run-Time Environment
+ g6 ^0 \) G. f' \6 ~
& c5 v, ^& C- S8 C0 ?7 h, R- C
20190626232949409.png
# o1 `* H% f3 h5 p' Z

+ |. L' y' Y% j" p0 d' O4 g   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。
& G2 n  z8 f( k( Y& x* d* [) ]0 {* {& \
3.Start STM32CubeMX- j1 d7 D$ D4 m

$ n  m/ W: K7 O" g* P8 g
20190626223125381.png
! c/ L4 v# v: q
. i6 C0 h3 `7 S( S3 ^6 U  h3 L
   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。
& @- [' q( I# L! Q, a
) W6 }& w  L; B3 p& G% H: _0 d4.STM32CubeMX配置Pinout&Configuration
3 |: s7 i- z3 V' B
" I) ?2 @6 c/ d8 [7 ~9 P6 Q
2019062622382861.png
* G& b  R; i: \/ k
20190626224105362.png

6 M' m! `& a) y0 j0 Y( y# A0 |
20190626224233634.png

, k# W; z& I" I3 I% \" h9 S1 r, Y( h' P) x* `( J) A) B8 m7 [
5.配置时钟
. j4 `; q5 a$ Y9 y! K
- ^4 W% m/ X& R' L! q
20190626224701758.png

; @$ r# _( K. B( e6 ]) |* h! T5 i: s" B5 h# f
6.单击生成代码
! i# Z( e/ N/ A3 B' }: J
+ F. q1 J2 x$ e/ b) }) b: y" k7 c1 H4 |
20190626224854251.png

8 _! {) V9 i; [2 B8 e  |. U3 C
: E1 j) t; v/ o$ E" N7.生成代码如下! ?3 @% y8 x; X/ U+ c; n

, [! [6 q! `# D9 T
20190626225932442.png
2 i* ^0 y' q, W0 {. f( @2 ^# e' W
+ c" O$ g; `4 A
配置工程
9 K+ f+ t/ W  t6 b: C" M8 J1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置; Y2 [- `# I$ `' n, |
  u4 y) e2 Z, A5 f7 }! X7 E
20190627004726239.png

2 w! w4 }  G% i+ o* t. K3 e' H% e4 [, X2 p. |
2.内存管理设置, f" w& N. C8 Z& u" A

% Z0 S: [; V+ @; `& y1 Y4 d* V( Q" Y
20190626232130606.png
4 J2 S" y- Y3 m2 I, ~8 D" Z

! h- z+ L+ @6 N# I   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。# R% K. l- i4 J+ |3 W
0 m. g& e) U+ j" G# K4 `. e7 v
3.关闭console和Finsh
- p/ ?) p; O+ g5 _8 Q! r* f: @
( [7 v$ i  S2 }# m9 a5 Z% E* `
20190626235930620.png

5 B1 M4 E' a. c% _7 j4 ?6 Y: g; G1 P$ g/ g4 f3 ?  y
   由于我们并没有接出串口,所以关闭串口相关的内容。# I5 ^# ~4 P5 k* E- ?& O

1 n  l0 k! r9 M5 X6 i修改代码,测试8 @3 \/ h' {0 k4 x7 V
修改stm32f0xx_it.c文件4 ]4 P- p% A+ `7 z# B$ y! f; a2 v
   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。
) t6 }  r1 w% e6 \/ P- s
  1. /**& |! H; B, @, z2 r3 s+ L- h
  2.   * @brief This function handles Hard fault interrupt.
    - o3 Q: ^7 ?4 F7 X+ q2 E% C$ @) I
  3.   */
    2 g$ o, ?# S& \( J) v( O
  4. __weak void HardFault_Handler(void)/ e, [+ k# y' r6 I4 f$ {
  5. {
    / c8 S  T4 e+ @, |: @" L% [! u
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */& l* `6 z9 q. l% N
  7. 1 e& K3 H8 C! p
  8.   /* USER CODE END HardFault_IRQn 0 */
    2 Z. L, P( v0 g, H
  9.   while (1)7 E$ `! Y/ \; O) O$ L( R
  10.   {
    % ]' v! a- O. x* h$ \4 R
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */$ A5 G; D, T! N
  12.     /* USER CODE END W1_HardFault_IRQn 0 */
    , C( ]% G2 b: c+ |8 k
  13.   }+ m8 L* E% d" ?* c- Q2 N( a
  14. }
    . `3 }- P+ W- @8 _

  15. * E! [) H( d1 r9 J- b( S5 |
  16. __weak void PendSV_Handler(void)
    * D: {: c( @8 x% T2 W( L1 U
  17. {/ d* z$ G2 @  j5 e8 O
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */
    % {5 l1 }" k' M, A0 x. n

  19. 7 U  \2 l3 V, `2 H1 j' [
  20.   /* USER CODE END PendSV_IRQn 0 */
    $ v1 x3 o5 b) G4 V  `0 S
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    0 |6 p- b! z2 R% a2 n. w$ `. C' m6 s

  22. " t$ p- b6 r" B! X3 ~
  23.   /* USER CODE END PendSV_IRQn 1 */4 S4 [; b" G+ F5 A# r  Z
  24. }  X( E: O/ _/ u: N6 s$ P; k, y, k
  25. & C2 F: G3 l, d( e3 r, ~2 W
  26. __weak void SysTick_Handler(void)' F0 @9 h9 Y1 w
  27. {3 j: q* e. O, Y+ c
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */0 h# p" w+ }( m2 }

  29. " b' s0 ?( |! {6 P8 i
  30.   /* USER CODE END SysTick_IRQn 0 */
    0 w2 Y) w; V8 E
  31.   HAL_IncTick();
    $ S3 I1 |8 D: b; m
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */
    ) X2 a6 P, A1 j% ^' y0 O6 a; r

  33. ( U( Z+ `3 T" s4 a7 R6 `( }+ z
  34.   /* USER CODE END SysTick_IRQn 1 */8 Q+ h) u& Q& [: U/ [  d
  35. }
复制代码

  J/ G  [" D7 w/ M* @$ w修改时钟部分
, L+ u3 u2 ]9 w( d   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。
* f0 w- I: g$ h8 L   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。
0 e" n% x0 F2 y; \6 w- F1 e+ \4 |
  1. void rt_hw_board_init()
    8 `. |2 z6 N8 K" |1 t
  2. {        
    5 f  T/ O3 M# N1 W: |
  3.         /* System Clock Update */9 U" n  M; A: G% y  k! w8 L' L
  4.         //SystemCoreClockUpdate();* h* Y0 u, m; j* |% c1 Q: y
  5.         HAL_Init();
    . ]4 _5 A* Y: @6 r9 T. n. m: n
  6.         SystemClock_Config();# q6 Y" t4 L9 l
  7.         , R$ e' h5 |, V
  8.         /* System Tick Configuration */: A! n. j: n% M5 C2 W& R
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    . a. n! W, F- ^

  10. : h4 Z5 r) M) Z% X6 m! R: K
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */" e5 a+ O1 }5 m7 ?$ g( m7 n' ^
  12. #ifdef RT_USING_COMPONENTS_INIT% P, D$ b7 c' C' A  c3 r8 K5 X
  13.     rt_components_board_init();% z7 P$ D! m2 a" z6 x9 }1 b( z
  14. #endif5 Z& [  L$ T4 H3 z1 e
  15. & a' R& C4 X; n, S2 z. z1 N7 G8 @
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
    # K8 _0 s7 n0 K! C/ i
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);* h* ?: W; }( h3 ]2 K2 P  B
  18. #endif# z+ g, l+ f! \

  19. $ B# }% J, k/ G( ]' }' C1 f3 I
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    6 p' p3 i% s* P( G# l- z+ W
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());0 B$ E( o3 t- ?7 p& Z
  22. #endif
    , S, Q1 V5 g* {1 t2 L1 r
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。
; h0 Q# ?6 b" ?% Z5 |
  1. void SysTick_Handler(void)0 M* c; V0 R9 N2 W. D0 M9 L8 v9 \
  2. {; ~% p3 ]; V/ A6 j' K( N+ s/ S  a
  3.         /* enter interrupt */( }7 d* e# }, l
  4.         rt_interrupt_enter();
    ( ^$ ?2 k# [/ N/ ]2 ^

  5. $ d, ~6 f% W% l! V! R3 B' E, A9 o
  6.         rt_tick_increase();! R' c; o1 i( B
  7.         HAL_IncTick();
    $ U4 O. Q# t2 F5 P3 \# I3 B
  8.         
    % Z3 Y* Y) g( L8 V2 ^
  9.         /* leave interrupt *// @, p4 V6 x$ ~
  10.         rt_interrupt_leave();
    0 a* b5 s% N% `# ~( W/ F
  11. }
复制代码

+ e- @: ]$ v; {5 P+ p2 \增加用户代码
- @: S  y9 ~9 }9 ~8 s     
  1.          while (1)
    ' l7 m. t* ^( H6 e' ]
  2.         {
    8 v3 Y; u/ j+ A( _( w1 L) s2 p0 E
  3.                  /* USER CODE END WHILE */! y. G& Y! Y& \- I) b$ v  q
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);
    2 i3 e+ \7 A4 d  O& s. X" G, O
  5.                 rt_thread_delay(500);    l9 k; ]/ @0 x% f% G' T  Y
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  
    - Y: X& ~3 l6 b
  7.                 rt_thread_delay(500);  ' Q" ~$ Z% n( Q6 O/ {4 C* ~, `. y
  8.                 /* USER CODE BEGIN 3 */
    . i7 c* E3 Y5 {+ ~) Y
  9.         }
复制代码
  ~5 l) @, i, f3 [5 b6 M8 c
编译测试( z" ]; k7 x3 P5 I# e# y, k/ }
1.使用ARM Compiler version5 进行编译,结果如下:2 g, d( R$ T* x( M5 g& C

0 o# N+ k) q' u2 t8 Q2 s
20190627003559464.png
9 x4 ?' N# @# u, Y1 G  l3 ?
) G# O/ H0 h8 v) B' ~* d* B
2. 使用ARM Compiler version6编译,结果如下:
1 @: B8 q; \4 `8 ?& i' Q" F) ]9 _, s4 y
20190627003658959.png

2 p  c8 n1 u* K5 r- M/ G7 I9 P0 p+ A/ b) Q: [/ X
  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。
9 G6 c- B, |; Q. a- g+ O9 i
; p1 W# E$ s8 f: ?! t7 B- j( R
7 g4 m8 F' L; e( \" p9 i* R
收藏 评论0 发布时间:2021-11-25 16:00

举报

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