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

STM32F103移植freeRTOS(使用官方源码)

[复制链接]
STMCU小助手 发布时间:2022-10-28 15:57
1.准备工作
4 B/ A0 L  u+ Q; K; y6 T3 u7 z. |. @( }
2.新建文件夹及复制必要文件
# H8 S8 Q! k& N6 A
2.1、新建7个文件夹
& e' y5 d: \) W% ^5 i7 q* |6 i* I5 [; y/ O+ {& n/ z( ~
.\freeRTOS# N4 Q- E3 a# d# R$ X. W8 V! a
1 [5 f) N6 j( X0 v3 S/ v
.\freeRTOS\include
6 v6 O& x) {  E6 j$ p# X' E* b5 T) K; T- L3 c7 W& Q  p
.\freeRTOS\port- t+ ^. M# f1 e6 I
5 e9 A$ `: z; f. T( \4 U
.\freeRTOS\src
+ |% X9 U: r) U+ M; e- L' M4 c7 |! B: e! V( u6 n8 [/ }
.\Library
+ K! R$ s1 z6 J2 I/ E) b7 P7 }3 Q  d% T+ ?) g8 x- P
.\Project
  s% o8 U* J$ Y9 x3 c: J9 p3 \) h$ ~7 ?
.\User9 n- n# I" H/ Y. B+ i0 f' e- I7 h$ Q
9 j" E& Y0 D  E
2.2、把源码FreeRTOSv9.0.0\FreeRTOS\Source\include中的文件全部复制到新建的include文件夹  `. r8 k+ }$ @# K
2 p! H: r% }+ F7 y* f
2.3、把源码FreeRTOSv9.0.0\FreeRTOS\Source\portable中MemMang文件夹复制到新建的port文件夹中# B+ `: o6 F' A4 ?: g' a% p( B/ U

9 u* [( q! v+ z# ^) ~7 p2.4、把源码portable\RVDS中的ARM_CM3复制到port文件夹中
1 N' D; r! d$ x# m" ?& `2 m4 \" A6 |3 d" _5 K
2.5、把源码FreeRTOSv9.0.0\FreeRTOS\Source文件夹中的*.c文件全部复制到新建的src文件夹中+ Z8 h7 U8 Y5 X+ \) r" r
' q- \# j9 }% a* t4 O
2.6、把CMSIS和FWlib文件夹复制到新建Library文件夹中$ A* ~6 T  Z/ |, }% U, L
3 t3 S. i6 p( P- b8 `0 ^
2.7、User文件中新建一个main.c,然后复制标准库中的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h文件到User文件夹中+ O0 d/ }" T  W8 b, \( M

" n+ i( S. g' l3 ]4 L. ?1 Y5 s2.8、把FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil中FreeRTOSConfig.h复制到include文件夹中
' R! F  T% E+ e( d! t: Q5 z
- E8 [3 [/ L! ~# j8 i/ g3.添加c文件
7 H1 }3 \& E4 S, R3 g9 w5 z; S/ {3.1、打开Keil uVision5新建工程,Project-NEW uVision project,选中Project文件夹,输入工程名称,保存。
: H5 s5 t: z1 Z9 ~) f" s5 P
4 ?) G4 C/ f8 f& {3.2、芯片选择STM32F103C8,确定,再确定。, v- Y9 N4 x% D* R2 c* P

& a$ G& A1 n4 m3 ?6 i' a7 J3.3、打开管理工程项目,分别新建freeRTOS/port、freeRTOS/src、CMSIS、FWLIB、USER% W3 S7 d: d/ }# j, c" s; T
3 r: }% v2 k. R8 a, ^2 z8 Y. o
20201108161635983.png , |+ I1 k4 v0 H' V

5 U. X7 Q- {% s6 Z/ m+ H3.4、freeRTOS/port中分别添加ARM_CM3\port.c和MemMang\heap_4.c两个文件
; I0 N% M2 {! ?& b
1 d" C3 V/ \. V# z3 C4 m 20201108161917372.png & L0 v3 {" n, i# J* S$ U
* H7 |0 C" \. V6 h
3.5、freeRTOS/src添加freeRTOS\src文件夹下的所有c文件
7 Q5 [0 y$ a6 ^- i3 x5 F1 o5 {
7 `2 M' w2 G" Z4 ?! E 2020110816205047.png + k: J* V$ G* d$ V7 j7 Z/ x% Q

) {+ P; {5 U$ j3.6、CMSIS添加Library\CMSIS\startup\startup_stm32f10x_md.s、Library\CMSIS\core_cm3.c、Library\CMSIS\system_stm32f10x.c三个文件% D# J2 V, `; i& G( ]3 v9 J3 l

3 j9 t% C- v: g: Y* p* s 20201108162313840.png
; q: r6 q! Y) k0 m; K$ d% e+ G, }  C3 ^/ j: G/ h
3.7、FWLIB添加Library\FWlib\src文件夹下所有的*.c文件
4 A, q( W9 }4 P% Y9 I
; y3 M$ q* t4 o6 w 20201108162421951.png 3 t4 ]: A2 F% y8 u0 W- o

: `5 X' I5 L$ E  a+ f3 p5 P3.8、USER添加main.c、stm32f10x_it.c,如果这里有其他自己编写的代码,也可以放再这里。比如LED,KEY,USART相关代码4 F6 V$ I& E* W8 l
1 W( W7 ]6 |2 K8 t8 a% U' u
20201108162900407.png
# }$ g& c2 Z! o9 I4 e* n4 [7 X+ ~
0 K/ s' K" G7 v4.配置运行环境' ?: T6 _( G: \* w
4.1、在C/C++选项卡,Define输入:STM32F10X_MD,USE_STDPERIPH_DRIVER
" u  }( _; Y0 a9 \5 ]; J* U, h1 J; _7 w
4.2、在C/C++中,包含include路径:freeRTOS\include、freeRTOS\port\ARM_CM3、Library\CMSIS、Library\FWlib\inc、User4 F( F8 [" _2 }& q
6 b6 N3 |2 N( Z! Y. ^4 k
如果还有自己编写的其他头文件,也一起包含在里面。如LED,KEY,USART
9 K( w  \  q1 ^* A+ ]3 r
1 J0 ^, ?, ]. ~& F7 i3 ^, E6 C 20201108173801445.png 0 Z; n4 H) t3 j) O

( K6 k7 x9 ]; I; `& q$ m8 u4.3、使用MicroLIB库,# F3 ?& ^0 i7 l8 Y; ^9 ^

( a+ D5 y8 ]4 b. t3 R 20201108172915724.png
2 q9 v$ H( U# _' Z; _; `) V# P5 }2 d, G! \2 U4 i8 |
20201108172935585.png 20201108173014700.png , p+ S! m8 q% A
0 D3 G& _/ x3 [! s  c
5.代码修改
5 `  h- }' c3 F% O  b1 E5.1、在freeRTOS中,已经为用户实现了SVC_Handle()和PendSV_Handler()函数,需要注释掉,修改stm32f10x_it.c文件
! h. v+ v' X5 ?! |# B4 T. {  Q6 ^7 r* O
  1. *& X/ ]! n7 ^& r3 k$ W6 ]# }" d
  2. //void SVC_Handler(void)2 \3 W! c  n5 s2 T/ {: G# Q+ l
  3. //{
    4 ^% u" n2 w2 g% v
  4. //}
    , U+ F/ o% Q9 a  Z- K- G  p
  5. *
    : F) h! [4 e8 R+ c) h$ c* a& `
  6. //void PendSV_Handler(void)' `0 {; _, E% y* h' D) g
  7. //{  U$ ?/ L6 J8 R' ~
  8. //}
    # F0 U+ W$ x6 i2 q; F7 q; U9 M
  9. *8 l/ E5 O% P5 M; A& C; y
  10. /*在c文件中添加如下代码*/  e& N1 w1 i: b+ ~. {8 j2 e
  11. /*freeRTOS中的systick中断函数*/
    # k; j  L; K8 i2 j2 s! y
  12. extern void xPortSysTickHandler(void);8 h7 X6 A5 G2 D$ z5 T: w
  13. void SysTick_Handler(void)) w* J, k7 _- L+ Z
  14. {% A" j! I0 u5 N8 R  B
  15.   #if(INCLUDE_xTaskGetSchedulerState==1)
    3 r8 x  w0 \7 [) o# S) [! M6 |0 r
  16.     if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED){7 Y7 ?) j4 j: R
  17.   #endif
    $ Y+ `5 V, z- V7 }- X8 O3 O
  18.     xPortSysTickHandler();2 N) z% s3 _7 d8 Q; h  W! Q
  19.   #if (INCLUDE_xTaskGetSchedulerState==1)                & Z* z' u* F, I+ f
  20.   }
    + O# x2 S1 @7 G+ e" I) ~5 c) r
  21.   #endif1 R5 D- z$ C# |/ K8 e
  22. }. I% h  B$ y3 E; e: ^0 h
复制代码

8 \% f) {# F  d/ P, @# G1 @/ ~5.2、修改一下"FreeRTOSConfig.h",这里我使用软件定时器,需要打开对应宏定义,还要配置FreeRTOS与中断服务函数有关定义
: A# S5 l0 h7 i6 ^/ D6 \' z1 S: y. Y/ K% N" B
  1. /*FreeRTOS与中断服务函数的配置选项*/3 y1 v7 S, `' b: [
  2. #define xPortPendSVHandler         PendSV_Handler
      m% Q* M( c& u# u4 j; @1 H
  3. #define vPortSVCHandler         SVC_Handler
    % g  m# V* n  t3 e: b$ A' R. c
  4. , e/ g' |5 W4 B" n& t1 s
  5. /*启用软件定时器相关宏定义*/* u: d4 W! y3 a' Y( ]/ s5 h
  6. #define configUSE_TIMERS                           1   D2 C1 z4 Z* o
  7. #define configTIMER_TASK_PRIORITY              (configMAX_PRIORITIES-1)        
    $ k) j4 f9 S$ |( Z% Z& F& X
  8. #define configTIMER_QUEUE_LENGTH                       10                              
    ) y$ c2 E1 x( k5 t
  9. #define configTIMER_TASK_STACK_DEPTH               (configMINIMAL_STACK_SIZE*2)
复制代码
. W  L2 C) @- m5 z9 R. \
5.3、最后就是添加外设初始化代码,主函数里面添加任务代码。main.c代码如下
, N; f$ b( x7 e% G
4 k. i  ^8 `' S/ T  O9 E
  1. #include "FreeRTOS.h"$ g( j7 x3 [7 V4 S6 p
  2. #include "task.h"$ V3 r7 O; H3 G9 `0 y0 a, l0 v1 m
  3. #include "bsp_led.h"
    ) v' N$ x0 z& b$ Z1 d" ]: w3 i4 x% s
  4. #include "bsp_usart.h") t0 @" E8 g& z! v
  5. #include "bsp_key.h") l8 V* ?- M0 V% k
  6. #include "queue.h"5 a7 o2 D, i6 Y& B+ g
  7. #include "semphr.h"( _  _: u( D5 q5 O7 d  R; J% d+ a
  8. #include "event_groups.h"4 Y0 _' c1 {; W: w
  9. #include "timers.h"
    - Y: C, u6 Q0 `% ^% d

  10. + Q& h5 k$ b1 |9 d  t

  11. 4 q) w: f3 R- E& `" b
  12. /*Function definition*/
    9 W  {, t! o  \4 d' W5 H3 [
  13. static void BSP_Init(void);/ v: a* Y5 R) d" n
  14. 9 O0 a9 R- s( H; x9 J) Z2 {
  15. static void Send_Task(void* pvParameters);- ]' ~6 H! W" _
  16. static void Callback_LEDTOGGLE(void* pvParameters);6 c7 h3 ^5 B% {6 H& U1 p5 `
  17. + j$ m* b1 z+ {
  18. static void AppTaskCreate(void);
    9 t  B& t+ [: u
  19. 5 E7 N" D* L( b+ m4 q9 G

  20. 3 s; ]& f/ ]/ {; x
  21. /*Task Handle*/
    ) K6 l/ a: C8 E8 p4 Q& M, \
  22. static TaskHandle_t AppTaskCreate_Handle=NULL;
    ; y* I2 _4 ]3 i! t% c
  23. static TaskHandle_t Send_Task_Handle=NULL;       //PRO:36 |. C5 p) T! z) u7 Y
  24. / i3 B1 i) f1 l/ G& V& g8 _

  25. 6 L' u; c+ d/ \# z
  26. /*Timer handle*/4 K. f. c, d. b4 Z( x
  27. static TimerHandle_t Timer1=NULL;+ u% s# R- d- h

  28. 6 V' n  o2 S0 D2 S3 f
  29. static void Callback_LEDTOGGLE(void* pvParameters)! q: g7 ^+ z- S, C% |8 _& ?
  30. {& b+ U6 ^, s+ f4 h, }
  31.   LED1_TOGGLE;$ {8 h9 g3 E* ~& R
  32.   printf("TickValue=%d\n",(TickType_t)xTaskGetTickCount());6 o+ K0 A# A" C7 M) F6 B
  33. }
    ' C: G; f$ C" \& x8 V3 ?; P' y4 y

  34. 6 j1 t& W8 \' q% [4 x; n: k
  35. + p1 D, e! B% d0 U: e( t
  36. int main(void)
    6 y& P: [3 W( h4 X" ?. [- Z
  37. {  
    ( y0 I: r' t  F& Q8 A# h3 R# K
  38.   BaseType_t xReturn =pdPASS;
    - }& U! Y# s5 @9 d+ E' V5 J

  39. : h" ]" n; q! ]1 ?2 a5 E
  40.   BSP_Init();
    ; H' y  W0 Z0 t& A/ C
  41. . o9 {9 M2 ]  ~, Z: a  o# [
  42.   printf("FreeRTOS creates tasks dynamically!\r\n");
    ) ]0 g- l: _; b
  43. 8 ?; A- U1 w9 L; l5 }8 v
  44.   xReturn=xTaskCreate((TaskFunction_t)AppTaskCreate,\2 d3 f4 B& k6 G4 `1 V
  45.                       (const char *)"APPTASKCREATE",\
    : y  j8 F6 c# X5 J; ^" z" `# u3 H( ^
  46.                       (uint16_t)512,(void*)NULL,(UBaseType_t)1,\6 y. ?- K5 N1 T! J/ A
  47.                       (TaskHandle_t*)&AppTaskCreate_Handle);' m/ K" k# r  g+ n2 C
  48.   if(pdPASS==xReturn)5 o$ ~5 v0 z- H7 E7 d0 o5 ]
  49.     vTaskStartScheduler();$ [8 J6 V2 A+ X6 Q" a
  50.   else3 K; D/ i5 W" n8 b
  51.     return -1;
    7 P4 y5 I4 g6 k4 a
  52.   while(1);
    8 B- e, ~8 `* S" G9 o9 K6 ]* n
  53. }
    * @5 x3 h4 q) ~5 k/ Z
  54. ! b. [, k9 m; \9 i* u
  55. ! h, k) o9 k& L% H& @
  56. /*Hardware initialization*/
    7 u. c. t6 n- g
  57. static void BSP_Init(void)$ X2 _3 g9 a* M) c" F
  58. {
    ( Z7 E" {' F6 D2 R! T, x
  59.   /*Use this priority grouping uniformly, never group again
    6 U$ h" v0 R; x9 m. M3 v: g) C- t
  60.   * 4 bits for pre-emption priority3 w6 L$ w9 @. W7 M' p7 k
  61.   */! k- G3 U$ M0 L4 M* _0 W$ D

  62. + ^: }- E1 }9 E9 ?7 b7 L& ^: P
  63.   /*led initialization*/
    , `* B3 ]4 G' z9 x& @1 u+ K
  64.   LED_GPIO_Config();
    ( {  x' _, W' Q
  65. 2 `/ E3 X. `/ W
  66.   /*Serial port initialization*/7 u! G1 r: N2 `+ N1 H
  67.   USART_Config();) U% F8 s/ h) }9 m8 g

  68. , c# D8 m% ]/ {3 S5 y
  69.   /*Key initialization*/4 j2 u1 C6 v( e' |, n: j" \
  70.   Key_GPIO_Config();
      h, a1 |6 M5 V
  71. }* T% C3 H7 V+ w, ]) F7 x1 a+ v: C5 Q

  72. 7 @; p  @, [2 @$ f' X5 z1 h
  73. /***********- g( D; a$ v# q# `0 z8 l
  74. *@Function name:SEND_Task
    0 t% v$ G; ]$ d/ `
  75. *@description:SEND_Task body, ?" k, p7 n9 f9 |8 L
  76. *@Parameter:None7 K5 s: |* P4 M
  77. *@return:None; P- B, z' r6 n2 o6 V( Y- p
  78. *************/
    ; w4 D( L1 I0 U7 g5 R7 z+ T" C1 M
  79. static void Send_Task(void* pvParameters)
    $ y2 p8 z1 G0 @, X
  80. {- e7 v% `1 D% W* ]$ V. `

  81. 3 H+ J& q. l5 d* m- w
  82.   while(1)% L. U5 |: @) z3 j
  83.   {  
    ! i! e) D1 p# `' `- p' r& ]7 t
  84.     vTaskDelay(100);         //只是为了演示任务切换2 D1 H& c! y4 p
  85.   }+ e/ }" V# ?2 b$ a
  86. }0 Y! t6 R' x8 \0 F' V6 i. e) A' b

  87. / i* A3 S1 o& C: N+ O
  88. static void AppTaskCreate(void)* T$ y) z1 n- a. s% s+ A( V
  89. {
    4 Y' L" d+ j5 y# J4 r) w1 q0 Q
  90.   BaseType_t xReturn=pdPASS;- d/ w. `+ _; Z" x+ H- l1 T: K
  91.   taskENTER_CRITICAL();
    ! h! d/ B, }6 V! U) b& J

  92. $ Z7 l' K( k5 l2 C: T0 v
  93.   /* Create Timer1 Handle*/
    2 U$ G' I: r1 U. }$ E; H9 F( d, i
  94.   Timer1=xTimerCreate((const char*)"1sec-toggle",(TickType_t)pdMS_TO_TICKS(1000),\
    / Q; U6 M7 }, p, m6 ]/ p7 w" o' T
  95.                      (UBaseType_t)pdTRUE,(void*)1,(TimerCallbackFunction_t)Callback_LEDTOGGLE);5 }* S2 @$ R% ^
  96.   if(NULL!=Timer1)
    - a/ n( z. g) P8 ]/ d1 O
  97.     printf("Timer1 created successfully.\r\n");
    0 C- Q( n. S$ {  K
  98.   xTimerStart(Timer1,0);; s2 e5 v/ m. `. w! L. B6 ?4 F

  99. - P7 [; O$ [3 ~
  100.   /*SEND task*/7 ]. _0 y6 \/ n0 A, \
  101.   xReturn=xTaskCreate((TaskFunction_t)Send_Task,\$ S: A  d+ b0 g6 H4 x
  102.                       (const char*)"SEND_TASK",\6 Q  U/ j1 a* S% O
  103.                       (uint16_t)512,(void*)NULL,(UBaseType_t)3,\
    # n' Z) o$ _+ q" b1 D1 l' I
  104.                       (TaskHandle_t)&Send_Task_Handle);: \, e, H( b% X/ u
  105.   if(pdPASS==xReturn)
      t# B3 _) b5 |& g0 L
  106.     printf("\r\nCreate Send_Task success!\r\n");4 z3 H- ~& f) _; i0 }" F/ W. L
  107. - ?! F( X6 I& j/ h3 D: H6 b
  108.   vTaskDelete(AppTaskCreate_Handle);
    " R, \2 ]1 l, |" R
  109.   taskEXIT_CRITICAL();
    " s: N0 [0 m- D' _# z+ ~3 T
  110. }
    # t! d$ Z4 ?/ U6 Z8 @+ b
  111. " O0 f. N6 m5 n
  112. /*********************************************END OF FILE**********************/
复制代码
, b. L, F( m2 p: q" e+ ?
0 M& T& I+ D; |; S9 a" `
————————————————/ E% c6 f9 o' s( H7 q* X, P+ l
版权声明:SCCELE
2 Y% V% e3 K# @/ Z" }% d9 c. |
; {/ c0 T& b, y7 {
赞 收藏 评论0 发布时间:2022-10-28 15:57

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版