你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】FreeRTOS任务挂起和恢复示例

[复制链接]
STMCU小助手 发布时间:2022-3-26 14:00
01. 概述
& k- v! d. U2 g' I任务挂起和恢复,当某个任务要停止运行一段时间就可以将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。
5 b9 z( M) y4 s
* F. c* V* v  B0 A: @5 k" F. S02. 功能描述) W! i7 N8 W4 H) L5 c" e
设计三个任务:start_task、task1_task和task2_task,这三个任务的功能分别如下:+ i2 K: w' C" @7 C0 U" I
& ?+ L' i* s% L0 H/ e$ }2 H
start_task: 用来创建其它两个任务。
3 e! i) P# K( e9 m" m" @3 U. ]& r& k# ~- a. ?
task1_task: 当此任务运行5秒以后就会调用函数vTaskSuspend()挂起任务task2_task,当此任务运行10秒以后就会调用函数vTaskResume()恢复任务task2_task该任务控制LED0的闪烁,并且周期性的输出信息到串口中。
1 E+ @% R( U, F: W& P9 @5 [1 E4 F6 h7 y, ?4 n6 c0 k& b: k9 o
task2_task:普通的应用任务,此任务控制LED1的闪烁,并且周期性的输出信息到串口中。! ^" i/ K' m( f. Z! v

3 P1 q  |8 P6 O. f9 T' c  {03. 任务设计
# X7 m. P1 C) o; o' D任务优先级,堆栈大小,任务句柄和任务函数
, p  _' x. x7 o, ]* T
6 D! I( e: i% [' m7 j: w2 h2 U& Q0 j
  1. //任务优先级3 b, V! g  |- ^, Z; y8 z0 i
  2. #define START_TASK_PRIO                1
    : |0 }; S  \: k8 S; m% l8 D
  3. //任务堆栈大小        
    7 D, s: ~4 Y, K( ?5 n
  4. #define START_STK_SIZE                 128  
    " V2 `0 C* z+ _
  5. //任务句柄  }% t1 K; Q- |" B) \$ r3 p  R
  6. TaskHandle_t StartTask_Handler;+ @5 p- _$ n2 @3 L
  7. //任务函数8 ?5 a& x6 S( H/ G  P' _
  8. void start_task(void *pvParameters);
    ' h% b8 U" o, s4 b- j- b5 k

  9. 3 I4 R2 d, Y; Z  e
  10. //任务优先级
    ! T! J' m  L; ?
  11. #define TASK1_TASK_PRIO                2
    8 K9 ]8 J- f7 T" A/ C5 {' D
  12. //任务堆栈大小        
    3 x4 _/ d2 W% v! t
  13. #define TASK1_STK_SIZE                 50  
    ' ?1 H6 I; D, ^  R
  14. //任务句柄5 C; J3 R8 b0 Y
  15. TaskHandle_t Task1Task_Handler;
    3 A; b- g( s* R. h8 S
  16. //任务函数
    / S4 N1 s) r( {/ @; O" z- Q. ?; v2 o
  17. void task1_task(void *pvParameters);
    ) C* B, Q; p% o) A! H# c
  18. " A: a5 Z5 _  n3 ^
  19. //任务优先级+ ~6 E6 J2 P2 H9 Y
  20. #define TASK2_TASK_PRIO                3& Y6 W3 O. h1 X3 q& G7 g- U
  21. //任务堆栈大小        * w) P+ p9 D0 r3 o8 `
  22. #define TASK2_STK_SIZE                 50  & ~& w$ o! V  C" a
  23. //任务句柄6 l* _3 @0 o2 l- u. d# s& w
  24. TaskHandle_t Task2Task_Handler;( Z1 ]7 x4 D8 m
  25. //任务函数
    ! ^( i1 g' d2 A0 @. f7 h: Z
  26. void task2_task(void *pvParameters);
    9 g7 @" t( ]& V
复制代码

- J% m& r- F4 A. Xstart_task函数
! V/ e3 q- y, y2 S
" r; c$ y, s( z6 {2 w8 Z  E6 ^' g. H
  1. //开始任务任务函数0 _$ c2 [  \5 |( y
  2. void start_task(void *pvParameters)
    ( M: |  I) A% X9 p2 }0 L7 G
  3. {# T  T( a- _7 y% \
  4.     taskENTER_CRITICAL();           //进入临界区% h! h1 g: g7 V4 _
  5.         7 \3 ?1 w7 j- r9 A
  6.     //创建TASK1任务- R" [6 x& A1 o% J
  7.     xTaskCreate((TaskFunction_t )task1_task,            
    5 o( c' u" T; y3 P
  8.                 (const char*    )"task1_task",           
    . i# a+ J% r- Z7 |' v! c6 m
  9.                 (uint16_t       )TASK1_STK_SIZE, ( [& m  v& P0 \
  10.                 (void*          )NULL,                                : _" k+ s4 X: d% C( X
  11.                 (UBaseType_t    )TASK1_TASK_PRIO,        
    4 B7 l- |& ]& u: X3 v! ~2 v
  12.                 (TaskHandle_t*  )&Task1Task_Handler);   9 _) H  A7 }$ Z/ c5 y% V- t+ R1 ?
  13.     //创建TASK2任务
    9 n2 i8 x$ Z3 b) J0 b( Q; X
  14.     xTaskCreate((TaskFunction_t )task2_task,     
    . K" A: u4 D8 j6 d$ _% b2 W
  15.                 (const char*    )"task2_task",   , Z0 L( w. n; R. ]5 s, t
  16.                 (uint16_t       )TASK2_STK_SIZE,
    8 R! l8 S1 E6 a: B2 L. x
  17.                 (void*          )NULL,
    % F# v; b9 V% ]5 e8 L0 ], T2 w, p" E7 K
  18.                 (UBaseType_t    )TASK2_TASK_PRIO,# K8 p( `- B; e5 v
  19.                 (TaskHandle_t*  )&Task2Task_Handler);        
    & Q( o& y) e( p. _6 H

  20. , j4 @% I  ?9 F8 x" m
  21.     vTaskDelete(StartTask_Handler); //删除开始任务; T8 |2 k/ ^3 z" w/ D0 g3 q
  22.                                 
    ' f: m  v( s; ?& ]
  23.     taskEXIT_CRITICAL();            //退出临界区
    ( D  S- V+ t6 L  L1 c  }% B
  24. }
    3 C( V1 n- b7 ?  I. i
复制代码

( [' ?1 o3 i9 V0 ftask1_task函数" \, F0 G& _* o  ~: z! N3 I
+ K! K! d; p# O0 s/ b. @  y8 f
  1. //任务1. W0 w3 n0 g7 b4 R: V" e: y
  2. void task1_task(void *pvParameters)
    1 V8 f/ ~4 N$ z) u( B0 p3 ~
  3. {8 N2 i% `, d8 ^  i% e6 V; i
  4.         u8 task1_num = 0;
      `4 I% E) n& A) ]. @, e: A
  5.         
    8 ?# Z2 g7 A! e9 k+ K
  6.         while(1)0 \: E: y  k3 K/ Z+ I' P
  7.         {
    # _/ X7 p  v6 x
  8.                 task1_num++;
    / B2 d; }6 J  O! S5 j0 W, H, M
  9.                 LED0 = !LED0;
    . a" l+ h- t/ O
  10.                 printf("任务1已经运行%d次\r\n", task1_num);
    " B0 f' L  L, ^' H; [  P# z
  11.         ) A; ]0 f5 v6 x! z: x( }# s/ Z
  12.                 if (5 == task1_num)
    , n9 X, `9 J" l4 n
  13.                 {
    ' Q" H: [& c" T9 C$ n. J9 S$ k
  14.                         //任务1挂起任务2) |0 r, ~! x4 t& N+ p0 C3 m: s+ i
  15.                         vTaskSuspend( Task2Task_Handler);7 l8 m6 ]+ m9 z3 h: O: n
  16.                         printf("任务1挂起了任务2\r\n");
    ! E: F! `3 k& `$ [
  17.                 }
    , I" y# [$ m% B* k  D. ~8 c' P, W) ]
  18.                
    : a& b3 @# R1 M* t
  19.                 if(10 == task1_num)' E3 h" J$ H6 m1 ?7 V+ l
  20.                 {
    # [2 f/ G; \1 G
  21.                         //任务1恢复任务25 h1 i2 |' s- Y9 o
  22.                         vTaskResume(Task2Task_Handler);1 u) l7 e- j1 Z1 G- z
  23.                         printf("任务1恢复了任务2\r\n");
    / y1 X' O+ X% Z2 H
  24.                 }
    8 U" I, J; f# }% O; o" K+ D9 j5 i
  25.                
    1 M1 M- g. v7 d6 y2 d3 F( c
  26.                 //延时1秒 1000个时钟节拍- ~& u- [6 o0 f7 }7 C7 B
  27.                 vTaskDelay(1000);
    $ w; J, D8 H" q$ Q6 V8 m
  28.         }0 s, M: K& `. c" t/ |
  29. }( Q5 |! w( F* k! R7 [! ]# g
复制代码

/ m- H4 A/ o( Jtask2_task函数
+ [; J; k5 O* J* z6 N9 @% V
$ x0 y& `) ^/ H
  1. //任务25 i5 f6 w2 k( [9 o
  2. void task2_task(void *pvParameters)% k% `7 d1 l$ I4 ]3 f# u# r
  3. {  Z3 h- w" x1 U
  4.         u8 task2_num = 0;' w/ g: D. L. e* Z
  5.         # G7 p0 j) {# n4 E9 w7 R# N* n  Z
  6.         while(1), d) g' R% f$ P0 \0 ^
  7.         {2 i! P( p$ O* {6 y9 h1 ?# k& ~, C  Z
  8.                 task2_num++;
    , q+ O9 |' C9 V1 r& `
  9.                 LED1 = !LED1;
    . b" S+ Y6 H: @( j
  10.                 printf("任务2已经执行了%d次\r\n", task2_num);
    ! I. ?1 u. R8 X) x' S  h
  11.                
    4 q3 h/ m  ?; b  O3 D& e$ i
  12.                 //延时1秒 1000个时钟节拍
    5 y& M8 w( y% l& {* F1 S2 o
  13.                 vTaskDelay(1000);: d1 E- x+ @* t. v$ z
  14.         }
    6 K! c, D, U/ q
  15. }
复制代码

! a1 E6 S! X* Q04. 程序设计3 D% |5 e7 I  _( Q* |1 D
main.c文件
! T* f3 Q; U' M( d# L: t
: I# j& S/ V7 g: M5 v+ c, K6 Q0 J; K
  1. #include "sys.h"
    % ?4 {* n, L! W$ b
  2. #include "delay.h"0 w# N# r1 B' N/ ?8 g- e
  3. #include "usart.h"
    $ B" O$ ~1 l2 s" [. L
  4. #include "led.h"
    3 ~; ]' O% ]" i0 x8 C( I4 j
  5. #include "FreeRTOS.h"
    , c% P. ^1 f0 B  m3 C, o( M2 w
  6. #include "task.h"9 V, F( k6 G- i# w

  7. * }" f* H) ~9 v3 c# Y5 y
  8. - i0 ]; A9 v% L( t
  9. //任务优先级
    ( _& I3 k7 f. J" G, {8 g, F/ E
  10. #define START_TASK_PRIO                1
    / R# G$ m1 u$ t0 g- t; h
  11. //任务堆栈大小        
      ^/ ~1 H9 V9 a- f' }8 p
  12. #define START_STK_SIZE                 128  ( ], a& |# i; `/ H' P; q; ?
  13. //任务句柄
    5 e# j: G( D/ F/ ]+ j
  14. TaskHandle_t StartTask_Handler;
    ! T' L# {5 b2 @. H5 S
  15. //任务函数
    2 p4 K2 L- r0 L% N  @4 ~
  16. void start_task(void *pvParameters);+ t5 _- L+ M$ v' }6 r

  17. ; \7 {- S' K, v! F0 z& z: {( `. g. w
  18. //任务优先级# L7 K6 L3 S! Y) s; `1 _1 |
  19. #define TASK1_TASK_PRIO                29 j" U1 d. f& h, Y2 `
  20. //任务堆栈大小        ' v& D  |& O1 H1 {
  21. #define TASK1_STK_SIZE                 50  ( z4 }( V4 ^( R6 j, ]5 K
  22. //任务句柄
    % d, u, ~( N+ I8 v# g
  23. TaskHandle_t Task1Task_Handler;
    : B2 @+ ]: _) W$ z+ Y9 K& c
  24. //任务函数
    1 a( i* [$ H3 E+ d9 `, V# v. e
  25. void task1_task(void *pvParameters);9 p# Z6 `% j% d) p# v; j( A% H

  26. 6 N+ d* K; X! b
  27. //任务优先级% f+ J, B) |) J" w$ @
  28. #define TASK2_TASK_PRIO                3$ g5 P- w9 u  ^3 \3 c1 D" Q7 m$ @
  29. //任务堆栈大小        / k% s/ I- N: c; o0 x" Q
  30. #define TASK2_STK_SIZE                 50  + g% E- ?& _; y9 B, a# T
  31. //任务句柄
    ( g- b# d6 {" V+ I) u3 J
  32. TaskHandle_t Task2Task_Handler;/ l$ y2 c% c# X; X
  33. //任务函数9 l% H) `" {0 ]. q, T2 O
  34. void task2_task(void *pvParameters);
    9 d) l, n+ k; V8 C9 s, f
  35. ! s4 z% n) ^0 s- c

  36. ) W6 {' k" c, X7 J+ W: v4 A5 s
  37. //主函数
    5 H, n/ W0 I9 `8 i) n  o) ~: S
  38. int main(void)
    8 z" I! W; D" j' U$ Y# g
  39. {
    $ [. Q2 U1 Z) k2 k
  40.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
    ' ]  y7 s: H- h+ V! s+ m
  41.         delay_init(168);                //初始化延时函数, C- Z' d; }1 G! }5 W
  42.         uart_init(115200);             //初始化串口; t8 I# o& Y! X- M  z
  43.         LED_Init();                        //初始化LED端口
    : h! O, b& t" G2 j9 Y
  44.         5 R, t' [$ w5 U9 ^
  45.         //创建开始任务+ t5 P: e& x: ^) R* P4 w, U
  46.     xTaskCreate((TaskFunction_t )start_task,            //任务函数
    * T  L6 L  ~1 ^, H& P
  47.                 (const char*    )"start_task",          //任务名称
    / D& K0 D4 A: c* X5 i% G: _. E
  48.                 (uint16_t       )START_STK_SIZE,        //任务堆栈大小
    & G% w! a* n* F) e8 q! d8 L3 B4 T# f
  49.                 (void*          )NULL,                  //传递给任务函数的参数4 \4 E- @* v( G$ P* W$ A$ ]
  50.                 (UBaseType_t    )START_TASK_PRIO,       //任务优先级) ~; i: S9 q, D8 v2 A. g! u; P
  51.                 (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              4 X/ M9 H) S" r( B% L3 R, u
  52.     vTaskStartScheduler();          //开启任务调度  b2 x5 ^4 d$ g1 A& R3 b- r; ^
  53. }
    4 n5 Z: X1 m2 b6 h
  54. ; O3 |5 [% ]9 `' y4 U0 m8 w& Q
  55. //开始任务任务函数
    8 ^& c" O+ A" ^3 N# K7 O( H/ ~0 e
  56. void start_task(void *pvParameters), Q, B1 {0 w/ L, _( d; Z
  57. {
    ( P! N2 }- C/ n; ~& ]( Z$ o4 A$ C* d
  58.     taskENTER_CRITICAL();           //进入临界区
    2 K+ ]& J3 {9 @! Z
  59.         & ^. L8 c& }( W
  60.     //创建TASK1任务
    ' j5 u' Z7 e0 Z' W0 G% K: v  L
  61.     xTaskCreate((TaskFunction_t )task1_task,             5 n, e, r! q7 G4 G. k& g
  62.                 (const char*    )"task1_task",           
    / b9 y4 ^. s: H+ \
  63.                 (uint16_t       )TASK1_STK_SIZE,
    # d4 g, V& P& K' K$ |, _' ?
  64.                 (void*          )NULL,                                
      D# l8 ?! O, s, b
  65.                 (UBaseType_t    )TASK1_TASK_PRIO,        9 T5 ]! _% O) k  {9 x, }
  66.                 (TaskHandle_t*  )&Task1Task_Handler);   
    0 c) w8 I: s/ |! ]: d
  67.     //创建TASK2任务1 _0 Z  Z/ ^/ `& O8 P
  68.     xTaskCreate((TaskFunction_t )task2_task,     # z, h1 ?- u' S% C; ~) I
  69.                 (const char*    )"task2_task",   
    9 C( Z% {( {; D8 R
  70.                 (uint16_t       )TASK2_STK_SIZE,
    3 B4 i1 [  L& l
  71.                 (void*          )NULL,
    % S: C$ R; X& e2 Y# E
  72.                 (UBaseType_t    )TASK2_TASK_PRIO,
    / p5 F0 r: L" V( r' F& }
  73.                 (TaskHandle_t*  )&Task2Task_Handler);        
    4 Q' D- B7 i" n! w; m0 j
  74.   |2 g% g% n3 ?
  75.     vTaskDelete(StartTask_Handler); //删除开始任务# n; ~% N3 F( X, j0 Y
  76.                                 
    # j; @4 n; Z+ Y8 q/ E6 U" F+ H7 Q
  77.     taskEXIT_CRITICAL();            //退出临界区
    2 S# s7 E. W* j" r7 f8 r
  78. }, B& s" T- H. k) G/ w' ]% B: w
  79. 0 |/ a' y% \2 x9 l3 a& c0 d
  80. //任务1
    ( K5 R! a: f6 A) a" y. M1 }1 h  {
  81. void task1_task(void *pvParameters)
    , `5 Z3 l- [5 z0 ~2 s
  82. {
    ; y& \. E, X! s) W- j$ P, S- o
  83.         u8 task1_num = 0;
    ( y: \- W- D, L3 \1 _/ d& O
  84.         # V5 a- X% W9 Q# F+ M$ D+ b0 {
  85.         while(1)3 D! z' {! H$ ^
  86.         {+ j! W/ |) L8 E* S" g! P5 b# O
  87.                 task1_num++;
    ' I- \5 A  ]! i
  88.                 LED0 = !LED0;
    0 L. H# o9 Q- K) C
  89.                 printf("任务1已经运行%d次\r\n", task1_num);/ v! ?, f. a* v& r9 Z
  90.         
    ! n: C+ j* q5 Q% f3 `
  91.                 if (5 == task1_num)
    # {7 x, b' v9 y5 J( l
  92.                 {% X/ t, A: r$ l8 a
  93.                         //任务1挂起任务2
    % n; E! ?; L$ U( E5 `0 X8 a$ e9 R
  94.                         vTaskSuspend( Task2Task_Handler);+ N8 I+ x6 S' G8 j0 O5 e0 n. a
  95.                         printf("任务1挂起了任务2\r\n");) n8 `3 }) {- F# |
  96.                 }
    4 v7 {( g0 n' M8 U; V5 Z
  97.                 ; f, M1 [& J. I  q
  98.                 if(10 == task1_num)0 j0 c4 |5 b. i' X7 P
  99.                 {
    ' E' \$ d0 n; E% w2 ]  p
  100.                         //任务1恢复任务2! h! a: P3 `+ |4 X; G" D+ U* J, W( t
  101.                         vTaskResume(Task2Task_Handler);0 m" G* @( j, n5 v0 y% ]
  102.                         printf("任务1恢复了任务2\r\n");
    & U  }6 D* @8 a- U7 |3 x/ g
  103.                 }
    5 D3 Y3 b/ c6 }0 o: z6 J
  104.                 6 K$ B6 R, P+ C* Q
  105.                 //延时1秒 1000个时钟节拍  j3 _3 W+ h+ n) Q" ]1 y' _9 d
  106.                 vTaskDelay(1000);
    * J$ S7 h# I8 n& ]8 |' B
  107.         }9 H, c: a, B. t' e! i$ {
  108. }  m* A6 Y$ w- Q5 k( q, o

  109. , k! U& E# F$ H
  110. //任务2
    . K; B/ t) j. [: t0 n+ P6 `$ o+ Z8 ^
  111. void task2_task(void *pvParameters)
    , D, G% Y! ^7 f) l1 P: j( ]
  112. {
    " t* v( k% O* G6 Y/ T# j1 R* Q$ ~
  113.         u8 task2_num = 0;8 _9 C5 ?  c0 R; y! }. T
  114.         ) ]6 j+ Z& s" [% ~
  115.         while(1)
    8 a! h8 k+ x6 A% W* i
  116.         {
    0 f8 G. s! k- I! P& }
  117.                 task2_num++;
    ' t9 N- c! v7 _3 ~3 ?
  118.                 LED1 = !LED1;" u7 C: q$ p6 U8 o. F4 s
  119.                 printf("任务2已经执行了%d次\r\n", task2_num);$ [" q. ]7 ?% K' b9 Z
  120.                 - J- B, }8 o& n" f4 _$ ]  R
  121.                 //延时1秒 1000个时钟节拍8 x8 r4 ]( B, `
  122.                 vTaskDelay(1000);3 [' y/ Y& ?  i7 y3 i* s/ [
  123.         }
    8 O: L! i3 x# b
  124. }
复制代码
; S) y' D; H8 Q: ?+ b
05. 执行结果: o# P0 H4 V4 j+ G( l9 R5 E
  1. 任务2已经执行了1次% A& Z1 U; ~! S, J: t
  2. 任务1已经运行1次- c: N$ i1 N" t! f& \
  3. 任务2已经执行了2次2 E* {& i: u' Y! _. p5 Y; z5 ^
  4. 任务1已经运行2次
    9 E% q# t) U: v( _( {
  5. 任务2已经执行了3次
    + Z) i" _3 c- u0 J  v5 d
  6. 任务1已经运行3次
    7 j  H' c7 v6 c4 Z2 I. q, l. x( g
  7. 任务2已经执行了4次
    8 P" G- L$ R, H8 C
  8. 任务1已经运行4次
    ; W# d. R' S, P$ j# Y/ x
  9. 任务2已经执行了5次- G! D% F$ Y6 Z3 F
  10. 任务1已经运行5次
    / q. \+ n: _3 G  N& ?2 u& d  R( G
  11. 任务1挂起了任务2% Y9 c  S& x0 c( R7 j7 ~% Z
  12. 任务1已经运行6次9 ^$ B$ H7 y- |) b: f  G: _3 n, I
  13. 任务1已经运行7次7 S. l% G- E. Z2 a: w( m: t
  14. 任务1已经运行8次& b- W# ~  H) Q
  15. 任务1已经运行9次
    0 M5 ?% m$ X$ O- [' c9 J
  16. 任务1已经运行10次
    - W) {9 u$ g/ x! C0 G/ \
  17. 任务2已经执行了6次) K  J; s: [1 h2 F1 c
  18. 任务2已经执行了7次2 L3 Q3 R8 U" V' G
  19. 任务1已经运行11次, \( E3 u' k0 V  \! ~) }  [- i
  20. 任务2已经执行了8次
    # _: s! @8 G. n4 U

  21. - Q* D! @+ i/ F  n! y6 v
复制代码
+ F* w2 Z" g5 Q7 x3 D+ ?

" H  `" s% ?- R7 C0 k3 h1 ?& [2 y7 ]+ l% V5 a9 c% R
赞 收藏 评论0 发布时间:2022-3-26 14:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版