前言3 K7 O5 L: C/ `9 Z
演示STM32F103移植FreeRTOS完整过程,文末提供移植好的完整工程: [8 z( P8 K+ P1 O; C& n
/ v# w7 R' k1 R* s: Q) w$ K# W
1.下载源码
' U# L4 _. ~1 |4 G4 W9 A! j% N下载FreeRTOSv9.0.0.zip解压如下图
' G% r8 N1 n2 u) t9 R- L2 u+ W! O4 R9 u: S; `4 k
! Z; A+ G N( P) J) t, q
4 l9 b% Y4 w+ M+ f% Y3 F只用关注第一个文件夹FreeRTOS中的内容
+ m4 X3 i' ^* K6 S3 p
0 M# ^$ R. p9 x$ e5 x
. q4 W5 o7 q, r& G3 p7 J
. B" @ d% y" x0 E0 P3 Q& k' P- BDemo是官方提供的常见芯片的移植示例,包括STM32F103,我们需要用到其中的FreeRTOSConfig.h配置文件。4 [: J$ h2 t; H
Source是源文件。0 p( Z! m+ x! C Y9 Y8 X
+ G9 S+ ^6 U; P
2.拷贝源码; J, N3 b- _0 ^! I( F$ [( Y9 ~( t* z
在工程目录下创建FreeRTOS文件夹并创建子文件夹src和port% m, T! }% L# t! V
- E. M' C& [& R" _8 [; D& ^
6 O* v1 B) V( g( M. H' ]0 w4 X/ e" a S! J
将Source/include文件夹拷贝到FreeRTOS下. }# e" d& Z7 M0 w# ]3 C8 k% [
将Source中的C文件拷贝到FreeRTOS/src下
9 v% m# [/ Z9 v" N+ a
2 {4 W! m0 ?4 F+ F! R5 {% R
. r+ H8 ^( E- i# d
* ^6 X" Y# g* |" I3 [! S将Source/portable下的MemMang和RVDS文件夹拷贝到FreeRTOS/port下,
4 G% d3 [ r9 T( o% K6 h6 z: D8 a
! j! _+ l! g$ _" y其中MemMang下的源文件是用于堆栈管理的,RVDS下的源文件是不同内核相关的接口文件。/ Z* g8 p+ a4 F% f8 I
, E3 K2 ]! e9 O% \
1 G' ?, W3 b' E) h, [
5 O- Z5 W6 A |% R$ d3.添加到工程
! Z. k5 ]. t0 u8 B/ L: p6 q" ?0 g( s- ?$ i, e
* T. ?/ A& S5 e( P! G# u! e" q
4 r4 ]5 L) B" M8 C新建FreeRTOS/src和FreeRTOS/port组3 t/ U9 l% D' Q# `5 |
3 ^ O$ P3 A$ N# ^: i1 bFreeRTOS/src组中把FreeRTOS/src文件夹中的源文件全部添加6 _% b3 I9 V: v) R
5 F9 y7 m; z0 e0 _" n( C
FreeRTOS/port组添加FreeRTOS\port\MemMang中的heap4.c和* R6 l- L, i% P+ N& \ F
1 u+ b% j7 a1 h8 }9 E& d; cFreeRTOS\port\RVDS\ARM_CM3中的port.c
- }% v3 [. A0 n# ? F5 T/ @" l2 u; E3 w$ @8 _4 F& ^% p5 L5 ?
. }/ K. c9 s4 ^& N. i* F添加头文件路径
. v1 e3 l$ T; t+ [: a) o( ~# g' E+ v. y6 {
1 R# l/ I- ?( H$ a* P+ m
: u" g* E* h9 ~
拷贝FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil下的FreeRTOSConfig.h文件到工程
# K( D4 p% I( T& R
0 g! |) T6 Q& C5 p9 h1 `# R& n/ t" I+ o$ P G
4.修改配置9 W2 F/ e6 z; i( }
在FreeRTOSConfig.h中添加
' {" `0 S/ h4 ]3 ^) g8 e- #define xPortPendSVHandler PendSV_Handler
# E* I% `6 Y0 q/ o+ E5 e$ K - #define vPortSVCHandler SVC_Handler
$ @! c' E' c, @- l
复制代码 ( X7 P( u# W5 C; R
在stm32f10x_it.c中屏蔽PendSV_Handler和SVC_Handler中断2 F/ G8 j, ?2 H' z7 N6 b# K
最关键的一部,修改stm32f10x_it.c中的systick中断服务函数。
8 `0 m+ q$ ~. w p6 t! C- /**2 s' ]0 {- k: j8 L0 n( k. T
- * @brief This function handles SysTick Handler.
' B* x9 s( S. N/ E* y5 m - * @param None
/ x) X; F) j/ w6 i/ C - * @retval None
3 `8 Y/ M* M" _/ ~; K$ R - */
1 J4 y0 M% F- L: \! b+ h" ` - extern void xPortSysTickHandler(void);
- z0 Z+ L/ E3 o9 A6 b; n& t - void SysTick_Handler(void)
! {! y) I3 T+ H. Q3 U - {
; s B9 T7 }$ y( H, X - #if (INCLUDE_xTaskGetSchedulerState == 1 )
# Y8 r/ n$ @' c - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)3 J9 D8 e& K; m- T7 }
- {# s8 G. O$ ?3 e% @4 v( ?
- #endif /* INCLUDE_xTaskGetSchedulerState */ 4 B. g! ~7 J: w/ Z" G- ^
- xPortSysTickHandler();1 e3 G1 D* L% v8 X% W) H3 E. n
- #if (INCLUDE_xTaskGetSchedulerState == 1 )+ E h! M9 s# ~6 M
- }
- P0 w: F: H2 \% e* P) I1 g [ - #endif /* INCLUDE_xTaskGetSchedulerState */5 O% g: X V& _9 y
- }
' l5 X/ [# B5 I% j" S
复制代码 8 U+ Z) a, y) h$ f, s
5.验证demo' B) `) u& T- p9 ~7 w3 ]
- #include "stm32f10x.h"
! p" O* c3 ?2 B) U. U3 g - #include "FreeRTOS.h"
& ` q# {2 x) F3 i+ {. m/ j$ V - #include "task.h"' c5 M4 _2 k0 [9 u M* H
- #include "portmacro.h", c0 ~) T9 h( |# }. x, [# ], Z# m) Y
- #include "bsp_led.h" % d Z/ J) W f" ~- w( s
- #include "log.h"
* U6 j7 s; m" R5 A - 6 L) ^. p# F+ V3 r. d2 \: ?
- static TaskHandle_t led_task_handle = NULL;
4 X: o: W+ A: t& h* r6 a" x! b - ) M4 Q0 H/ v# X4 Q2 \# p! z, B
- void led_task(void *arg)8 v! b T G* d1 E4 i
- {
# O$ y4 G h) E9 @" W$ V2 T. f% a - while(1) ' Y- S. K0 `. l) N9 M# y I
- {
1 o7 L) R' k, ^+ k8 g9 ^6 c) n3 K: R - led_status_set(LED_STATUS_ON);. s# Z# \2 G$ K$ F3 q' N/ s
- LOG_DEBUG("LED_STATUS_ON\r\n");7 @5 D( b& E0 U5 o" C2 f/ C
- vTaskDelay(500/portTICK_PERIOD_MS);# [6 Q- w) ?4 }- Y2 A2 V# p
- led_status_set(LED_STATUS_OFF);
?) n0 ~* ]8 ?- \3 l1 Z# ?* c' s - LOG_DEBUG("LED_STATUS_OFF\r\n");
, Q9 y0 g3 ~8 @% u - vTaskDelay(500/portTICK_PERIOD_MS);$ p/ h3 n3 }8 ?# ?
- }
{2 [% b4 W/ ]0 w - }
' T+ K$ F) S- w8 [# V2 t2 Q - & R! K" j/ r1 z3 f+ U
- int main(void)" z1 M0 d3 N8 K" {; m/ B( Z
- {9 E, Y% B8 L. |2 K* B. ~5 x
- led_init();
: I6 K; v1 T3 h5 ~7 n% P0 j - ! v. `/ V1 z* F) X* l: y
- xTaskCreate(led_task, "led_task", 1024, NULL, 20, led_task_handle);
# P$ \8 R c* P/ z6 O7 b2 `1 d6 l; { - ) E4 k/ p( U& y3 o' `+ d: e3 V b2 D& g
- // 开启调度
7 u+ s5 E7 Z6 {8 \0 n9 | - vTaskStartScheduler();
+ z+ @. S v! c8 I, G+ [9 s - while(1);
8 _! J. G3 Q/ x* z! Z - }
8 B, a8 R& K" p9 Z - # M1 y" w! @6 ^
复制代码 * R' j" J+ p$ |1 x
' L3 p6 L+ A) N- t0 n! q. \1 v6.完整工程
; z7 t. M& p7 R) V亲测可用
8 l ?& K( N# s1 y- f3 J( J
4 u3 A4 X2 e: l' h L/ O
: K( S! o! X0 @
3 ]+ S. u6 T; V8 s
————————————————
& U( N# ]4 E7 m% w) K! Y( Q版权声明:无聊到发博客的菜鸟6 ~, \( x/ G. q
如有侵权请联系删除, N3 F( Q( }( ?! q' g" O
6 L5 |3 K7 [9 e$ d+ `; K" Y. U/ y) Z R0 k5 B0 y) v M6 v, H- {, X
|
完整工程呢???