01. 概述
2 u8 b" ~$ L! y! P; Z2 ^9 l1 fFreeRTOS中创建和删除任务API函数的应用。2 d) h, }! f8 m
5 }' h# X0 ^! N3 F. P02. 功能描述
7 h; \9 g) t" f6 T2 k' ^设计三个任务:start_task、task1_task和task2_task,这三个任务的功能分别如下:
: Y- U; a2 A4 b, M9 G2 [# G/ r3 j. i( M! ?$ n
start_task: 用来创建其它两个任务。
" m7 O- l7 \: R$ x6 s- J( O# X% F8 W# U6 M4 X7 D
task1_task: 当此任务运行5秒以后就会调用函数vTaskDelete()删除任务task2_task,该任务控制LED0的闪烁,并且周期性的输出信息到串口中。, U x7 w7 T7 o8 \$ L8 D
) D) A! n, t# c _
task2_task:普通的应用任务,此任务控制LED1的闪烁,并且周期性的输出信息到串口中。
0 V8 f6 c" s) A9 d7 D$ x x, w
) W& t8 v1 Y% e03. 任务设计% j& V. Q7 H# z- w
任务优先级,堆栈大小,任务句柄和任务函数: t4 G- Z: T! k2 r5 Z
. h% u' l% Y' y
- //任务优先级3 V" E2 T+ q. H
- #define START_TASK_PRIO 1
' Q9 B+ M5 D+ _, C7 W5 h6 r - //任务堆栈大小 . s7 j- j% L: K! m
- #define START_STK_SIZE 128 , n) q3 F4 E$ {9 ]* K) F
- //任务句柄! Q9 c% f- [- y* C$ n
- TaskHandle_t StartTask_Handler;% @" H0 J- J$ Y
- //任务函数6 U6 M3 r2 c+ n3 \ z
- void start_task(void *pvParameters);
- u% Y8 ?8 ?! @, d' u
, n- M8 E+ @# c7 n9 a4 p+ p- //任务优先级" Z4 w6 `7 Y6 F% q% t# W
- #define TASK1_TASK_PRIO 2
8 N5 `6 n# a* J' z, ] - //任务堆栈大小 ) i; S/ a7 b% ~8 w2 [1 V, r5 W
- #define TASK1_STK_SIZE 50
( i6 ? l7 v* x - //任务句柄9 V" ~: h1 a) ]# c+ k7 t) O$ ]
- TaskHandle_t Task1Task_Handler;2 z1 o- Q& n/ {% n: }
- //任务函数
% C' w. q9 z; w) m' A - void task1_task(void *pvParameters);
4 e& [ U' z. l5 H% a$ P
8 o: z& E: k, E. d$ f3 T+ {- //任务优先级- C# W4 X& j6 L6 G" Q
- #define TASK2_TASK_PRIO 3/ [/ a9 p$ ]& G( u- N" y: Z
- //任务堆栈大小 * q$ X+ j5 ~; C, Q! v
- #define TASK2_STK_SIZE 50
0 k( r9 F) h, ~0 k6 G4 N9 p) }- E* @ - //任务句柄; o+ P4 [3 w# L" K, s
- TaskHandle_t Task2Task_Handler;
" o n% e, g7 B$ E: i# V - //任务函数
1 b9 v) i9 n( c( E - void task2_task(void *pvParameters);
复制代码 ' e$ `& q1 ^: o# a& a* _& Y
start_task函数& A3 y- }1 A* y0 p
" o( R* |' X) ~, m/ x; p
- //开始任务任务函数 A4 a2 m: Q% w$ H0 @ H8 C
- void start_task(void *pvParameters)1 R! N1 }, |' O' x) X8 M
- {( B S$ F6 F7 V4 x W" a9 X
- taskENTER_CRITICAL(); //进入临界区 Q+ Q, q% \0 D; B6 e7 y0 d
-
# _% E7 i( b3 C - //创建TASK1任务 _1 L! B& S; h. w8 d1 O6 O( v
- xTaskCreate((TaskFunction_t )task1_task, & M7 k. Z2 l) X6 W
- (const char* )"task1_task", 4 w1 m/ K+ j3 M4 G9 Y+ O
- (uint16_t )TASK1_STK_SIZE, - g8 D) l' I& b$ J$ D
- (void* )NULL,
8 o! b/ X& u2 ]6 O4 E5 q - (UBaseType_t )TASK1_TASK_PRIO, * g; U/ B4 d" v6 @
- (TaskHandle_t* )&Task1Task_Handler); 5 F4 {: g5 A7 B3 J0 S+ G. i/ b
- //创建TASK2任务* X. G3 S! j0 j( J& X( Y
- xTaskCreate((TaskFunction_t )task2_task, , J U! Z' n. c: q% j: C8 H( {: {
- (const char* )"task2_task",
2 q' @- o' l6 ^ o$ g! r - (uint16_t )TASK2_STK_SIZE,
% R) L8 b! \# P. z' x - (void* )NULL,
& t* H' P- b1 n$ ] - (UBaseType_t )TASK2_TASK_PRIO,
* \' d0 {- R* d - (TaskHandle_t* )&Task2Task_Handler); 2 r. y+ f+ O2 C! G" M, {
2 _$ a" _6 |/ r% I- vTaskDelete(StartTask_Handler); //删除开始任务
. l- I9 ]+ Q& k2 g7 o! w6 } -
( |( v: g: Q& x' p7 P1 d/ t - taskEXIT_CRITICAL(); //退出临界区
* \% ^) U8 B+ J- Z5 G3 K! V$ ?( f - }
复制代码 8 ~8 c- j. x1 e, R: M
task1_task函数
& D! t5 `" H2 m( N Q1 V% F
# Z: |- R8 C. Q q) l( {7 v- //任务1
4 p6 {* s2 ~: M5 [5 O! f" J - void task1_task(void *pvParameters). U% e3 Z0 d' {2 w0 u# k" ^
- {
* z6 B9 h2 `3 [- k) R% k" p/ n - u8 task1_num = 0;
# @' Z/ V$ Q5 b9 ~4 I( J7 q - 4 o4 ^9 F% P- ^: ^/ u# w& `9 z
- while(1)% z3 b2 q6 P; y0 B) D
- {
5 z' ~: K3 a, x& x - task1_num++;
2 z, G C+ u K/ N/ b - LED0 = !LED0;
# d4 L) ]( g5 a7 w: H+ H - printf("任务1已经运行%d次\r\n", task1_num);
6 q: D6 a- D3 K6 I8 { - 1 w9 O5 T6 P: V. S8 O3 Z1 ]/ I1 ~
- if (5 == task1_num)
8 V2 |+ k' U3 `. ?, n/ l' r1 Y1 o$ ^ - {
; d7 v; u. J F* ]/ \ - //任务1删除任务2
) I2 E/ X* H% I+ A - vTaskDelete(Task2Task_Handler);
' p# B, k& @5 g( I9 n - printf("任务1删除了任务2\r\n");
+ d! ~9 e- |: s$ J: N" n3 o# w - }( S6 K" |) A# q7 T$ s/ K0 v( s
-
1 S4 X% ?2 E8 D" k1 l' z - //延时1秒 1000个时钟节拍. j# X6 p; i- N3 E/ S# l5 r- C6 j
- vTaskDelay(1000);; y" n' Y" ~% [/ v! S9 A0 u
- }( l( J, E- ?3 S4 [% ~& T
- }
复制代码 . C4 b' ]6 ?/ z7 H' Z- _3 b; R( `. f; X K
task2_task函数) B7 D& `' ] _) G( O- U# T, u) D
6 r8 a+ W$ V2 m8 C) z- //任务2
. P( H8 n" t& i5 e: G7 f( ~( s8 c7 v8 K - void task2_task(void *pvParameters)& v- N; n, P6 l1 d. b' a
- {
& t+ ?0 R" u7 X! I7 u3 K - u8 task2_num = 0;
" T1 S+ f; N4 y. Q. j% R - ' f6 K E/ f6 [" f+ a
- while(1)1 [. ` J5 E/ R( S& C# x1 f
- {
1 U q3 O/ j4 [# f9 X R6 _ - task2_num++;
& A4 ~) Z2 C( ?* E/ { - LED1 = !LED1;
) n9 C- r% k, L& O6 Q1 Z; ^ - printf("任务2已经执行了%d次\r\n", task2_num);
* o; f5 B4 S# C% p6 s" l/ t+ {6 u -
- P+ Z4 I2 {+ ?+ Y9 x) W+ f4 U - //延时1秒 1000个时钟节拍
% V! \3 e" n& K5 J) g [# m - vTaskDelay(1000);
8 Y6 t/ Q1 J- U5 |* e, }, c - }1 _: h! _' O+ R1 h, o- S( B
- }
复制代码
: J) ~" t) g' m5 u* `8 o5 I9 W- [04. 程序设计
5 d2 z3 w+ Z m+ c, a! wmain.c文件; \" Z' q$ X, @+ Z0 H
* ~/ H1 d7 n+ K/ Z
- #include "sys.h"0 ^) F+ y0 d( X, G: M
- #include "delay.h", C9 F+ c# A! M+ f3 o0 ~
- #include "usart.h"& Y' _5 L+ V; e! J2 H- @
- #include "led.h"; b; q6 {4 w# g/ k
- #include "FreeRTOS.h". b: G* E+ f# A3 ~
- #include "task.h"
H9 F- _$ p/ Q& r2 S6 I
$ M" s$ A% ~" [0 f! s# z5 b- , J7 R, k q* e6 S; z$ e$ L
- //任务优先级4 O- ~ ]' O% H/ H% a
- #define START_TASK_PRIO 1, h9 f! g6 x& y- ?( w: {
- //任务堆栈大小
. G& I; K1 s, z4 ~ - #define START_STK_SIZE 128 , J2 J/ [% o ^2 @/ W. @! e9 n* e
- //任务句柄
7 \* g# Z/ _' P' t4 n - TaskHandle_t StartTask_Handler;+ N6 ]9 S; D9 n1 `- ^3 [# Q
- //任务函数- O6 v- ]! c' ]' L
- void start_task(void *pvParameters);9 u0 L6 L0 \# \ T
1 R9 |" l6 g9 Y2 F- //任务优先级
2 Y! ?. U: E2 R. U8 ]. L5 i5 K% ^& g - #define TASK1_TASK_PRIO 2: r. S: x0 i" }& z i. j3 [
- //任务堆栈大小
8 v8 E2 x* w/ \- X6 d1 Z - #define TASK1_STK_SIZE 50 : C" M" V0 I7 P1 y& E% ]
- //任务句柄
1 V1 X& k$ B) \& f! s3 _+ @ - TaskHandle_t Task1Task_Handler;- i! o2 U ^+ b0 {5 r- C8 u
- //任务函数! T& Q6 [& M7 r/ Z( u5 o
- void task1_task(void *pvParameters);- {! I4 U. p% d1 d! F7 t
- ( K0 Y2 V; q& |% F7 h# e* z& U; [
- //任务优先级
0 h0 D/ x( ?) }7 G5 u# |) \ - #define TASK2_TASK_PRIO 3* T* A, c0 C$ E* M' z' m% C
- //任务堆栈大小 $ D# ?2 B# m; o$ ?
- #define TASK2_STK_SIZE 50 % u" l7 s" y/ u2 t; y6 F
- //任务句柄& W, B9 L! M8 V, V# Z) E% l
- TaskHandle_t Task2Task_Handler;* q! p3 E# O: }8 W
- //任务函数
8 \# t+ g3 I8 j* M6 `: ^ - void task2_task(void *pvParameters);* l; d% f: T! m
- % S# d* A0 O) `
9 l& j. J1 l) a- //主函数0 v% Y( z$ ]/ `; t1 C6 g! O A, `
- int main(void)/ Q/ D# G/ q( o- H; `
- { - [! x& `) X" g" h& R( P6 M
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组42 Y% _: F) H6 t: z& c3 b
- delay_init(168); //初始化延时函数0 v# m8 v# ~5 {* o6 p
- uart_init(115200); //初始化串口
8 W. U' ?7 p* \' o8 b+ u- A - LED_Init(); //初始化LED端口
0 T7 T( ?& T* b -
9 v( q0 U, Y; B. z - //创建开始任务/ {. [: N+ H* N; o. W* _- V
- xTaskCreate((TaskFunction_t )start_task, //任务函数8 A. f4 l; n. |. Y8 Y4 K8 B# a% a
- (const char* )"start_task", //任务名称
" R( {# }" }: Q+ F4 C. X - (uint16_t )START_STK_SIZE, //任务堆栈大小
# p& w+ P _1 [# H+ X - (void* )NULL, //传递给任务函数的参数
3 r/ m A& I+ o1 {% I - (UBaseType_t )START_TASK_PRIO, //任务优先级
- }. I; i0 k( c f C* f4 U - (TaskHandle_t* )&StartTask_Handler); //任务句柄 4 h* V3 Y( k7 v& {# c
- vTaskStartScheduler(); //开启任务调度& L) S" C) z$ ^3 Z, I$ j
- }. v0 f% \) V- J @- A1 U4 _
- " \( C8 l5 n" B3 v/ e
- //开始任务任务函数- ~ O/ @* H0 m9 S' U
- void start_task(void *pvParameters)
! @; R8 _; } W( ` - {1 l; H' ]! }" C h: k, D+ t
- taskENTER_CRITICAL(); //进入临界区
. l' b# \& k1 g1 ^7 [8 E" a - * }- n, a: y+ f1 z( N" H D# Z
- //创建TASK1任务
) T O$ G( {5 u% W4 r: Z* M7 H - xTaskCreate((TaskFunction_t )task1_task, & V! B' V1 E6 a% j* V0 _
- (const char* )"task1_task", ; H' `* l3 B& J- i- z
- (uint16_t )TASK1_STK_SIZE, 1 _0 h$ X5 W5 ~3 S6 U/ s0 \9 Y7 e
- (void* )NULL, 8 a7 ]0 A& T2 \2 g& O
- (UBaseType_t )TASK1_TASK_PRIO, ( o' M$ j: n5 ]! X8 D: m" j
- (TaskHandle_t* )&Task1Task_Handler);
9 s6 x! u4 a; r5 P - //创建TASK2任务
3 i- h7 m a6 o - xTaskCreate((TaskFunction_t )task2_task, * ]# ~8 }4 n: \9 I& \- _7 ~
- (const char* )"task2_task",
( O d1 H/ [/ O0 s+ O, J - (uint16_t )TASK2_STK_SIZE,
% s8 b* ?8 p f - (void* )NULL,1 H/ S0 g% p- K V
- (UBaseType_t )TASK2_TASK_PRIO,( F T8 c& i- J0 ]1 i w7 x
- (TaskHandle_t* )&Task2Task_Handler); : ]( i& Q' E. s
- 1 G( M p) e3 i1 t' V2 ]: [
- vTaskDelete(StartTask_Handler); //删除开始任务
) @6 ?2 r/ N. \3 _8 A8 }& a -
( d* |6 w8 A( R2 ]5 B# c - taskEXIT_CRITICAL(); //退出临界区
- M* p/ t- A0 G- H0 v( g - }+ X5 U. z0 K6 ^ M# Y3 _1 S
3 J. ?: k3 c9 `2 b$ r% W- //任务1
5 H! H" J' N) m- f. l" e - void task1_task(void *pvParameters)
" q9 |# k( V! K5 a - {
; Q( n; I5 k0 z2 Q, l2 D5 v% w - u8 task1_num = 0;1 ^! [+ n& v) Z0 I7 @* X" r
- ( U7 i* G7 z& k6 v7 Z
- while(1)
$ T. H8 C% z' d5 `1 B' q - {
: R6 d @2 A @4 ^8 j% U - task1_num++; [3 D7 G i8 C& P: d
- LED0 = !LED0;
- G9 M- {+ {; l: h: l- Z - printf("任务1已经运行%d次\r\n", task1_num);) M8 h1 E* m2 T, x2 `
-
. e: V4 u! W; ^! Z; n3 D/ z) { - if (5 == task1_num) q6 C# E# H% A5 _
- {- c3 p5 ~ j' }9 V, d( U
- //任务1删除任务2: c0 D* R1 m& c( f+ ]: W Y2 \
- vTaskDelete(Task2Task_Handler);
0 l: x. a$ _+ }" T& h7 o& F - printf("任务1删除了任务2\r\n");# v: ^5 b0 I* } M
- }
* P5 s; k) T! C& c1 [; U% s; ^' Z -
6 E: [) }) W0 x - //延时1秒 1000个时钟节拍- N& C8 P: b+ }8 b) C1 W; }9 Z4 O
- vTaskDelay(1000);8 G) b/ K& l2 u6 k0 a
- }
6 n1 o* b2 G7 T7 L - }
) X' R; r+ }! I- E/ D' x. B0 ] - 6 c/ W+ `; J5 W1 m* S# h j
- //任务2
& g k) F* j5 B( | - void task2_task(void *pvParameters): S7 L3 k7 d# \ ]6 z
- {4 a% J2 d) V& v) m/ S$ b
- u8 task2_num = 0;
3 z! K6 F, |6 D2 v+ v% u - 3 D6 _, ^; `7 a- q% j2 u
- while(1)
) c6 D6 K+ t9 }: ? - {
7 r3 m) g6 p; D' u& E- V9 B - task2_num++;) c @: J# ?' `) {/ T
- LED1 = !LED1;5 Q% |7 _) j+ A# u
- printf("任务2已经执行了%d次\r\n", task2_num);
+ d0 }2 p$ H, M! o6 x -
5 M+ Z* O' z% Z" u& ?8 [4 g' e - //延时1秒 1000个时钟节拍
- N9 V5 _. R& c# k$ X - vTaskDelay(1000);# P0 _5 s" h( L5 f
- }& l# ]* m+ J9 u, {5 o
- }
% Y& x3 R; ^3 B+ V& J
复制代码 + h( Y5 Z* r2 L' w. C
05. 结果验证* Z& A: U5 x( `" Y2 c# G
任务1运行5秒中之后删除了任务2,任务2被删除之后就不会被运行。最后只剩下任务1运行了。
: I$ |, L [, f: X8 `( q
& w; m7 [4 R$ e. p2 E5 U* ? D, M. r- h' B
|