01. 概述
3 ?6 r; o- B/ j8 U4 ]8 MFreeRTOS中创建和删除任务API函数的应用。
. i" U$ @5 p( l- M, F/ P% I% T, R: W, R8 \3 Z$ v0 f
02. 功能描述& u0 k( n8 P1 m" F+ O8 e: z
设计三个任务:start_task、task1_task和task2_task,这三个任务的功能分别如下:) p! @% ~9 ^6 F5 k
- ~0 u) u u, Ostart_task: 用来创建其它两个任务。; c$ x% x$ ]$ A" ^/ G- d% |+ B/ b
# J+ L1 T# p3 m% k2 Etask1_task: 当此任务运行5秒以后就会调用函数vTaskDelete()删除任务task2_task,该任务控制LED0的闪烁,并且周期性的输出信息到串口中。
* G- @! \9 W3 ?3 A g7 m' I7 z" I# g a, ^/ ^
task2_task:普通的应用任务,此任务控制LED1的闪烁,并且周期性的输出信息到串口中。
# | z, E$ t$ [" O1 h1 ?9 R: D \8 [- S* S2 p8 |
03. 任务设计, z& k% o" f" s: t" Z3 G" X3 v
任务优先级,堆栈大小,任务句柄和任务函数
: }5 X+ E8 v4 O9 C" o; i3 L: O. @3 W9 X7 Y5 {- T q0 f
- //任务优先级7 r3 t7 {* B. v2 H2 E
- #define START_TASK_PRIO 1( ]/ V! O0 W- \3 a/ G/ ]/ {
- //任务堆栈大小 : ?! }, K2 t) i U$ l
- #define START_STK_SIZE 128
, ]; j6 v% E1 l6 o. M4 A: x - //任务句柄+ L+ _% |* u0 I+ R. P' ^+ J
- TaskHandle_t StartTask_Handler;% I+ u0 v4 w: @ y
- //任务函数
, W7 N, h9 f: y8 O3 h" ^9 o - void start_task(void *pvParameters);
/ g* s+ L+ x6 @) N - 7 z% |5 x- o# k0 ~1 r
- //任务优先级* h8 x9 o! B0 l; V* g: g
- #define TASK1_TASK_PRIO 2% U6 b5 D/ T4 K# B7 j$ D, f
- //任务堆栈大小 ( V( i. {* C$ |; I9 N" \- }" t! g; j
- #define TASK1_STK_SIZE 50
. k) @" M6 z# w5 o8 N1 {/ e# m4 M - //任务句柄
# W9 F# N4 g. g; p1 }# k8 S - TaskHandle_t Task1Task_Handler;
- E! i- U d+ q- N% u - //任务函数4 V- |8 z: k _! A- O
- void task1_task(void *pvParameters);
1 R- u& w7 g5 { m
+ r; R1 O5 n. s U) L" W3 Q- //任务优先级
: ^" N1 U/ L2 B7 y' u - #define TASK2_TASK_PRIO 3
5 f7 b$ v' X3 g9 x! b0 j1 ?1 X' Y - //任务堆栈大小 + \1 P, b q# i: O9 c$ @$ ^
- #define TASK2_STK_SIZE 50
" o" ]% v3 p/ f - //任务句柄* r% H5 V1 P! y* K6 h# M
- TaskHandle_t Task2Task_Handler;
$ s6 Q1 p2 B: ^* m* J: Y- V - //任务函数
6 i' N3 [/ G, J# O8 a$ V9 ? - void task2_task(void *pvParameters);
复制代码 : `9 p# k4 y/ L" `# ?
start_task函数4 M0 K8 p9 Y% p% j
5 ~5 q* ?# M3 T X5 n3 _- //开始任务任务函数- E' a) [ j5 d5 S
- void start_task(void *pvParameters). i$ R4 y( r4 e. e7 v" q+ I
- {
; B' c1 C: _) n/ d% Z& m7 M - taskENTER_CRITICAL(); //进入临界区, x8 f# r, M" s
-
. j* B* p9 J- [' G! |( ~ - //创建TASK1任务
* F9 S% y2 H; D' h. ^9 z" C) q - xTaskCreate((TaskFunction_t )task1_task, 9 V7 m7 x2 h- W" L
- (const char* )"task1_task", ' b" ^9 a4 T0 I
- (uint16_t )TASK1_STK_SIZE, 9 m; w4 |8 U: e+ y
- (void* )NULL,
9 p% l9 g( o J5 [ - (UBaseType_t )TASK1_TASK_PRIO,
. O0 x, l( F4 V+ `( Z - (TaskHandle_t* )&Task1Task_Handler);
s6 N. m. S& G3 [& @ - //创建TASK2任务
# h+ p' p) U% }' ~( C* { - xTaskCreate((TaskFunction_t )task2_task, 8 U; V1 p! t* ~2 U$ c3 A( J( R' W3 y
- (const char* )"task2_task",
$ w* ]) Q6 a6 j! _ - (uint16_t )TASK2_STK_SIZE, # A m; U% @+ Z3 n4 k/ K0 I+ h9 v& s
- (void* )NULL,
! l6 L; u4 a2 f0 m8 A - (UBaseType_t )TASK2_TASK_PRIO,: M$ |/ Z* F! ^
- (TaskHandle_t* )&Task2Task_Handler); 6 W, g4 @7 o- p: h( _4 l! v8 L
- * r9 D. N7 Q C# W7 j5 O
- vTaskDelete(StartTask_Handler); //删除开始任务2 T) U/ ?7 z9 J# l
- % J. ^& T' M( T
- taskEXIT_CRITICAL(); //退出临界区! w# Z6 v2 W5 p8 S$ U
- }
复制代码 ( x; p" D* b6 p- h* f
task1_task函数
7 A D8 A4 ^5 l) }+ i
5 I% \9 M0 y, j/ k6 a- //任务1
- i% y3 J" T2 i( E7 a# Q - void task1_task(void *pvParameters)
' x! M3 k+ X+ y2 k5 v7 P - {
" L/ K& `# p& u+ U- s - u8 task1_num = 0;7 M, g) ] L+ ^& E- I
-
- C% Y, g7 v4 b( Y - while(1)
% H4 t( t% y2 J0 E- o - {: @5 M1 K+ D0 ?) T6 S
- task1_num++;
+ _1 y8 I e# Y5 L' M, x2 k - LED0 = !LED0;
2 Y( v" E8 K4 t0 r - printf("任务1已经运行%d次\r\n", task1_num);
3 }6 \7 \1 S' P' i -
5 S: s% _! |0 } i# t1 e0 h8 m3 O - if (5 == task1_num)* Y; o7 [4 K) k ?& T3 ]0 q! P2 T
- {$ f! b. q1 |% c. A/ k
- //任务1删除任务2
4 S% U" a4 l: _8 D8 V& ]) y - vTaskDelete(Task2Task_Handler);& H9 L: J1 f1 S% X+ l
- printf("任务1删除了任务2\r\n");
1 J$ f3 ?. a$ a; r - }* P( X5 ~5 j: N- Y5 a3 C
-
- e4 [, R5 s" W) `, }) W - //延时1秒 1000个时钟节拍3 v: f; z% n# K1 S3 s& }) _
- vTaskDelay(1000);' U8 k- n2 t' q+ A1 a! o0 W' Z' e
- }7 t* w a4 r: p7 O! N
- }
复制代码
# P5 t5 ^, O) Y M4 b5 G+ `' Btask2_task函数) f1 O8 ]4 k& m- `/ k& r4 R5 `# @
- {- H6 x# Q& `" c+ Q0 I1 e2 r- //任务2' O0 w6 v8 O. H( z% k5 o) F
- void task2_task(void *pvParameters)
7 T7 D: G x& x. A# l - {" v/ b. s* R/ o( N3 Z2 j2 \0 y% f: A
- u8 task2_num = 0;* N$ O* t& D! U
-
6 j1 f4 w+ m4 E: ]+ t' I0 P" r& ?' q/ i - while(1)+ q' d( s- S5 }+ @" x/ n6 s$ ~
- {. L2 M. d2 ^0 J: U5 z$ q2 h3 z
- task2_num++;
. z" a! b5 v Q4 L - LED1 = !LED1;
: k4 [8 ~7 ]1 V2 B0 C* z& t - printf("任务2已经执行了%d次\r\n", task2_num);
" C2 W( p$ {0 Y! m* q# n0 m, P: V -
4 C) O1 P3 y- U8 R! Z2 z' _% j2 A - //延时1秒 1000个时钟节拍
$ g: H$ W4 i W - vTaskDelay(1000);
1 m! F& L# K4 Y; I0 f$ w5 Q! }- a - }8 C1 E, X% X+ r7 g
- }
复制代码
, O% s; ^& t! O/ Q' R6 L0 t7 G04. 程序设计
2 J$ l1 f; ?4 G2 k' Emain.c文件
3 \. S7 ?/ _7 g
: E- @* ]2 a- `, A! d- #include "sys.h"7 S3 H- u9 l$ Q8 L
- #include "delay.h"
& y/ z0 {' f7 M$ x9 e1 Z - #include "usart.h"; Q! Z" v4 r' w- [
- #include "led.h"
4 @" J y4 U! p& ? - #include "FreeRTOS.h"
9 p; z+ X4 j, ^2 l - #include "task.h"
, g: m' f( L# b - 4 M% U; i5 r- R' f5 ^' w
- 4 S, `: {1 j& X- ^
- //任务优先级3 P6 i7 |' Y. k K2 }9 L
- #define START_TASK_PRIO 19 z3 y3 F" C# r0 t. x Q
- //任务堆栈大小 / T1 d9 m' t! r, P) ?1 Z8 k
- #define START_STK_SIZE 128 . ~* n$ |& f) ^: p( F
- //任务句柄5 H. ~# S) x0 a2 m+ I6 s9 d. i' Z" y1 ^& \
- TaskHandle_t StartTask_Handler;. D3 r* \: P7 C' F
- //任务函数9 Y0 c2 n- Q/ K% f0 T; R
- void start_task(void *pvParameters);
" ]$ K$ I! A, q" b! Z, j" o! R - ( d& M$ g" N7 e5 F% {. R
- //任务优先级9 W' s1 U) a4 ?- [3 n
- #define TASK1_TASK_PRIO 2
) a; L, g1 i! w - //任务堆栈大小 Q7 u& c) }/ s. ^ _
- #define TASK1_STK_SIZE 50
# a' Z: C1 j/ o: A5 D - //任务句柄
/ D& T- E3 ?$ u& r0 P - TaskHandle_t Task1Task_Handler;9 I: I0 t1 w! z
- //任务函数$ M+ A' M3 B& f1 F3 _
- void task1_task(void *pvParameters);' w) U* i3 p& K' W8 X
- ' q4 a) C' E% G; o
- //任务优先级
) p$ u- _9 |$ k+ k/ _0 ~7 b - #define TASK2_TASK_PRIO 3
0 ?9 [9 i% x+ D6 P+ \* h' ?, @ - //任务堆栈大小 ' ~6 \& o! M# F: `/ g& G
- #define TASK2_STK_SIZE 50 1 u3 e" a2 D- {
- //任务句柄
, y' \* [, w+ |9 t( \/ j - TaskHandle_t Task2Task_Handler;' M) c9 s5 ~- b. d
- //任务函数: n! U d |- C- T: m4 e! R
- void task2_task(void *pvParameters);% J' }5 F! @" z1 R
- 0 j- l$ |- s0 O6 R! E
4 l# P1 a1 c$ E/ t3 {; e. o! B+ W; o- //主函数6 K' o* n8 \7 Q2 A& C2 m- m7 |/ k. ~
- int main(void)
+ o/ T4 Y3 H; K; R! }$ o6 i - {
) M! `2 ]& n8 j - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
$ Q1 |4 q" G0 h% G - delay_init(168); //初始化延时函数 ` M4 w7 \- C; }; S
- uart_init(115200); //初始化串口4 \3 J7 m4 E5 @* L) |
- LED_Init(); //初始化LED端口. H& [" F; ^) p! q2 M9 ^" q8 u
- , }# n3 {% y" G O
- //创建开始任务7 r9 W& y3 G4 K z6 d6 i
- xTaskCreate((TaskFunction_t )start_task, //任务函数
+ T7 P; m- p) s4 i' { - (const char* )"start_task", //任务名称
, W# R3 I1 q* {7 ^ - (uint16_t )START_STK_SIZE, //任务堆栈大小
0 G) ?/ N$ y7 Y8 u - (void* )NULL, //传递给任务函数的参数
6 O2 ^ T& o! r - (UBaseType_t )START_TASK_PRIO, //任务优先级
8 }. f$ T% o. z" ~" c7 {; }" y - (TaskHandle_t* )&StartTask_Handler); //任务句柄
. n: P9 F" J( Q$ n- a% ^7 w7 H - vTaskStartScheduler(); //开启任务调度2 a# a( R, R# [: j
- }
5 f u8 T# H$ I+ @6 u* t
. e- h$ w- u2 z. v1 f9 m- g- //开始任务任务函数: Y @/ q6 M9 p1 R) e
- void start_task(void *pvParameters)
% }5 r6 \9 d' g* T! D - {- o) r' ~6 u3 h4 U) a9 Y
- taskENTER_CRITICAL(); //进入临界区! A* ]( i) c7 V# `) \7 F/ C
- ! p3 u% B8 P0 P4 X3 K, e+ J
- //创建TASK1任务
! r2 v9 Y V* R - xTaskCreate((TaskFunction_t )task1_task,
3 m# [% n- v- R1 t4 R+ l - (const char* )"task1_task",
/ o! Y9 Q/ N4 O% F/ L F - (uint16_t )TASK1_STK_SIZE, : M) Q, g/ U8 U9 j
- (void* )NULL, , L" ]% h, ? B; S7 l
- (UBaseType_t )TASK1_TASK_PRIO, ' z m& P% i1 z* ?2 Y' ^6 j; [
- (TaskHandle_t* )&Task1Task_Handler);
1 ~ y8 a2 B0 ~0 s4 J1 `. J - //创建TASK2任务
4 j; T( B* J) V/ Y - xTaskCreate((TaskFunction_t )task2_task,
0 C/ K6 \5 Z6 _5 Y# q7 Z c - (const char* )"task2_task",
: A5 X* A1 }7 Y - (uint16_t )TASK2_STK_SIZE,
( j/ Y, x0 g( j4 L% T" j - (void* )NULL,
3 R. s1 u1 v$ l! D - (UBaseType_t )TASK2_TASK_PRIO,3 V5 V7 Z6 o! H/ P8 g( K+ K
- (TaskHandle_t* )&Task2Task_Handler); 7 \7 T% y; K& ^% K% A# ~2 H
- # [9 u. u! k( K5 M
- vTaskDelete(StartTask_Handler); //删除开始任务( t# s; w+ p/ }
-
% z. n! j& `7 d' m9 F7 c' ]) k - taskEXIT_CRITICAL(); //退出临界区7 V' C4 y: t% a1 s
- }
. C5 p$ H4 ]0 t- ~! l! f - ! ~% H7 ?/ B A! _9 w
- //任务1* b8 \0 v1 B! [2 s5 @
- void task1_task(void *pvParameters)6 J. ~, x" h, T& L5 H5 f
- {
- L( T" t/ L- f+ } - u8 task1_num = 0;9 Z0 t7 H. O: I% |1 ?- U: H
- 6 n7 H, p) ?& S4 ~; c+ }4 t
- while(1)
; \. d x6 }! B; z6 J2 z+ o' }# R - {
/ S' {# w9 u9 v' R6 o Z$ b - task1_num++;
& H' H& O% s \2 v( \ - LED0 = !LED0;
! y& n' O1 A$ X* b' D9 e$ t - printf("任务1已经运行%d次\r\n", task1_num);% s: ^% M. Z# f8 [' {
- |6 [) X5 \/ a# L0 q
- if (5 == task1_num)
+ ~: O( }% t% J; \+ g5 U - {0 [0 P1 I: l ?# _& ~4 ]
- //任务1删除任务21 f5 y2 ~( C/ Z6 R! w: N
- vTaskDelete(Task2Task_Handler);* E( Y; V: g# y- }3 t: [6 d; Y
- printf("任务1删除了任务2\r\n");2 Q: V0 _7 V6 a8 N) ^5 t k
- }
$ s' r. Y; k: t/ V7 w$ Y; j% C, L2 o - ' ^3 |8 E4 x4 \2 W
- //延时1秒 1000个时钟节拍
: f2 D5 A: k Y- D - vTaskDelay(1000);/ k* P6 H3 g3 E' y& K
- }1 u5 `" i. l2 Z$ `2 ]! _1 r
- }
* u6 U* X) y* |1 [ - 5 O5 f( K0 G( o4 [% P/ X- X
- //任务2- U$ k0 `. `. c. z' R" j% W
- void task2_task(void *pvParameters)1 ~. X; n" g m
- {
& v4 J$ m5 K" y, S/ O - u8 task2_num = 0;
" E% l" p4 G" U. v! V0 P4 f1 t -
. ^; [. {* J" g- K0 D- J - while(1); h6 W8 ~# b. a, M0 _8 c, A
- {5 \9 Y$ V+ A8 d; v) G6 \
- task2_num++;7 r, l4 M& _3 K& _+ E, T1 U8 G) G
- LED1 = !LED1;
, ~& Y f3 v, Y4 L* a& M2 G; T+ X - printf("任务2已经执行了%d次\r\n", task2_num);
6 c9 [+ r5 z( ] -
2 o5 g v. d- `1 h - //延时1秒 1000个时钟节拍
# l0 T7 [5 ~3 L3 P% I+ b - vTaskDelay(1000);
h, ^1 M+ S. y! E - }
8 Y- y0 U( t7 H/ I3 {9 e+ O$ V5 v - }
# Y! _ R& p8 w( k
复制代码 * l+ U+ f" P4 v0 w A5 U1 }" k1 v7 m6 w5 |
! v/ @% o9 ^: B |