前言 _# H7 ~; I7 t( h
演示STM32F103移植FreeRTOS完整过程,文末提供移植好的完整工程
U- ? P( _; S6 X" ]/ R
! I& }' t" J( i5 t1.下载源码1 F+ F) _( ^4 ^+ h% h
下载FreeRTOSv9.0.0.zip解压如下图1 d; p7 R( b( u
4 _: S* R- Z# _, n- a9 J4 f1 i
1 C+ V( T ]0 {
& M" d* N3 U/ A9 q4 P% B只用关注第一个文件夹FreeRTOS中的内容
G4 h# |; j1 V' Z5 q3 E; G
1 Q0 e( p) a/ C2 i/ M
/ f. ?1 U6 ]) F4 `$ w
8 }. o* o, {, |, V& Q; UDemo是官方提供的常见芯片的移植示例,包括STM32F103,我们需要用到其中的FreeRTOSConfig.h配置文件。- Y) u' L; U3 d$ O3 X
Source是源文件。- v1 q* n: h8 K3 @: N
% O' H6 l. @" d: C& u( L3 f' e2.拷贝源码6 V* ^' \1 Q Q8 E1 x2 x) J
在工程目录下创建FreeRTOS文件夹并创建子文件夹src和port1 O6 W- ~3 H" A( c/ i' G
" q$ T7 e Y$ o3 r% i7 N5 ^- `, |
- o; ?+ }# N0 U
6 {% m- A* ?. K' U# J将Source/include文件夹拷贝到FreeRTOS下
9 M" o: S# \; G1 G将Source中的C文件拷贝到FreeRTOS/src下
) d. R D& O# |! t# B6 z2 {
& q$ k7 n. r. c' ?" V: W: \
+ j/ `% c2 |+ D8 E8 \1 o# v
$ r! d% s1 O9 R) \' D- T
将Source/portable下的MemMang和RVDS文件夹拷贝到FreeRTOS/port下,
' p6 [' Z6 P; `
. j; Z' f! N; }* b8 R+ K. O, ^0 }其中MemMang下的源文件是用于堆栈管理的,RVDS下的源文件是不同内核相关的接口文件。
2 Y6 i; |1 Q( F2 Q9 R( ?7 a# J/ G! {' b
! l ^: b3 y% y9 ~0 C# G5 d) \8 K' ^- u; k- x
3.添加到工程5 v5 A. | z7 E k
/ o- v2 @6 q v( i% K
: P' B, V# @1 u, E! q6 c' S1 A& d
" y4 s* ^4 p6 C3 O新建FreeRTOS/src和FreeRTOS/port组
7 z$ d/ o& z- R
2 J5 _5 `9 n" I' s9 Q; `FreeRTOS/src组中把FreeRTOS/src文件夹中的源文件全部添加& a8 _! g; c* C( E
! }! Y) w! m! j& y' [! W
FreeRTOS/port组添加FreeRTOS\port\MemMang中的heap4.c和
) [: f% W. t9 Z
. W% T3 N' `6 H, i0 r7 BFreeRTOS\port\RVDS\ARM_CM3中的port.c5 {& l" Y: y" L- K, O( P% A# Y
+ S- `2 S+ I% O
, |: Q0 y6 z; Y0 b' D( X添加头文件路径
6 q a9 |$ N, Q# C& Y
6 F- ^) V5 J) a" S: w( ]
+ B) g3 h* Z0 Q" b7 s$ v; i; J& R3 t! [! V+ O
拷贝FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil下的FreeRTOSConfig.h文件到工程
& b; {( ^7 w$ O8 A, v& Y! S
2 Y. R$ K1 M' Q; v* J( s4 E9 p" }" u. }
4.修改配置+ G0 A9 b r' [
在FreeRTOSConfig.h中添加( o$ b' m; g: q, ?& X
- #define xPortPendSVHandler PendSV_Handler
0 d* m* X, V" W% M - #define vPortSVCHandler SVC_Handler5 d# T% J/ }) h# A9 O$ S) M: d
复制代码
: \, g" Z$ R' ?( Z在stm32f10x_it.c中屏蔽PendSV_Handler和SVC_Handler中断
& M' M, }4 `4 K; F; L, h* j# l最关键的一部,修改stm32f10x_it.c中的systick中断服务函数。* h2 x5 e, C, X, @. S& z2 m! F
- /**
- ]7 E3 W2 H: V1 [- \7 p5 N3 ]$ W - * @brief This function handles SysTick Handler." E, z1 R. y- E5 u
- * @param None2 i* f, w! g, h! h9 l
- * @retval None
: K' U; F: A( C# z - */
) K# O0 s" x6 u+ O$ o3 w - extern void xPortSysTickHandler(void);
" l0 n b7 p. q$ k: @% S$ T8 ?4 n% r - void SysTick_Handler(void)3 ~* d- T) F2 y0 p& A% f4 U
- {% t5 j% ~ f/ j9 F" B: {
- #if (INCLUDE_xTaskGetSchedulerState == 1 )8 \) K2 q$ Q [2 v9 r
- if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)$ g7 [; S1 y$ h9 K( C# ~+ c
- {8 \' F: Q% t: z4 w/ |* p1 n7 ~6 ~
- #endif /* INCLUDE_xTaskGetSchedulerState */ . g( v4 `! R' b `) H! _+ k
- xPortSysTickHandler();* b& k+ F, L6 M1 U; x( A, R
- #if (INCLUDE_xTaskGetSchedulerState == 1 )
2 X* F0 t* o/ d3 u! ?/ l7 Z - }
+ o6 x& _8 A. Q( ^. j; s - #endif /* INCLUDE_xTaskGetSchedulerState */8 U2 P* i, l- Y' v) _5 f3 D& t# Q
- }
' t- h0 \% A h
复制代码 , r3 j' U- m* h5 r
5.验证demo0 A @, }' O2 n* J
- #include "stm32f10x.h"
& ^1 k. i+ `! r, B- r. d - #include "FreeRTOS.h"
' a; @5 l) D% P$ _, s) S( H6 d2 q - #include "task.h"
: H$ ^! e: j: b3 z- M - #include "portmacro.h"
' L: p/ g7 R/ i2 E8 V1 M2 q% H( U - #include "bsp_led.h"
6 m! I* v5 y% E/ E0 D2 Q - #include "log.h"
4 ~% q* e6 L3 M
: h7 R) O$ C2 Y( m! k: t s6 }$ h- static TaskHandle_t led_task_handle = NULL;; u7 P7 C0 F/ T2 `, U, S
- ) e2 `7 y- ~- D6 A
- void led_task(void *arg)
2 Q1 x8 l1 B# U. c) I7 m% Z- r7 F - {
9 p% R5 V" o' b/ S9 U# E: I - while(1)
1 J0 ]2 M; Q) Z& y: w7 T! y# J2 d - {# O' R/ @0 j$ I! p! W3 r" o# E
- led_status_set(LED_STATUS_ON);8 B' [* t5 W; _/ x0 z7 s
- LOG_DEBUG("LED_STATUS_ON\r\n");3 X+ P! [! j0 L& E' M
- vTaskDelay(500/portTICK_PERIOD_MS);+ ]" J2 G8 N* t: x
- led_status_set(LED_STATUS_OFF);7 r# L. s% v( C- B" }+ y5 G6 [2 l" b8 \1 m
- LOG_DEBUG("LED_STATUS_OFF\r\n");) s+ S; B3 h$ N3 X! e W
- vTaskDelay(500/portTICK_PERIOD_MS);
/ C7 \: I3 H( V; C' W( C7 V, M" g - }5 l6 w4 l" j& w- s
- }' m( U& y, g" ]% G% h
- + q( p! t" T* d
- int main(void)0 G% A" T( m0 u4 _2 i
- {
( L, {( F3 n# X$ @. [0 t - led_init();
9 g1 O5 {; T+ j& w3 Z
, p/ n: Y# a. [- r- xTaskCreate(led_task, "led_task", 1024, NULL, 20, led_task_handle);8 I! G& s1 b3 O6 L& P3 B; w
4 B" w& F h6 X; d4 k" _, x- // 开启调度# Y# H9 j; L# f. A$ `; e; \! w
- vTaskStartScheduler();2 H+ e% h ^, P% j8 _
- while(1);) |/ Y0 \* V$ T2 v0 |' U/ I
- }, N6 Y- I: g; K1 |/ t6 _) t
- " S6 m# j+ y5 S/ s% ~% Q
复制代码
; R+ o# e, I. h# ], ^+ Z! W( D& p% v& }
6.完整工程
% @0 i/ l+ O+ b; v' B# j亲测可用
4 z6 I5 C( u& C* X# \" p
0 V4 Z( U2 S" t! b$ G
' d9 b0 A* e) w
$ l8 o3 J7 M0 W& `( |————————————————
9 w* q3 W$ G E版权声明:无聊到发博客的菜鸟
* z$ K) z4 @; p# i5 b( M. g如有侵权请联系删除$ J L+ H6 {, L# U0 p1 ^4 _( Q
6 A4 c! {- `9 Y4 h
6 \$ V/ G) r* G7 o7 a$ {8 {7 r1 l
|
完整工程呢???