01. 概述
/ T6 q/ e9 |. B4 |# SFreeRTOS中创建和删除任务API函数的应用。使用静态方法创建任务,任务的堆栈、任务控制块就需要有用户来指定。
! k5 V, d/ H1 R3 z% \" G
3 V8 k* {) |8 A$ ]8 I3 B+ e02. 功能描述5 [6 m: r: {/ h( A: T. d$ m( P
设计三个任务:start_task、task1_task和task2_task,这三个任务的功能分别如下:
, z. K) `( O0 n O4 S1 t
5 `# V" U+ `0 S$ U' sstart_task: 用来创建其它两个任务。
: _& a6 {1 ~ d4 l' w* u9 d) ~( Z. W
task1_task: 当此任务运行5秒以后就会调用函数vTaskDelete()删除任务task2_task,该任务控制LED0的闪烁,并且周期性的输出信息到串口中。
1 k. _$ e2 K# q. t
. g1 C' d% _) _' u% ktask2_task:普通的应用任务,此任务控制LED1的闪烁,并且周期性的输出信息到串口中。1 k# n$ N% B( L. H( M& y
1 @& X+ d8 v2 n( v
03. 任务设计$ L2 v( ^* q' z* M2 f9 P
系统设置
: n$ f( c, ^! }: F" J( w+ G: I
; |+ I( V9 U! c, k+ h在FreeRTOSConfig.h文件中需要将宏configSUPPORT_STATIC_ALLOCATION设置为1.* C$ [" E4 W% S$ r7 H }
, L: L5 x3 X/ L- #define configSUPPORT_STATIC_ALLOCATION 1 //静态内存
复制代码 7 c$ _2 Q- Q4 c
编译报如下错误) O8 i, g$ H# K- p
5 U3 H% B0 Q3 P+ S4 W
0 P E9 L' }* O2 }& F) s. y# r# ? r
8 q9 |. `5 a6 ]使用静态的方法创建任务我们需要自己实现函数vApplicationGetTimerTaskMemory()和函数vApplicationGetIdleTaskMemory()。, E" E% h( t& G! Z0 w" D% D
9 t& M* ^8 v& z: V7 X- a' U/ H0 `- //空闲任务任务堆栈3 P; C* e' I8 M5 T; o: \
- static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
( Y- e4 W. H5 G9 F+ U( T& S - //空闲任务控制块
5 c+ X1 Q- P( r# w0 s - static StaticTask_t IdleTaskTCB;* y9 R. i- Q3 }
% [5 S$ R# f' O$ S+ G& b- //定时器服务任务堆栈% p1 k' r4 a# C1 i
- static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
* ?% w; t; c4 Y9 F' @; H7 S; q - //定时器服务任务控制块( d6 Z! H1 Z" p& A
- static StaticTask_t TimerTaskTCB;7 F- p, x0 `; t3 @& u8 y9 H( H q
" f' j: n5 P# U+ \! S7 L- //ppxIdleTaskTCBBuffer:任务控制块内存) s$ a2 h1 Q% g
- //ppxIdleTaskStackBuffer:任务堆栈内存+ k) \( Z0 ]9 F4 u2 r; [4 j0 G- ~
- //pulIdleTaskStackSize:任务堆栈大小 }, k' Q& G2 }+ F6 q/ ^% C
- void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
$ ?5 V, w+ l6 ^, j1 z5 K/ O7 b - StackType_t **ppxIdleTaskStackBuffer, 4 b3 v1 o* z6 R! f7 {0 g- ]
- uint32_t *pulIdleTaskStackSize)5 F& _! M8 \% ~1 H
- {& j( C! Y/ `3 b; Y7 |2 [% W3 j
- *ppxIdleTaskTCBBuffer=&IdleTaskTCB;9 t4 L3 P2 y2 o! _/ `
- *ppxIdleTaskStackBuffer=IdleTaskStack;8 z6 g0 N% o" g! j n' ?, k
- *pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
" M/ u: b" Y0 U9 D9 P% y: [ - }1 M) v+ u; j- J, h- k& ]9 x
( R- K- |% c# ^( N1 p7 O) T
# T+ f C9 [/ S& R, z1 B- //获取定时器服务任务的任务堆栈和任务控制块内存
3 g; L( g* j8 L. P$ x - //ppxTimerTaskTCBBuffer:任务控制块内存) W2 _( } Q; D" J1 v( W: z g
- //ppxTimerTaskStackBuffer:任务堆栈内存+ X% t$ [* l8 ]; j4 a2 L) w0 Y
- //pulTimerTaskStackSize:任务堆栈大小, [5 P8 _+ e3 j+ r/ h
- void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, " x+ Q& h. e7 P# o( D
- StackType_t **ppxTimerTaskStackBuffer,
0 A9 { ~6 S. ?/ p0 x2 Z2 b( _ - uint32_t *pulTimerTaskStackSize)
?6 w6 \3 @! K, [% ]: J& L3 i V - {
# a/ P" {& ^" X | - *ppxTimerTaskTCBBuffer=&TimerTaskTCB;
& p6 p" W1 m, U- ^5 U/ C2 Y - *ppxTimerTaskStackBuffer=TimerTaskStack;. h* Y- d( A$ i2 t* c
- *pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
8 @' u8 J4 C3 p% I, l$ N - }
复制代码 : \( A: a4 G/ r
任务优先级,堆栈大小,任务句柄和任务函数
w; G# n \, l9 p; s* ^4 Y1 D4 f+ R8 }7 J8 D/ S* g8 Z" j) Y3 o1 K8 i, g8 f8 ^
% O- B" T9 f7 _3 t: I- //任务优先级% A8 p+ R5 Z- ]& {/ P- v: X
- #define START_TASK_PRIO 1/ c9 a/ @9 S9 a- E1 i# Z
- //任务堆栈大小
5 B* |! B0 k$ d$ T- c - #define START_STK_SIZE 128 6 x6 E2 t" u8 J+ M
- //任务堆栈
. v7 L' h9 ~7 k. u+ R - StackType_t StartTaskStack[START_STK_SIZE];
! A8 Q1 R1 i; _7 `9 y. V7 O - //任务控制块
4 `5 C& }1 U0 Q4 L' j* i% J. j0 _ - StaticTask_t StartTaskTCB;0 P$ i- {: A- ?# ? S- P$ X
- //任务句柄* U3 @! `$ A1 J2 y- b
- TaskHandle_t StartTask_Handler;3 j3 L( B' j8 o: v8 U
- //任务函数
7 @2 ]6 O8 M; l" v( R8 h - void start_task(void *pvParameters);
9 d2 u3 E" P7 x. r0 j* T - 3 h3 `. v8 ]( d, R$ v+ D$ @/ C
- //任务优先级6 A* K+ ^( @! `. y a5 f; J
- #define TASK1_TASK_PRIO 2' m6 |& G/ i; I) S: Q
- //任务堆栈大小
1 ?% o* Q# c' E/ {+ O+ h' y7 P2 d- c - #define TASK1_STK_SIZE 50
9 v0 H* E) B9 a. H; x3 E - //任务堆栈; B! D- z- C: x( A! y
- StackType_t Task1TaskStack[TASK1_STK_SIZE];
5 o7 P7 d e& H) ~$ r' T - //任务控制块. M$ t* D' I$ @" j5 N) |3 W
- StaticTask_t Task1TaskTCB;
$ Q) I) w5 c9 F; K - //任务句柄
0 m+ }& t, F/ m! c, B - TaskHandle_t Task1Task_Handler;
0 N8 A; J# O. o1 N) N0 z7 W. n - //任务函数( c7 `. U# K5 _: q0 f, |
- void task1_task(void *pvParameters);9 t% Z7 w( p* s& b' y3 q/ Y- ~* G
! r. y* o: b% s6 B- //任务优先级
. f4 g- c6 K" T& c: V R( G# F/ ^ - #define TASK2_TASK_PRIO 3% u: K5 O3 Y2 H# ?& y4 H3 e
- //任务堆栈大小
; P4 f7 P8 s" w. x1 E/ n$ f - #define TASK2_STK_SIZE 50
3 q6 R# l; w+ Y5 x4 i. e - //任务堆栈
6 J7 p+ y$ A) k( T - StackType_t Task2TaskStack[TASK2_STK_SIZE];) o7 o3 `: Z5 d+ L
- //任务控制块3 K' ]$ J) R! r; p* \8 [, H5 }
- StaticTask_t Task2TaskTCB;5 T9 i. y& S0 C1 M2 Y( s, m
- //任务句柄
- I7 T+ |1 J* H - TaskHandle_t Task2Task_Handler;) g* L2 g# N4 s. s+ S/ Z0 N! H
- //任务函数2 {/ T# v& L3 @% w3 o) i% ]
- void task2_task(void *pvParameters);
复制代码
' h" ?: L2 ~% Z( w [7 _6 r, Tstart_task函数5 _* E) A& o2 j! ^" o
7 _8 L2 E b& O; L6 I: X- //开始任务任务函数
" D, n) s- W2 z' o! | - void start_task(void *pvParameters)7 \ g- B8 G, K9 z2 M: _( {
- {4 v2 Z9 I$ c! I; t
- taskENTER_CRITICAL(); //进入临界区
: r3 ^: g: t) A, t; J4 }; s; D - //创建TASK1任务
( O7 B) w/ s; z( B3 @ - Task1Task_Handler=xTaskCreateStatic((TaskFunction_t )task1_task,
0 }4 F8 d: ~; n( y& v: r! M - (const char* )"task1_task",
6 Z) L3 \. l3 ? - (uint32_t )TASK1_STK_SIZE,
9 b) p0 r% F# ^ - (void* )NULL, 8 G& q8 L9 N/ H. X% g/ z
- (UBaseType_t )TASK1_TASK_PRIO,
! E$ f" a x" p9 y Q$ a - (StackType_t* )Task1TaskStack, ! @6 p; | p2 x$ c4 }2 p
- (StaticTask_t* )&Task1TaskTCB); + Q! f# Q, ^& v
- //创建TASK2任务
* o0 |6 p4 j* ]' V1 A+ |/ A - Task2Task_Handler=xTaskCreateStatic((TaskFunction_t )task2_task,
P+ Z8 A* x1 {1 k7 _) @ - (const char* )"task2_task", 6 P/ f/ ~: r* c" J
- (uint32_t )TASK2_STK_SIZE,
. ~7 K2 B' Q/ H& i8 s- }( N- F; Q - (void* )NULL,
) H1 Y1 A9 ~- p! f. K; Q4 c( V# N - (UBaseType_t )TASK2_TASK_PRIO,
4 R% e' T. J( n) P% h - (StackType_t* )Task2TaskStack,
$ y9 y2 U d* I9 @$ l/ Z - (StaticTask_t* )&Task2TaskTCB);6 V8 e6 C5 {: y0 O" d: \- w+ q, w
- vTaskDelete(StartTask_Handler); //删除开始任务
( t" B3 d% w7 e - taskEXIT_CRITICAL(); //退出临界区
, ?, {/ M) e2 { h6 g% r9 t: ^ - }
复制代码 0 W9 `; b2 `7 D2 }
task1_task函数
) v" L) d+ l0 t* D- ?3 y- g/ C& W; [' [/ k* a
- //任务1& M* X1 V7 ^$ J; h- A
- void task1_task(void *pvParameters)9 K6 u: N% z% j7 W' g" S
- {
! Z- O0 a# Y; X; L - u8 task1_num = 0;
. @0 W e( Q% d- ?" n - ' }6 z/ }5 J$ F( A3 i
- while(1)
8 l: T6 _' i" g j% d - {2 n! m# l- G: `) c& E
- task1_num++;7 N/ h5 p+ v" I% j; P2 o5 w
- LED0 = !LED0;
: W ~) z0 w" h0 F1 M9 ]7 m - printf("任务1已经运行%d次\r\n", task1_num);) _( U! w6 D; G& f- \
-
+ P/ g5 n% l p) j. f, r* b - if (5 == task1_num)
2 Y" z1 r ^ y, A$ \; S - {
% }+ y" B! A" D) I* Q- [ - //任务1删除任务2" J5 z+ V3 `8 F6 R2 o
- vTaskDelete(Task2Task_Handler);
) p- p- }% [8 I1 `3 A - printf("任务1删除了任务2\r\n");
8 ]- r( `* u6 K. f5 T - }0 q8 |) w2 ~2 h: p1 K7 S: W
-
4 v$ X3 M5 l+ x) a$ U7 {$ t7 Q - //延时1秒 1000个时钟节拍
! F) w, X9 `$ r; J) [4 b - vTaskDelay(1000);. q. i4 s/ P e$ x0 j1 m
- }, V9 o* U7 _8 X
- }
复制代码
2 O) n- z$ t. F, C+ }/ \) ~. etask2_task函数9 x5 K% @" c6 p3 n2 l4 h- }. C
; U+ b( W: `/ U/ X; J; @- //任务2
5 E. T: ^+ K0 z S - void task2_task(void *pvParameters)
" i$ ]5 u H4 y8 o7 n3 V - {
! t: d0 G7 l- L( k: E: k6 `. x - u8 task2_num = 0;
# E* @/ t6 @2 l& ]! z: `% e -
% N: O7 x& V- a5 q, y - while(1)
& K7 |- @: S! M% }: ^- C2 V - {
% R) {: d1 d' F: \) o - task2_num++;
" J) e' E. j- i8 D - LED1 = !LED1;6 e/ M9 Y" Z/ x
- printf("任务2已经执行了%d次\r\n", task2_num);2 o9 i- G6 L" N- t3 i) n9 p u2 l
- ! m4 k4 a+ Y3 W* E5 T
- //延时1秒 1000个时钟节拍
0 N2 L9 i- p e M+ k+ g - vTaskDelay(1000);/ J% z% A, M2 u/ d. T3 n; ]1 \8 W
- }
" V( L# E" i; P" A2 P. S$ z9 K - }
复制代码 2 z1 H9 @& z) \& B; _# x! R( H
04. 程序设计
2 I; M7 M* x2 w4 {8 Emain.c文件! t# M0 H: {: ] d) x4 r7 J
5 }3 d$ O8 Q d8 U- #include "sys.h"2 x; }4 C4 K9 a: b; i# s
- #include "delay.h"( E$ M! S$ W* m1 n
- #include "usart.h"" j1 T# C; `; _ W
- #include "led.h"
* \) i8 e' c2 l9 u3 y& E H - #include "FreeRTOS.h"5 p* h; h l/ [4 z% [6 @1 m8 ]
- #include "task.h"7 [, w2 Q- z# z* ]+ q& N- g( t o
- " [4 R' o/ B1 |& `) i# Y$ u% p& g5 [' ?
- % k/ ^8 v4 c, q; Y) U: ^3 A
- //空闲任务任务堆栈
$ g& f; |4 V; q! @/ c - static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
( [( i+ [& o( W. x8 L - //空闲任务控制块
' O4 \/ l. N( D$ a4 C3 @4 R c - static StaticTask_t IdleTaskTCB;5 f* u6 m2 k! K3 D, h4 W( Q
- 6 A( H/ _% x) f0 I
- //定时器服务任务堆栈' s W7 Q9 n) t. Q
- static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
8 ~ b0 g: c' v8 b7 }$ t# d/ x - //定时器服务任务控制块
& j/ E& j: y4 {; @& d( o - static StaticTask_t TimerTaskTCB;3 [2 x! }, C4 h Q# f' S* z
1 O6 C6 P1 @6 i+ f! k, ?- //任务优先级
$ L' v& g6 G- \ - #define START_TASK_PRIO 19 a6 E: f4 i0 K# o; P% m& `
- //任务堆栈大小
5 i( B7 w$ c! E/ J7 R - #define START_STK_SIZE 128 7 I+ h$ r$ y$ J4 w; ^/ c
- //任务堆栈1 z( i: t( C( L. z: @
- StackType_t StartTaskStack[START_STK_SIZE];6 S3 x1 P0 U* Y0 m l3 P+ C
- //任务控制块
9 g ^* ?8 o8 U# {! e7 z9 O: Q) C9 ^ - StaticTask_t StartTaskTCB; @6 H' {9 x" D6 j8 _
- //任务句柄
8 U) W5 I# S% {' x" S& G - TaskHandle_t StartTask_Handler;8 r% K& r( _, \. \: l9 c
- //任务函数$ r1 Q6 S# s$ m) B4 A
- void start_task(void *pvParameters);
0 c, c: ?8 J; r. L" f - 8 [ R2 f& [+ I- b, m) F2 f5 q
- //任务优先级
0 r4 w0 A( p4 l" A9 i/ U" i - #define TASK1_TASK_PRIO 2; _* R9 \8 ^9 w) ?1 V7 f
- //任务堆栈大小
( o l) e+ V! ^* F" E3 ]6 K0 _ - #define TASK1_STK_SIZE 50 ; d3 s; Z; u3 x0 c6 V9 V7 }
- //任务堆栈
/ b" Z. w2 P. i. H5 [- Z! O - StackType_t Task1TaskStack[TASK1_STK_SIZE];
/ r! L- S* O+ K2 `$ N% k+ A - //任务控制块, e1 u8 E" ~/ M
- StaticTask_t Task1TaskTCB;
; F% r# T: @ f! C - //任务句柄
7 ?' q3 @) t% B( {, A& v' ?3 B - TaskHandle_t Task1Task_Handler; t ^- i( W8 s- l, `: \
- //任务函数
u" \ y6 J% k* E9 Q - void task1_task(void *pvParameters);* I) F7 Y* _& l& ^3 M1 Y
- 4 m0 \# G6 U( j$ D
- //任务优先级
( f6 ]* W/ e2 L8 e4 L8 J t) b - #define TASK2_TASK_PRIO 3
6 Z' C0 I$ F, A% [ - //任务堆栈大小 m& C* U, M# u) o/ X' U: a
- #define TASK2_STK_SIZE 50
) _ f0 }! B8 s8 } - //任务堆栈
" J/ L2 _2 n. g6 y6 }. M" g+ N6 c2 j8 [ - StackType_t Task2TaskStack[TASK2_STK_SIZE];% E' m# N6 J' i- s6 x9 s# K
- //任务控制块
' b$ W6 s$ u# s" G9 J- H$ S - StaticTask_t Task2TaskTCB;
6 V$ C1 ^) g1 A3 a* s - //任务句柄* H- x5 Y$ p8 W# ^
- TaskHandle_t Task2Task_Handler;% s! p1 l* y! V: D8 b
- //任务函数
5 C$ Q- @) I3 E - void task2_task(void *pvParameters);& t& n! j) h; s3 [; A# u
( Y3 M3 [, H( s) j' \. A- ' ?* F. w1 H; O* t2 Q) A
- //ppxIdleTaskTCBBuffer:任务控制块内存6 h+ u4 f- L6 R3 c' t* P% B G
- //ppxIdleTaskStackBuffer:任务堆栈内存7 D7 {6 u1 D6 K o7 x
- //pulIdleTaskStackSize:任务堆栈大小
$ i3 f5 ?6 D: i2 R% K - void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, : ~5 @* V/ r# o
- StackType_t **ppxIdleTaskStackBuffer,
7 [& _. R' y! w( X& b- o% d - uint32_t *pulIdleTaskStackSize)
; ~: ~- p( ?! m7 Q0 H% u) T - {
7 F' A0 K [! V4 k - *ppxIdleTaskTCBBuffer=&IdleTaskTCB;
, p% T/ A0 P( U0 ~ - *ppxIdleTaskStackBuffer=IdleTaskStack;
* ~3 }+ Q* [: _8 w2 W8 `( F - *pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
+ n$ U Q3 `& L( T - }# P7 s2 A. _3 [+ b! i
- % ^' G* P$ i9 I+ a9 M
- % c5 T( g: C$ U( k- s" c" t
- //获取定时器服务任务的任务堆栈和任务控制块内存
# R, Y1 `$ {( `; @ - //ppxTimerTaskTCBBuffer:任务控制块内存
7 ~/ O, o; s* q - //ppxTimerTaskStackBuffer:任务堆栈内存
7 O# y+ i5 p7 E" e - //pulTimerTaskStackSize:任务堆栈大小- u: m2 M2 x9 t, m9 @# N+ P
- void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 0 G# E7 C- x! n' ^7 b/ ~
- StackType_t **ppxTimerTaskStackBuffer,
. z' K* p. @* ~6 G1 K4 v - uint32_t *pulTimerTaskStackSize)
. P8 p$ c& w- j - {( `# u1 h$ \2 B% ]( \ W* k
- *ppxTimerTaskTCBBuffer=&TimerTaskTCB;! @3 s+ }. l& L' C, Y+ S
- *ppxTimerTaskStackBuffer=TimerTaskStack;
! Y$ H0 @% s. F8 l4 t+ G" D! {" t - *pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;. U' Z/ \: I( I' \1 r! X8 k& _0 T, W
- }
7 g+ e% _8 i+ n - 5 c T0 V( W( f8 K1 W
- //主函数: r( g+ d/ h+ B3 ^
- int main(void): q" B% x7 \2 `3 D8 L& h' w
- { % |6 W/ d3 F( q6 A( a3 X; `
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4; {. \2 Y2 }7 ~% h/ E) T3 v2 l
- delay_init(168); //初始化延时函数
; P0 N. u7 k8 o% M2 v3 C# Q- A- { - uart_init(115200); //初始化串口
" r5 X) g0 V0 z$ _5 g- k- | - LED_Init(); //初始化LED端口( C3 r5 K& [; e3 ~
- : ?' h3 h- K5 k0 d7 ?! _* r
- //创建开始任务+ N8 E" R) G' q, \6 T
- StartTask_Handler=xTaskCreateStatic((TaskFunction_t )start_task, //任务函数+ M$ w: e. B3 Q- u
- (const char* )"start_task", //任务名称+ b8 Z' M, J+ a: M! l6 x# Q
- (uint32_t )START_STK_SIZE, //任务堆栈大小9 E- `: C2 D3 v: j: c! D9 f
- (void* )NULL, //传递给任务函数的参数
5 U/ n- O0 _9 P( ?+ d9 b! l5 e. o7 B - (UBaseType_t )START_TASK_PRIO, //任务优先级
3 B/ N3 t" |" A3 F, N - (StackType_t* )StartTaskStack, //任务堆栈
4 H7 @8 R9 K* b - (StaticTask_t* )&StartTaskTCB); //任务控制块 4 S% @1 H- w* r2 e# T- G& y* L, o2 J0 e
- ( Q( t# S: v& p# ~; p
- vTaskStartScheduler(); //开启任务调度- Y9 L, g; E% `
- }0 R) O( d# q- B2 t
- : I7 Z& f1 y! V& h; C$ P. E
- //开始任务任务函数
5 |# {0 m. K) e - void start_task(void *pvParameters)* ~7 q* z- }- r" Q }
- {
+ R' N* |7 v, B# [* w( M P( h1 w - taskENTER_CRITICAL(); //进入临界区* E, ~- q9 J7 l% z1 y
- //创建TASK1任务
& u+ g5 T" _' N" V% j" |# P - Task1Task_Handler=xTaskCreateStatic((TaskFunction_t )task1_task, 7 r7 d* a; z* N
- (const char* )"task1_task", 6 m; K' K4 u3 v# s6 r9 k
- (uint32_t )TASK1_STK_SIZE,
$ n# X0 G6 Y) Q2 }7 Q - (void* )NULL, _& a' L* c% R$ ~3 M j6 ], P
- (UBaseType_t )TASK1_TASK_PRIO, 8 P1 z# T6 P: T2 n @. j
- (StackType_t* )Task1TaskStack, , X% y1 x: _- |" e/ D; d$ k
- (StaticTask_t* )&Task1TaskTCB);
7 t: O% P# i. k$ }+ B- f0 V - //创建TASK2任务
5 I3 G& f5 Z1 x" R+ ?. Z - Task2Task_Handler=xTaskCreateStatic((TaskFunction_t )task2_task, ) {1 U1 z7 G+ {$ X0 @9 s
- (const char* )"task2_task",
; w/ \+ k2 L0 q+ {* i! a - (uint32_t )TASK2_STK_SIZE, 2 _. S8 k8 O$ `! f9 r
- (void* )NULL,
# H. b6 ]3 Z* K( C% C$ v - (UBaseType_t )TASK2_TASK_PRIO, % J( G/ z: @2 e9 \+ I. {. n
- (StackType_t* )Task2TaskStack, % b4 t" M: J# N& _
- (StaticTask_t* )&Task2TaskTCB);+ }6 x. g, u8 P+ T
- vTaskDelete(StartTask_Handler); //删除开始任务
: _8 O6 f: ?$ _6 | z% `$ M. X - taskEXIT_CRITICAL(); //退出临界区
: i# ?5 y+ {; Z - }. Z: \0 S; j2 j
+ m; N" [- _ H8 x. ]+ Z# v- //任务15 l4 t7 A; y& b' H* S
- void task1_task(void *pvParameters)
9 F5 u. \" Y- W* B" V - {3 z" A3 L( C* c" {" o' c @( q
- u8 task1_num = 0;
- U6 U; \/ K% n7 E- C3 p5 p$ X8 x1 v -
# P: }5 g* l8 h4 G! H+ r - while(1)
6 \. ]+ B& u* s7 d2 \% i; |2 G7 h - {
3 {9 W8 Y- w3 Q, N- T2 u* E; _ - task1_num++;0 z5 @1 a; t' H1 t8 r3 q
- LED0 = !LED0;
5 p6 v( U2 T' O; x - printf("任务1已经运行%d次\r\n", task1_num);2 Z8 c( ]' M y3 L% E/ i
-
2 o4 W' l; v; F" t- f: G - if (5 == task1_num)
0 d3 }' `! r9 B5 j - {
4 }5 R+ a- V$ v* C- j* s, U - //任务1删除任务21 s% w0 @! C+ G- r& J: B4 _ C; |
- vTaskDelete(Task2Task_Handler);
- E2 l- W1 c# ?- M/ X4 D. D5 R - printf("任务1删除了任务2\r\n");
- u7 ^$ G, c* l! d$ A8 R - }
4 D2 B" G# g' I; x% h& \& ~ -
X. E. r* e! e6 M6 z( r - //延时1秒 1000个时钟节拍! R& n' v9 I/ C9 U8 y' c
- vTaskDelay(1000);: i, f3 F% H+ y% X' _/ Q
- }
6 n4 t9 O# j2 | K# P% L' c! I - }
3 y( v$ H: i' e
. J( r! V* {& x4 [+ U- //任务2- a S O+ a4 C" z4 r
- void task2_task(void *pvParameters)
5 w( W- \/ n' | d) V9 ? - {$ G( X9 z+ J3 c4 l
- u8 task2_num = 0;4 c, ^; J- h* u
- 7 c- z0 G/ @; \( {
- while(1)
; t* p- ?% J1 w4 ]4 k - {1 e! O5 p: }1 E7 {, ]
- task2_num++;
! C2 O. N' _' q' P - LED1 = !LED1;
- O L& B; b8 x - printf("任务2已经执行了%d次\r\n", task2_num);
5 E2 ?3 z. v$ X5 U) x# I - 5 O7 p9 X2 P: N
- //延时1秒 1000个时钟节拍
5 p7 f: `. U! }3 D T. r R( r; a - vTaskDelay(1000);4 L; b( E. o3 j* {5 m
- }; N& x; m% y* n
- }
: Z* D0 I9 I- z+ ~& _- X: g
复制代码 0 t. u& S. x/ S. \/ G- u
05. 结果验证
. m/ T& p: N; J: k! m! b任务1运行5秒中之后删除了任务2,任务2被删除之后就不会被运行。最后只剩下任务1运行了。% q+ Q: Q2 `- a+ Y0 a
- n0 u: a5 Q6 J2 A
+ Z9 F2 o- E8 \6 b6 G' P- J |