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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
硬件介绍& g- Y1 o+ N6 [6 V; j
  我手上开发板使用STM32F030F4P单片机,无外部晶振,所以直接使用内部晶振。开发板上有3个LED灯。0 p; a/ s, Q  A3 Q3 {! Z' m
: L1 |3 t1 M3 R6 u! d1 Z
AI[KPXW81}UWZ~_C_U1JBZR.png
% g+ O7 g# T" {7 z! h$ {

+ m) D+ T) z. S; E7 e) J/ G' O* F安装rtthread_namo包
$ z1 _" K- V0 B在操作前,需要安装MDK5软件,以及STM32CubeMX,并安装好STM32F0的Pack, H  K8 X/ @" Q7 ]$ n1 K" Z

2 i/ S) h& }* ^/ X3 E1.打开MDK软件的Pack Install工具,选择RealThread:RT_Thread进行安装( z7 Z" B' `6 g2 M. d/ v4 w

9 J  `9 E# H8 z& F3 Y/ m5 j! b, J
20190626221653457.png
+ `: i$ [* H, Y' }  o7 I  X. J: A

* f0 ]2 ?: ]+ _) Z8 n
20190626222025313.png

. l! f  G+ g# z9 @9 D
: k- k8 `4 G0 F" F7 J2.在弹出的节目中选择Next,等待安装3 n1 ]( }" N! A$ F

" _/ `/ z* ~  o
20190626222140363.png

! k, D# f3 u! N. o# ?. ?1 B- S  j$ Z" G  r
3.安装成功后,Reload Packs即可。
0 y6 T9 x, v' ~8 w; J
4 U* F5 n/ O* M% K3 \/ i
20190626222321230.png
/ X) ^  {1 p4 @( [# x/ l1 c: E; D; p

3 {! P9 c( w) ~+ ]创建工程
6 D7 m* r! ?2 i1 u* l! ~* `1.选择芯片STM32F030F4P6
" D* S3 X% Z; _* U
. x8 l2 k5 J  X3 z& L
20190626222525565.png
0 l/ n' e6 C9 t6 @. D) C) R
$ |: z2 A6 `* g: i" E
2.Manage Run-Time Environment
% v; ~6 d5 H" W9 ]% Y: \- n
5 \9 b7 {" p+ U
20190626232949409.png

0 E. q" g* n9 I5 ^. v( h* k. f; U0 l: z$ a# s
   按照图中进行勾选,由于我们芯片资源有限,而且这次的电路并没有接触串口,所以在RTOS部分,我们没有勾选shell。
5 z/ T1 X% i0 n3 i8 c4 j! w" @5 c$ |- k7 h7 w) k7 }8 g6 ~% n
3.Start STM32CubeMX0 H6 G0 o- r: i2 h( g' e& a

7 K9 }" R4 A* z1 e' m+ ~6 A
20190626223125381.png
( p2 e) x! z: S  d- O' C( Q
" t  @9 c; {' }8 [% S+ z
   勾选完Run-Time Environment后,会自动弹出启动STM32CubeMX的窗口,我们打开STM32CubeMX进行配置。$ {2 D0 J1 i# H: @

( S  V* I8 p3 N0 V" p$ n- a0 [2 {4.STM32CubeMX配置Pinout&Configuration
5 ?. v* Q5 V8 q% U7 d/ |$ `4 a) O: z9 p" `, @' }7 R
2019062622382861.png

/ p  Q* ?. S7 B7 v5 c$ B7 y
20190626224105362.png
! F  j0 f, J+ l! [# p
20190626224233634.png

( F1 f9 U9 {1 E; N% ?7 Q& H9 ^4 t* Z7 _' r1 j: ?1 ]
5.配置时钟
$ \/ E9 K$ V  @+ N: Z! m6 ^1 G3 A) _2 _( D
20190626224701758.png
- g* S, {& o2 P% J5 S% y

  D  J; H/ J1 Z6.单击生成代码  C7 q; I' Y/ O( \) L/ h
: r5 s% B. H( c0 E# w
20190626224854251.png

% Y0 W% t: u2 l3 ^- n6 s% H8 y# _* y9 ^2 ?3 ^$ t
7.生成代码如下* j, ?( W. g: k9 E% n
  b; V. m5 Z1 M* }
20190626225932442.png
1 Z" F& _3 N# |/ {* B) B  o
; l+ u- f& ^4 I! v, g0 u# p
配置工程* F$ j' b- @  h+ B3 s( ~  O1 o
1.选中RTOS下的rtconfig.h文件,使用Configuration Wizard进行配置( ^% v' m% C$ s2 H8 C
1 |3 k( T- q8 p7 q- q7 ]8 Q# |
20190627004726239.png
' q2 v) r$ i& _1 u; [; n
# B" g8 c6 t. o( R
2.内存管理设置- Y$ o2 K/ _, d2 J
9 z) j# l, {6 @! L" P
20190626232130606.png
; t' D2 O8 C5 n  E

7 f# k" w( V+ M! u: N% d   由于芯片内存很少,我们取消Dynamic Heap Management。勾选上using small memory。
6 \  u+ R0 m5 Q6 {
( f  I& v$ L# Y5 u0 D/ C3.关闭console和Finsh  n( G7 ^  C" O' f8 R
7 ?) ^" @1 I# v
20190626235930620.png

2 \: U0 ]( e  h3 g
- a9 S0 `8 p+ S) f5 V   由于我们并没有接出串口,所以关闭串口相关的内容。
2 y9 }4 F- ], N& {- r9 G$ p4 Q: h% Z5 b3 Q4 {; W
修改代码,测试/ T/ _% ~& i* \6 V6 |$ Q
修改stm32f0xx_it.c文件" X9 j5 m' f% n8 |! C. F
   由于rtthread重写了部分中断服务函数,所以我们需要将stm32f0xx_it.c中部分函数设置为weak。/ H- P) K+ ]  s3 Q( p
  1. /**
    , I/ X8 z+ b8 P* h3 j- k  y
  2.   * @brief This function handles Hard fault interrupt.
    ; e/ i5 @: t- T/ E9 k2 R3 U& e1 X
  3.   */% o- t/ M" Q' L
  4. __weak void HardFault_Handler(void)5 B! q- [5 d* M4 Q$ w
  5. {, O$ f7 ]+ ^* B- c, t& }
  6.   /* USER CODE BEGIN HardFault_IRQn 0 */4 R1 d$ V4 P6 g% n8 v
  7. * e) g& d3 Q& J  p% l
  8.   /* USER CODE END HardFault_IRQn 0 */
    : ^) _& H0 ]( y/ k* o7 b2 }( G
  9.   while (1)
    ' Q, P$ r- i) m, \: Q+ i8 ~  Q
  10.   {; M' y0 @) [$ f( ]+ ]2 ^  i) U
  11.     /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    ( ]( I5 t+ A7 W- F( z
  12.     /* USER CODE END W1_HardFault_IRQn 0 */
    + {$ @* T0 t8 P
  13.   }5 U) d( D$ [% E
  14. }
    ! K# {  j3 J* |9 m5 A2 e% q+ V
  15. & k. L5 V8 A+ W
  16. __weak void PendSV_Handler(void)- c7 G2 a  K  Q, w
  17. {
    % E% c1 \0 R. O5 @
  18.   /* USER CODE BEGIN PendSV_IRQn 0 */) Z: \8 [# O& h

  19. 0 S5 A3 b0 O& N! Z2 O; q, d
  20.   /* USER CODE END PendSV_IRQn 0 */
    7 M7 j8 f0 u3 y
  21.   /* USER CODE BEGIN PendSV_IRQn 1 */
    ( M" Z0 L0 M" O$ ~! {
  22. 0 d' D  G5 W+ i/ ~8 G  m  K
  23.   /* USER CODE END PendSV_IRQn 1 */
    : o, T; i  C  R  L+ \# v, y
  24. }
    ( O* O( e8 t" R5 @' {' T
  25. 4 J- }) ]: n% v1 m0 Z
  26. __weak void SysTick_Handler(void)0 D- w& i/ X9 ^3 i+ `2 D& w: M
  27. {# y# M1 y- i' o' f, S
  28.   /* USER CODE BEGIN SysTick_IRQn 0 */
    $ X' v1 I* S2 z9 @) P5 C8 S' ^2 P

  29. 2 \  q# }- i- M9 S1 l
  30.   /* USER CODE END SysTick_IRQn 0 */
    * y" }  m0 ?2 A2 r* W6 D, p
  31.   HAL_IncTick();8 e. v& B0 e' Z
  32.   /* USER CODE BEGIN SysTick_IRQn 1 */
    ; h6 l( Y' ?% P8 h" C1 y' i
  33. $ Y4 ~1 m2 J& @
  34.   /* USER CODE END SysTick_IRQn 1 */
    ; w3 m' V2 l3 s/ l8 Q
  35. }
复制代码

/ V) B9 n. F! r, t! K( ~) |  K  r修改时钟部分
2 X" C+ n' X$ K3 _; c- y) s   在mian函数中,有HAL_Init()和SystemClock_Config()函数,用来在系统开始的时候初始化HAL和System时钟。但是当我们使用rtthread后,第一个执行的函数不是main()。而是rtthread系统的初始化函数,并在board.c的rt_hw_board_init()中进行硬件初始化。
" `" ?. X4 s  ?; @# ^   我们将HAL_Init()和SystemClock_Config()放到rt_hw_board_init()最前面,保证在用户代码运行时,时钟时我们希望的样子。$ \5 q2 w# ^1 ?  Q; F' H
  1. void rt_hw_board_init()+ Y9 U( t/ `8 K0 x
  2. {        
    / d" g0 y2 O3 d3 }" w( ~
  3.         /* System Clock Update */. g7 k: e8 Y0 l
  4.         //SystemCoreClockUpdate();
    ' N! \2 w$ Z2 i* f+ p9 Q. i" d( Z
  5.         HAL_Init();$ v: s% T8 }  A) F* q
  6.         SystemClock_Config();. j! w  z. z4 v7 [3 _' x& y6 B
  7.         + V$ c% s4 o' a1 ]) L  d
  8.         /* System Tick Configuration */
    7 e% n! _, @1 @9 ]3 ~& L
  9.         _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);& i7 p$ L3 w. t: E
  10. 1 `$ \# K% {" ]( u
  11.     /* Call components board initial (use INIT_BOARD_EXPORT()) */
    ' {" Q* ~' S1 }/ Z8 z# a* c3 G
  12. #ifdef RT_USING_COMPONENTS_INIT
    * g8 k6 i5 ]3 r; {" \+ m
  13.     rt_components_board_init();/ p8 \$ M6 D" u" s/ e. o( _- q) k
  14. #endif, i2 [( N. E  w) d) p- f

  15. # e0 X; R- ~, V- O
  16. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE): F9 T( g% H9 i/ i, H8 G
  17.         rt_console_set_device(RT_CONSOLE_DEVICE_NAME);: z) M  ~9 g9 q3 }# [. r
  18. #endif
    0 R1 K5 L; @; e. M% d
  19. - U3 a* L( [; W
  20. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)7 u, Y7 ~4 a' x+ ~1 Q
  21.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());- n0 {- e) W, W7 ]% w/ p
  22. #endif# P$ k& o$ q- N& m1 p& I
  23. }
复制代码
   由于我们屏蔽了stm32f0xx_it.c中的SysTick_Handler(void)函数,SysTick_Handler(void)中的HAL_IncTick()也一同被屏蔽,我们将其移动到board.c的SysTick_Handler(void)中。
! g. s: e- X  h: v- |
  1. void SysTick_Handler(void)
    : Z: [& U' W# ]) Q. J, r" W
  2. {' l! ^+ n3 n/ f  t8 h% [3 ^
  3.         /* enter interrupt */
    " A! `0 D. m0 t) t
  4.         rt_interrupt_enter();1 q( Z0 B& ]4 _5 @% m; I- L

  5. * [5 b* v- L/ `1 V& E' G% Q
  6.         rt_tick_increase();0 f/ c4 K: I0 S! @
  7.         HAL_IncTick();
    3 F1 E7 E9 ~. }( ?2 i! s
  8.         6 r* O* d9 e1 N2 T% x& r1 F  o
  9.         /* leave interrupt */
      `  s4 j! _5 J0 d
  10.         rt_interrupt_leave();
    : m+ ?  D4 Q1 L+ \
  11. }
复制代码
, _- a3 H3 s3 `1 ?  q/ G
增加用户代码6 V+ O6 _' u( x9 x+ [
     
  1.          while (1)
    . N% u+ @! Q, X$ T) f1 i" z
  2.         {
    ) ?5 u1 d8 E/ j& D1 y/ Y
  3.                  /* USER CODE END WHILE */
    , h9 n; P# h" I- J, M. z2 L. m4 k
  4.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET);9 d, E+ y1 |7 j# @
  5.                 rt_thread_delay(500);  9 w& v$ @# i7 u7 c9 ~& M8 J5 X
  6.                 HAL_GPIO_WritePin(GPIOA, LED_R_Pin|LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  : a6 l' L& W  `0 ^0 G: a
  7.                 rt_thread_delay(500);  
    " T& R5 w# r# O/ b8 K- `- O3 d
  8.                 /* USER CODE BEGIN 3 */3 X1 ?1 S$ E! t8 H* t
  9.         }
复制代码
# Z- Y* I1 u; H4 J
编译测试- X# `- |1 E" C% ^) E6 [
1.使用ARM Compiler version5 进行编译,结果如下:
9 f7 E0 W- F6 N( u
$ O' k  x3 h0 g4 Z
20190627003559464.png

& H4 q! c5 ?! ?/ K+ B1 |7 ~
- ^5 u/ x" S/ N' h) s" ?% L" o7 Y2. 使用ARM Compiler version6编译,结果如下:# i( h) b1 y7 O5 \6 _

5 U4 ~$ T( P2 K/ I4 n& a
20190627003658959.png

" D8 F( A" W2 F6 b+ ]
8 B3 I  D. h4 X7 }6 f6 j. {1 i0 q  相对于我第一次写关于ARMCLANG的博客,已经过去很久了,目前很多中间件,以及STM32的HAL库都已经能很好的支持ARMCLAGN,推荐大家使用ARMCLANG编译器进行编译。
7 ]; x& ~& L* D$ _6 T3 d5 @* o. j/ z

$ ~/ A7 K9 v) T9 s
收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版