01. 概述% R3 `7 u/ p5 Z, v
FreeRTOS中创建和删除任务API函数的应用。3 X, S: ~4 @1 _) ~2 v& u) W( i
( Y, m l; c9 g" B: [: }5 v+ F% ~02. 功能描述
; y: p3 Z5 k. |- J设计三个任务:start_task、task1_task和task2_task,这三个任务的功能分别如下:2 `0 G: J7 a4 s2 w! j: ^& }8 t
. V0 k. Y% \1 p0 wstart_task: 用来创建其它两个任务。
% n5 \" n+ f7 ?: m; O/ L# R1 N
0 c1 `) r1 f9 A6 t2 ptask1_task: 当此任务运行5秒以后就会调用函数vTaskDelete()删除任务task2_task,该任务控制LED0的闪烁,并且周期性的输出信息到串口中。# A/ Z7 V4 }: T+ s4 e+ O
+ R( ]# p: q' p
task2_task:普通的应用任务,此任务控制LED1的闪烁,并且周期性的输出信息到串口中。
- \* `& |2 B. t* L
5 A8 J' c9 r# J# b8 ?- j, n, w03. 任务设计
: M- O/ C' s! f; ] E% |; y5 E任务优先级,堆栈大小,任务句柄和任务函数
% Z6 O5 Y. c$ K" X/ O. g5 ? M$ [( d2 t- Y
- //任务优先级7 S$ l5 T+ A8 l$ y' N3 z
- #define START_TASK_PRIO 1, @- J) ]* T; a) I3 e {& X6 ^4 [+ _
- //任务堆栈大小
( C) g" Q% O* K; F& x - #define START_STK_SIZE 128 , t7 k+ W m8 ^
- //任务句柄
5 R6 j% H- }9 }& ~ - TaskHandle_t StartTask_Handler;0 N4 h1 k$ D! ?, `
- //任务函数9 R0 W5 l/ `! N) d7 Y& Q$ S/ {! @
- void start_task(void *pvParameters);! l" \4 v2 l( H/ ?! F
- 6 }5 N# V1 s4 i
- //任务优先级
" W+ M/ |9 `& { - #define TASK1_TASK_PRIO 29 y1 r" }! Z1 s. f8 Y
- //任务堆栈大小
W; d2 u2 p4 k' c; U/ j5 P5 L( k - #define TASK1_STK_SIZE 50 , U: l) u9 l( `# T
- //任务句柄
6 M. s5 {. M' @ - TaskHandle_t Task1Task_Handler;
) ?# h& T$ t5 |3 c( s8 {& C$ G9 l - //任务函数
# I5 d4 s! C7 t. }/ z8 q - void task1_task(void *pvParameters);
* F, F$ R) t4 i4 `% P
# }! ]- a1 O* _' T, p: N- //任务优先级
# {% _4 T; ]' ]% [# E - #define TASK2_TASK_PRIO 3
# N- B& z# z) U9 G: _/ } - //任务堆栈大小 . d. k2 o$ P5 ~
- #define TASK2_STK_SIZE 50
4 X, j6 z2 I& W6 B- G% y3 D - //任务句柄
! P6 F" N7 j4 a) C# D3 Y' Y - TaskHandle_t Task2Task_Handler;
# L3 \) Y( G, `2 S2 _1 n - //任务函数9 [$ T2 y2 h- f5 e4 Z# U2 p
- void task2_task(void *pvParameters);
复制代码
) W" p$ [% c/ e* x8 W. q! J4 Ostart_task函数
% I8 i# t3 U- j$ {" o) Z8 e- E
$ a2 K2 T# f9 B a0 w- \; U- //开始任务任务函数( ^5 ?* z0 K; {7 Q
- void start_task(void *pvParameters)+ f+ N- M+ f- C1 w
- {
7 _2 Z% J, }' [8 X* Y - taskENTER_CRITICAL(); //进入临界区4 `3 K @. \" P6 F
- : g* j7 x* `7 l% t# s. b
- //创建TASK1任务
& y! L+ X: a: u - xTaskCreate((TaskFunction_t )task1_task, 0 l9 r; L* M9 _6 }7 b" b2 }
- (const char* )"task1_task",
7 @& m/ A. F* J/ e# S% G - (uint16_t )TASK1_STK_SIZE, " A# ~) ]/ I; @& v% F' W9 G4 p
- (void* )NULL,
3 |- R8 F8 O$ w8 b - (UBaseType_t )TASK1_TASK_PRIO,
0 X- s4 J7 a8 N6 E: j# N$ J - (TaskHandle_t* )&Task1Task_Handler); ! s! g) @( ?0 _7 X1 B
- //创建TASK2任务: W+ W4 x4 Y0 t. O% q
- xTaskCreate((TaskFunction_t )task2_task,
3 X3 A. k& b/ U( L/ v, \4 h8 } - (const char* )"task2_task",
7 p5 C% A1 S; D6 V( L* ] - (uint16_t )TASK2_STK_SIZE,
; s! D0 z+ ]7 U8 `# ^* q0 p - (void* )NULL,! V) j; c& T6 ]0 s+ Q B
- (UBaseType_t )TASK2_TASK_PRIO,1 f8 O, M: S ?# `# I- k+ h& Q
- (TaskHandle_t* )&Task2Task_Handler);
7 d3 Z/ B6 Q6 g5 b4 p x
; `) N8 z8 X* V# n- vTaskDelete(StartTask_Handler); //删除开始任务
6 C: e A0 Z# L# J. P+ n -
2 Q8 A3 r: J" S! b; |6 n, S - taskEXIT_CRITICAL(); //退出临界区# v0 c6 ~8 \2 c1 K; D/ q P
- }
复制代码
+ y- m2 \& L/ {% z' o* H6 y }- Itask1_task函数
. M' d4 S9 p; y
9 |, ]# j: k J& P4 ~$ |/ N- //任务10 B+ h# c- { U( T% L
- void task1_task(void *pvParameters)
* v& m+ E9 e4 Y - {0 z$ s4 M% |7 A R8 o1 T
- u8 task1_num = 0;% Q7 p9 U- C& F" P: \- v
-
7 w( b/ q' Z! x& B - while(1)
" B' I. ^, m6 ~* k - {1 A6 p3 b G8 _
- task1_num++;4 ]( L J/ n+ L$ R2 Q7 d9 D
- LED0 = !LED0;
( j4 j/ d, r/ a! a& Z% }5 O& e% d - printf("任务1已经运行%d次\r\n", task1_num);& |3 t: c; p. w
-
6 C5 k0 Q$ F! N3 _7 j! \ - if (5 == task1_num)
3 K, _# i/ D5 H - {
n! _9 z5 y9 B! K \# ?! T: \; p - //任务1删除任务2
) T3 t' G( J7 I& i - vTaskDelete(Task2Task_Handler);
2 F0 n+ K5 r+ q, f& P. B1 E0 u. b - printf("任务1删除了任务2\r\n");
$ S- |7 F. J) X+ S6 `* |8 l - }8 J# E: j# D7 i7 F' \, B! ^8 f
-
+ d- |9 z. v) u! `9 j - //延时1秒 1000个时钟节拍8 k7 j, i* ^8 V4 f
- vTaskDelay(1000);
! n1 N) k0 z+ X* L) ~ - }2 d8 w, k2 T6 W/ ~% g
- }
复制代码 . L& N6 M. A2 m- E" s
task2_task函数
: r0 o$ D1 \0 V$ |3 S0 g/ t9 _ I# k9 w1 `8 M# H$ v0 O$ Z
- //任务2, l7 h; S4 @$ [7 F( P9 ^) K, p
- void task2_task(void *pvParameters)4 P6 z3 j% E* b+ @: f) f
- {
8 ^7 V0 k( b+ Z, z8 y7 m) U - u8 task2_num = 0;
0 t) g& O. g6 X8 B6 {+ X# O$ o0 @ - ' [9 ^* X1 o( l9 {
- while(1)
+ ^* Q( D z e9 m - {* R1 T* e2 E0 F
- task2_num++;
1 s) g+ B9 H1 l7 W2 w3 G - LED1 = !LED1;
0 c- v# |& G1 }4 ^: p) w( g - printf("任务2已经执行了%d次\r\n", task2_num);: b% y3 G' p, D# t4 c: B
- ! K( L2 |9 ^+ H
- //延时1秒 1000个时钟节拍) N# x o3 x- G! {+ \6 f% f
- vTaskDelay(1000);8 n( F: i! R8 B, Y& m
- }5 K+ n X; q' Y' L* [3 u
- }
复制代码 % G+ M; ~, h$ D6 B4 }9 k- ^0 Y
04. 程序设计% `. A4 A$ D" a6 M" j; o" f
main.c文件: f0 x, `. u1 A/ T, m
; w1 Y6 C$ ?' y3 Y B( E3 o- #include "sys.h": d' s' u3 n3 @# z3 v! M
- #include "delay.h"
$ Y6 k) B5 k) s( X - #include "usart.h"
# g, o i) Q, ]4 D4 d0 | - #include "led.h"( h+ e* @1 Z% x9 S w
- #include "FreeRTOS.h"
2 ^* Z4 Y9 W" b, w0 o - #include "task.h"
0 r) J; [; I d6 @; S
: h( R9 I( Q. N$ C4 F- / u& m( Z) H g
- //任务优先级1 z5 v- h* o9 a/ y. U- d3 r
- #define START_TASK_PRIO 17 i7 B2 [1 d* D: G! _
- //任务堆栈大小 ( `) G3 A# b) {4 h" [9 X
- #define START_STK_SIZE 128 0 A4 x9 u0 g/ u1 }
- //任务句柄
+ s7 p( ^# }. w$ A# n - TaskHandle_t StartTask_Handler;$ j* I u! V1 M' W4 w7 E/ f
- //任务函数
2 g% P; l. F$ P5 _5 ^% F - void start_task(void *pvParameters);
. \% F: ^6 G" }2 F( x3 l: f
' s3 ]5 x% ~5 v6 E; ~7 H! i- //任务优先级; I3 s6 Q' g+ L
- #define TASK1_TASK_PRIO 2
5 D8 Y1 u9 b2 ?% ? L6 i" Z, t J - //任务堆栈大小 4 h5 P- r2 T) [9 u2 q; k
- #define TASK1_STK_SIZE 50 + T% c2 @$ `4 j- T9 L
- //任务句柄: V! M. O0 z1 i6 \2 _5 {4 B z- ?1 L1 H
- TaskHandle_t Task1Task_Handler;
# M! T9 }+ m. w6 Y' m0 }" b - //任务函数
( k: z" z) V7 J3 q$ J+ ` - void task1_task(void *pvParameters);3 d: f! q8 X7 W* y. v' ]% [* S) A
) Z4 K* n+ b* o) i- ~; A* M- //任务优先级
/ u* H; n- B$ G" H/ d4 H - #define TASK2_TASK_PRIO 3' B5 _7 n( }/ c5 S4 N- w
- //任务堆栈大小 7 M" B$ U. m& l! S2 x1 p
- #define TASK2_STK_SIZE 50 + ^. @1 S) v! @* Q* b6 @0 w( X7 o
- //任务句柄# d. F; }6 S; `( V
- TaskHandle_t Task2Task_Handler;( ?# D: b: Y, O0 |' J3 Q, T4 B
- //任务函数
8 L9 E, z3 @7 @# O5 o3 \ S - void task2_task(void *pvParameters);
8 Q1 g* S4 ?6 o
4 B& b/ \: h# R: E7 Z- " q9 L' _ g! p/ j
- //主函数5 r: U: P+ A6 ], |. ]( A: m
- int main(void)
5 Q' ~ u4 t" ^) }* Y! e - {
. g) L3 X" k3 v* E# U% V - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
+ i7 m0 f0 F+ N/ W T/ _7 F! } - delay_init(168); //初始化延时函数+ Y* R# `$ x' l+ G7 ^# N, }+ Q
- uart_init(115200); //初始化串口. b9 B8 i4 Q8 r- X/ K' Q; D) I
- LED_Init(); //初始化LED端口4 O% a+ y1 V$ w+ B& {) B" l" f
-
, h! y8 V; ^! c - //创建开始任务: Z3 A4 u- C1 W( w
- xTaskCreate((TaskFunction_t )start_task, //任务函数3 }* U. E/ c5 ~5 K T" P
- (const char* )"start_task", //任务名称
7 Q% B9 w. U- P1 D - (uint16_t )START_STK_SIZE, //任务堆栈大小
" i& _1 ]! ^% Q& ^7 {+ y1 A# t: H - (void* )NULL, //传递给任务函数的参数
0 `# k, ]0 m0 ~; R5 u - (UBaseType_t )START_TASK_PRIO, //任务优先级& c# @& ?/ x! u& X: u
- (TaskHandle_t* )&StartTask_Handler); //任务句柄
. w5 W8 v& w) c. z8 I" c7 E) A - vTaskStartScheduler(); //开启任务调度
" i5 _& O* ~' ]8 h. d# S6 X - }% R( B2 P8 f9 F
- k j) u s/ Q: |- ^9 l# l
- //开始任务任务函数0 ^2 r! w ~% N9 y* S/ O9 Q
- void start_task(void *pvParameters)0 R3 b6 u5 c) v" ^2 M
- {& {# {/ V! }1 k5 s# A! S( g8 N% u
- taskENTER_CRITICAL(); //进入临界区
- O" k& f9 @' |6 p7 N2 j D" m -
9 Q+ T, [, n# g7 @2 R7 O - //创建TASK1任务. s2 Q' d& L' D
- xTaskCreate((TaskFunction_t )task1_task,
3 n6 y$ W/ Y6 e - (const char* )"task1_task",
9 U9 ^; s7 c# r* P1 l" J - (uint16_t )TASK1_STK_SIZE, 3 b& _# B; S) _3 y& x8 v
- (void* )NULL,
4 c" k& J F. n; X - (UBaseType_t )TASK1_TASK_PRIO,
" N, B1 j: d+ d& A* m; v - (TaskHandle_t* )&Task1Task_Handler); ' i( K9 R* |2 l- f
- //创建TASK2任务
# N8 ~ N. b$ Q, W: ^5 {' I2 b# E - xTaskCreate((TaskFunction_t )task2_task,
" d$ A% R+ p! G5 Z - (const char* )"task2_task", . G5 e2 |3 w, S! G
- (uint16_t )TASK2_STK_SIZE, # s7 s6 g$ h8 y& f. c: S
- (void* )NULL,
" @" P$ I2 v* ~% ~( G - (UBaseType_t )TASK2_TASK_PRIO,6 Y' Y4 c+ G6 D3 D) z# j* D$ i0 _
- (TaskHandle_t* )&Task2Task_Handler); 2 p# Z! `: j) _9 d/ Q1 }
- . x1 D. \! N0 b9 S2 `: J
- vTaskDelete(StartTask_Handler); //删除开始任务
6 ~0 `7 k2 e: A* |1 R -
1 r+ h9 B4 k4 L+ a - taskEXIT_CRITICAL(); //退出临界区
; _ Z5 b( k; U0 L - }
) h& ?# Z( k1 j+ K
. o5 l6 r) x1 }$ I- W; h- //任务1! {4 N0 R% ^( _# C- U
- void task1_task(void *pvParameters)
2 O9 Y1 F5 r' G/ Y- G - {
2 d; N! B! ^/ _5 D( D+ H: i9 ? - u8 task1_num = 0;1 `% i" g8 g' D b! N
-
% ~/ k: [7 K4 M, D9 ~5 R - while(1), {2 R2 Q# x4 \# w. h1 J0 w
- {2 f) P7 l, R2 k! ?
- task1_num++;
: S5 l/ v8 {$ y- X4 d# U+ I - LED0 = !LED0;
+ ^6 z2 H# b( _- t( p5 Y - printf("任务1已经运行%d次\r\n", task1_num);
# G1 e& V9 [8 }* }/ I; T# Q7 E -
0 r' p+ I+ W6 s: J4 Z; f - if (5 == task1_num)' {3 ~+ S! ?8 @0 B; e
- {
+ Q9 S2 [8 y0 M# n8 x - //任务1删除任务2
, r: _# @6 \- K. G( M- A - vTaskDelete(Task2Task_Handler);
) P, d9 A% E2 i - printf("任务1删除了任务2\r\n");
, i: [3 B. E. p/ y% S& f - }
9 c# S4 t& D7 W7 R4 c -
: P) m$ d8 H/ t: a% i6 F( O - //延时1秒 1000个时钟节拍- X- R2 a0 ]4 U- p( f l4 b
- vTaskDelay(1000);( l3 i- ], e& L3 f0 p! i
- }
8 n; j6 Q% M8 [) J - }( x- q; `" v/ r; v: \4 E+ X# Q
- 3 e2 a8 ^4 y) H) b' Z9 ?
- //任务2. I/ V; Q2 v8 F+ X" u" e, T
- void task2_task(void *pvParameters)/ K. ?; Y6 S3 g- p( g9 D1 X8 Z
- {
7 [7 { A# M* |. I3 J% g( a - u8 task2_num = 0;
* ~6 {' ?# a! F4 f3 h. ? -
" O) p( h+ G' r/ K; c4 d - while(1)( |6 y. @" `" b! u3 Q0 q% X n
- {3 z3 X( J4 F5 |& s& A* L
- task2_num++;6 Z) _5 Z2 N8 _% @/ o/ t3 U; t, j- @, B& {
- LED1 = !LED1;
: H1 X' S8 @0 n$ W) }6 x' d - printf("任务2已经执行了%d次\r\n", task2_num);
- J& P4 L1 i, A5 o/ v# q; _ -
0 H" c: M# p1 { X) i) l - //延时1秒 1000个时钟节拍& l3 B, w3 [( q& K: A
- vTaskDelay(1000); `4 a* x6 d9 P- h" }. E0 C
- }
; N* E5 n: v5 D) A - } g1 ^' p3 ^$ [4 X g7 [6 }
复制代码
8 l+ x( | B7 j0 d* b M! C' }05. 结果验证! T/ g# p0 e2 j* s, P% ]
任务1运行5秒中之后删除了任务2,任务2被删除之后就不会被运行。最后只剩下任务1运行了。
! M: _% R7 h* f U; j9 m
0 t2 p8 d9 I* U" X2 ]
7 e' c! k& K" n5 ] |