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

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

[复制链接]
STMCU小助手 发布时间:2022-6-18 17:00
01. 概述
! X0 M" V0 V: W+ P. B- Z任务挂起和恢复,当某个任务要停止运行一段时间就可以将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。
: \7 y/ \' b9 N, j( r/ r8 M3 I- _: c5 w. q- |1 u' R; |/ M) u, x- l
02. 功能描述
; h! a5 d% K# f0 o设计三个任务:start_task、task1_task和task2_task,这三个任务的功能分别如下:" c. I- `8 c) b& t( l0 K% ~
0 i; N) D; U; q4 k8 K
start_task: 用来创建其它两个任务。, I9 O2 l) }+ K5 ^; V

* P8 k% l* B3 U/ x; N9 g$ G+ I- ctask1_task: 当此任务运行5秒以后就会调用函数vTaskSuspend()挂起任务task2_task,当此任务运行10秒以后就会调用函数vTaskResume()恢复任务task2_task该任务控制LED0的闪烁,并且周期性的输出信息到串口中。8 g. M7 K* b& h) ?. f0 y, T8 n
/ ?- S+ B. b' H% q- {; Q
task2_task:普通的应用任务,此任务控制LED1的闪烁,并且周期性的输出信息到串口中。; W$ ?. [  |3 O( N2 s, E! t

2 M# o3 Q; F' M1 B7 C% D$ Q03. 任务设计
4 E* b2 p1 l5 m1 f! ?/ W
任务优先级,堆栈大小,任务句柄和任务函数
0 z/ ?3 t) f% z$ h- R# W4 T" R2 t6 R4 r# H
  1. //任务优先级
    ) \+ M) |7 X' p& B$ s, D
  2. #define START_TASK_PRIO                1
      U& O) E4 \% P0 v) d% K
  3. //任务堆栈大小        9 |* P) q4 S& h4 L0 `# b  Q; e9 R
  4. #define START_STK_SIZE                 128  
    1 Q  D3 q3 f- E1 M) e& S5 g
  5. //任务句柄
      \  `1 |: v6 h; e. s4 f/ u- s
  6. TaskHandle_t StartTask_Handler;
    " j) l: R% h2 E% ~
  7. //任务函数
    % S# z" v5 p! h1 M/ F! A) r
  8. void start_task(void *pvParameters);
    6 V8 g8 E* E! ~/ P) M

  9. / ]  H! t  U# {$ o6 K  \
  10. //任务优先级
    7 t; t8 H& i3 P3 D& B
  11. #define TASK1_TASK_PRIO                2
    : f, ~# B$ _. q( e: S
  12. //任务堆栈大小        4 h/ v& V2 w# G5 i; l  m! n0 t4 E
  13. #define TASK1_STK_SIZE                 50  
    8 a- @6 M5 p8 [
  14. //任务句柄
    $ W0 W& x! G: g  I' b4 ~2 b  A6 b' s
  15. TaskHandle_t Task1Task_Handler;
    $ K8 |0 {9 F1 R
  16. //任务函数
      s7 r" T& e. V" v, L
  17. void task1_task(void *pvParameters);3 @8 J5 S5 u) X3 K- N- \

  18. $ F( e) {" ~9 i& @7 P7 o
  19. //任务优先级2 A: X( H% z3 b6 A
  20. #define TASK2_TASK_PRIO                3" x- z" E8 N9 d+ {1 |5 T$ K5 J
  21. //任务堆栈大小        
    1 T* ~6 u+ x1 ^8 T) |
  22. #define TASK2_STK_SIZE                 50  4 V/ ^, j; ^: r# P3 u! S* \! A
  23. //任务句柄/ _7 O, g$ ?  p+ \6 [6 O4 c
  24. TaskHandle_t Task2Task_Handler;
    9 }' `. ^2 s/ M% @) z
  25. //任务函数
    3 |, ~4 S; b: d
  26. void task2_task(void *pvParameters);
复制代码
# ?4 H. R! q* X4 Y1 V
start_task函数
& B, {/ @- t' G& H% W0 T+ e. R$ q1 d+ K# F$ n% Q& a1 D
  1. //开始任务任务函数
    ' O$ @8 ^  _! h# Z) W! Y
  2. void start_task(void *pvParameters)  a$ V+ s- I' K* X
  3. {
    ( C; ]4 ]( Q7 e; ?
  4.     taskENTER_CRITICAL();           //进入临界区
    5 S* O2 h! J; z
  5.         ( q1 b3 i* ^! e0 C9 h9 p% \' n
  6.     //创建TASK1任务
    6 F* G# r3 N& V% y) K3 W
  7.     xTaskCreate((TaskFunction_t )task1_task,             1 W! Q. C! m% V, i. n
  8.                 (const char*    )"task1_task",             F: |, i4 z- J+ U& q' P6 e
  9.                 (uint16_t       )TASK1_STK_SIZE, 0 d% }$ U- V. x4 W; a8 d
  10.                 (void*          )NULL,                                
    ; m( q6 F3 a0 T* B
  11.                 (UBaseType_t    )TASK1_TASK_PRIO,        ) v& d- m: g  Q1 u& p  I3 e
  12.                 (TaskHandle_t*  )&Task1Task_Handler);   
    2 o4 H! M9 a7 @6 F4 B$ w/ X8 k
  13.     //创建TASK2任务. p+ m$ Y" a9 Z& p% e
  14.     xTaskCreate((TaskFunction_t )task2_task,     ) d2 W7 B; {- E* J7 z+ M! {
  15.                 (const char*    )"task2_task",   - X. X+ h* [, [- p. q: U
  16.                 (uint16_t       )TASK2_STK_SIZE, ! I* x2 X% y. b9 e3 J
  17.                 (void*          )NULL,( _( U* m5 w( e7 a0 c
  18.                 (UBaseType_t    )TASK2_TASK_PRIO,
    1 }, P8 V* B8 j6 C, ]/ X
  19.                 (TaskHandle_t*  )&Task2Task_Handler);        8 l0 c4 L" P# A% |0 ^' j2 _, Q, a

  20.   s# `/ k9 G0 x9 ]2 z
  21.     vTaskDelete(StartTask_Handler); //删除开始任务
    / ~% Z2 F( P* {6 Z: y, O
  22.                                 
    . [7 y. i. C2 T$ _6 q) m
  23.     taskEXIT_CRITICAL();            //退出临界区3 p1 \( K* Q! u6 V* O  K) i
  24. }
复制代码

! _  t- a3 J1 W( f; M1 }& Ztask1_task函数
3 M6 z' J) M, S5 u5 E! p$ b5 z5 l4 \' v
  1. //任务1
    : W6 s% H. h- ~
  2. void task1_task(void *pvParameters); u8 ~; x4 v! H+ I4 k4 V+ I
  3. {. f. U( A' \# L6 K0 L: Y
  4.         u8 task1_num = 0;2 }0 s; ]% t" f6 z2 p' @5 F. u
  5.         2 `" g$ m  t6 D, i! {; N  `1 ]
  6.         while(1)/ ]9 s4 Y# E' z  S- t
  7.         {: m  [, t! B9 G
  8.                 task1_num++;4 W- w# r. D" s
  9.                 LED0 = !LED0;% v& g1 Z8 U6 \$ w. Q2 @/ j
  10.                 printf("任务1已经运行%d次\r\n", task1_num);8 G, ~  W6 r  M  d9 E+ ~
  11.         
    , S1 @  O) w3 Y, ]+ K# V
  12.                 if (5 == task1_num)! r* G3 ~$ r: w! a8 M9 E& Y5 k: T& L
  13.                 {+ y# c, M' w7 c5 ~4 Y! ~( g$ o1 H
  14.                         //任务1挂起任务2
    0 O! ?) ?5 Z  e7 h) n
  15.                         vTaskSuspend( Task2Task_Handler);! a5 l% Y+ x6 b. i9 Q, r
  16.                         printf("任务1挂起了任务2\r\n");9 a: X; E0 |7 t0 j- u. e5 |
  17.                 }! V! p! @5 |* _; N9 p0 P0 e( }0 b
  18.                
    : u/ W/ Z; u+ {" ^* B3 \
  19.                 if(10 == task1_num)5 Y9 S2 a2 L) G1 K% K
  20.                 {+ o' x2 O6 k7 h: X: A
  21.                         //任务1恢复任务2
    0 I4 \' z6 z' G' V' ?
  22.                         vTaskResume(Task2Task_Handler);& n& a7 g, o! ^% \
  23.                         printf("任务1恢复了任务2\r\n");
    ( ^4 D* M: F3 z& A( v* b
  24.                 }
    " H3 U5 t/ M; w" Z, G& o3 y) C
  25.                
    : C( L. G/ B& a1 W5 M
  26.                 //延时1秒 1000个时钟节拍
    $ i$ Z5 C; m: \! M: L  \
  27.                 vTaskDelay(1000);  b1 P7 E0 H" }, @
  28.         }5 K2 G1 @0 }4 \* E; n0 r
  29. }
复制代码

8 F" y8 M$ s+ ?3 e7 M7 Ctask2_task函数# H' T% f+ o! v# D6 |6 m% ?) p
% ~/ o  o, p/ f2 [- n
  1. //任务2( b5 ~. H& `* j  W  e7 @* T
  2. void task2_task(void *pvParameters)
    5 g+ t3 |' |* M* x  b. p+ q
  3. {
    " g. }0 ]$ m7 x- ~1 @
  4.         u8 task2_num = 0;
    & A8 ^' K. P* i) J% ]
  5.         
    - N, ~4 f8 U0 _! O
  6.         while(1)3 d3 ]1 s1 C" _  @1 n% v5 r& s6 E3 W1 J
  7.         {1 F1 r( V6 S+ A( G3 }
  8.                 task2_num++;+ f7 @3 ?5 c. i- B/ U8 r9 f
  9.                 LED1 = !LED1;
    0 u, U% ]  D' _8 j- K2 G. L/ g/ L7 x
  10.                 printf("任务2已经执行了%d次\r\n", task2_num);
    8 e! ]" \- _4 k0 g
  11.                
    # Q/ z$ h6 N$ q3 q/ p9 T4 b. ]
  12.                 //延时1秒 1000个时钟节拍
    " G7 L. Q0 W- H6 k% @# F
  13.                 vTaskDelay(1000);
    / l# b' I2 g. K/ _: z
  14.         }
    : O# D. S% A6 X/ m. G
  15. }
复制代码

+ o1 ?; E% r5 _8 R- ?04. 程序设计

2 P6 \/ ~! D/ S+ `; m: j, C9 s& v7 qmain.c文件- ?* B  n6 `7 X% P5 O+ v

# m8 \" {' ?" u& Q( t' L$ s
  1. #include "sys.h"' `  L$ L; l  L- @0 H
  2. #include "delay.h"
    0 P* D  \8 e- |4 s/ B# M2 p1 E0 n
  3. #include "usart.h"& {. D' k/ H2 [- |% k
  4. #include "led.h"
    * k# n% u6 V( |3 |
  5. #include "FreeRTOS.h"
    1 P9 S! P: E9 H5 e6 v# U
  6. #include "task.h"
    4 L& x, R, f, W/ ?. J: A
  7. 4 \  X& w8 k& Z3 ^0 }( k! v. f# C
  8. ! ?0 g5 T) {9 ^% U* k, B
  9. //任务优先级
    4 r; k8 G! n' x3 m" V
  10. #define START_TASK_PRIO                1/ E7 h/ B4 i+ T( f9 H/ O6 N9 S& J
  11. //任务堆栈大小        + D: u0 ^: @+ u: r6 ~8 m+ T
  12. #define START_STK_SIZE                 128  / r. C$ w- H& f/ ?7 t# r
  13. //任务句柄! }' B& y/ R* |, X6 j1 x
  14. TaskHandle_t StartTask_Handler;5 O! D4 |2 H3 `" ~2 Y* ?( p2 h
  15. //任务函数3 t. c- @# H7 N2 w2 {0 r% q( Q
  16. void start_task(void *pvParameters);, `; T0 x" Y1 }# e* ^0 E" D

  17. $ N! g$ G! T; Q6 L7 n# @. M/ w
  18. //任务优先级% W1 N. N5 F1 L8 }* K$ J
  19. #define TASK1_TASK_PRIO                2
    ! ?+ J/ B' ?8 h( H  k6 @) V. n0 @
  20. //任务堆栈大小        
    ; ~! W( I, ?; j& |
  21. #define TASK1_STK_SIZE                 50  . @1 x7 M, n3 U4 J8 O5 d. M
  22. //任务句柄
    / s# H% ?1 p- P3 m
  23. TaskHandle_t Task1Task_Handler;1 ]" H8 N6 A/ f2 ^; B
  24. //任务函数( b# m8 I: \" }* M+ ?' X
  25. void task1_task(void *pvParameters);
    9 t) C' N. A: U9 u
  26. * H1 `, E) u# d. m# ?2 d
  27. //任务优先级2 F  D4 [0 O- j0 e9 W$ A
  28. #define TASK2_TASK_PRIO                3
    # a) ^8 U' O$ H. H, f
  29. //任务堆栈大小        
    - N! r2 C9 N2 u2 H
  30. #define TASK2_STK_SIZE                 50  & J8 |. H5 X( ~
  31. //任务句柄2 I9 C% v$ w. |- `! v6 n) k
  32. TaskHandle_t Task2Task_Handler;7 v0 X# @$ B  j' l+ [
  33. //任务函数
    ( d2 b" G0 M0 X" {3 @
  34. void task2_task(void *pvParameters);
    ( q8 a7 j$ ~9 c$ N- z! z/ m

  35. 5 ~. g5 y7 v; [( s
  36. ' |/ Z/ Q5 f/ H  x
  37. //主函数
    # D( @9 s8 Y1 }( T
  38. int main(void)! V( J/ `: i& \9 l. }1 x$ _+ V% b
  39. {
    ! {( x# l3 X# c* v, ^4 D! g
  40.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组42 U5 x( I& U$ _9 |
  41.         delay_init(168);                //初始化延时函数
    ! B# p+ V) R2 }, @4 K
  42.         uart_init(115200);             //初始化串口
    4 E) ~$ u, Z, K- G1 h
  43.         LED_Init();                        //初始化LED端口' z! V- v9 B) A3 p. m0 n) _' _
  44.         
    + _- p9 o( ^8 z7 e- t$ x1 ]
  45.         //创建开始任务
    ) O9 O3 u4 v3 X9 e% p% B
  46.     xTaskCreate((TaskFunction_t )start_task,            //任务函数" c  G4 H9 f! m3 s* X
  47.                 (const char*    )"start_task",          //任务名称, o. c( }9 ~# l1 {
  48.                 (uint16_t       )START_STK_SIZE,        //任务堆栈大小, q0 r. z3 C( r+ m. y: \
  49.                 (void*          )NULL,                  //传递给任务函数的参数
    9 W2 E- U; Q& g' T5 y9 ?0 K% {8 H
  50.                 (UBaseType_t    )START_TASK_PRIO,       //任务优先级) _" v: {0 ^1 I% U
  51.                 (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              . l4 K; b6 R- ?3 x0 ^' H* b: C$ A, _& j0 V
  52.     vTaskStartScheduler();          //开启任务调度. H# U4 N9 f3 ?& K
  53. }: d# |" U3 Y& T$ n8 G
  54. 1 C& i/ C' Y0 z. L4 L& t4 z% \
  55. //开始任务任务函数
    % D, p0 c: M3 k3 ^7 g
  56. void start_task(void *pvParameters)
    ) |2 `; m) ?3 H4 U
  57. {
    % m4 v7 A. d  o0 L
  58.     taskENTER_CRITICAL();           //进入临界区
    % _& c+ x* s: Y' }
  59.         $ V0 E1 j! q) K, d
  60.     //创建TASK1任务
    7 u' l! {) M* l: l( O; G) P
  61.     xTaskCreate((TaskFunction_t )task1_task,             ) O/ [+ f3 a2 `& ~$ _
  62.                 (const char*    )"task1_task",           3 J  i$ u4 t  m
  63.                 (uint16_t       )TASK1_STK_SIZE, 0 ?; W- \2 M% ~- L
  64.                 (void*          )NULL,                                
    5 a% A8 `% o; @0 v$ g
  65.                 (UBaseType_t    )TASK1_TASK_PRIO,        5 b) I8 C# \) Y7 |& L1 O
  66.                 (TaskHandle_t*  )&Task1Task_Handler);   
    3 n. |! o# O: I5 z# o
  67.     //创建TASK2任务
    4 _" W' B% R! ]' ]2 H& ]1 t* `
  68.     xTaskCreate((TaskFunction_t )task2_task,     ) m2 F% r2 N7 g$ ~5 j
  69.                 (const char*    )"task2_task",   
    3 y1 g1 T: n) E% F4 m& M, R
  70.                 (uint16_t       )TASK2_STK_SIZE,
    7 d4 V4 ^8 C8 n4 U6 Z3 n
  71.                 (void*          )NULL,
    9 p, \3 G. Z' O& K9 S& @; b# ^/ Z
  72.                 (UBaseType_t    )TASK2_TASK_PRIO,& K; Q6 D+ ?! w7 V& @: k
  73.                 (TaskHandle_t*  )&Task2Task_Handler);        " i( b3 F- m( R1 H; m. M) `, G, Y
  74. ( d8 ?0 |9 S: ^  ~
  75.     vTaskDelete(StartTask_Handler); //删除开始任务
    2 n8 d/ c" r% `* N8 f
  76.                                 , C4 Y5 ?# x& s3 ~7 ]: R+ W
  77.     taskEXIT_CRITICAL();            //退出临界区) P( k2 ]: F1 H& r$ o+ `
  78. }# ^/ X) A, V1 ^: M3 F- S8 J

  79. 7 `9 t* T: z/ j# L! a- m
  80. //任务1
    3 k: t& X. `1 Q, ^1 [7 o
  81. void task1_task(void *pvParameters)
    1 o" Y/ _' r/ W5 q
  82. {
    $ Y5 U% h* f/ [, }& I, n; P7 @
  83.         u8 task1_num = 0;
    : K! ^3 d4 P5 C- `5 e( G
  84.         
    ; w6 {) ^6 n* C; X; U
  85.         while(1)6 G4 Y+ ]9 e/ k4 I9 u% f# G
  86.         {9 S: P* v' ?' W& N+ v5 f; O
  87.                 task1_num++;
    2 ~+ r" R! a8 Q
  88.                 LED0 = !LED0;
    & R+ {! Q. \2 b5 `3 T
  89.                 printf("任务1已经运行%d次\r\n", task1_num);
    - g5 [4 r6 D; b" K3 b6 \
  90.         ; w3 A/ c  O! h0 X4 ~: G5 n1 b
  91.                 if (5 == task1_num)* Z, U+ M% o+ i7 s
  92.                 {2 U! E. v5 B" o# h* A% `
  93.                         //任务1挂起任务2
    8 O* f" |( c1 m! _: K' d0 ?+ C) r
  94.                         vTaskSuspend( Task2Task_Handler);
    * X# H7 u; H+ E4 j% o1 g
  95.                         printf("任务1挂起了任务2\r\n");* s& ~3 r4 A7 p* O
  96.                 }. k& C( Z+ L( }& ^) J- j5 z3 a
  97.                
      n9 ]" o* }, h, h9 U" p2 e- L) G+ G
  98.                 if(10 == task1_num)
    9 `/ o3 x. @2 ^  u$ D
  99.                 {
    / h! K' T( K% z
  100.                         //任务1恢复任务28 t& k2 ?* S8 Z5 H. W
  101.                         vTaskResume(Task2Task_Handler);
    / L, @/ A4 h. q6 V7 E
  102.                         printf("任务1恢复了任务2\r\n");- K5 I" f, K, ~* h* n6 H
  103.                 }( l# o/ b" ~3 M$ x  W+ W$ d
  104.                 " R# J+ h: G( w3 ~
  105.                 //延时1秒 1000个时钟节拍
    3 E! |( f# b( }* I! t; j5 R+ k$ K" H4 U
  106.                 vTaskDelay(1000);( p% V+ x" U6 c& u9 I/ k
  107.         }- J& W) K) Q' ?6 B) `/ k
  108. }8 [9 a' W$ Q  ?; c5 t, V! |
  109. ( G$ z5 o, ]9 g
  110. //任务26 K' {  C( ]0 L5 ]3 e+ y
  111. void task2_task(void *pvParameters)) `5 m& u: ~0 G: Z, V* A5 A5 Z
  112. {( [# y5 e: }& \, C6 q, [7 y
  113.         u8 task2_num = 0;) m5 q- W0 {( D- @3 g$ a8 x
  114.         
    , X: ^( h& z, T" S. z
  115.         while(1)
    7 A3 g9 m% [% `9 P0 U- K
  116.         {
    ( p! f" k1 [2 w, D* ?/ S
  117.                 task2_num++;
    2 u/ a; W7 w- r$ _" |3 [, b2 h
  118.                 LED1 = !LED1;  B/ N8 `, J8 ^$ G0 b, k  A
  119.                 printf("任务2已经执行了%d次\r\n", task2_num);9 D+ ]! [% N& ]5 z: q
  120.                
    : J2 U5 ~  g' K* |7 Y7 R: ~
  121.                 //延时1秒 1000个时钟节拍* s1 X& x5 S2 \% H( l$ @
  122.                 vTaskDelay(1000);, g' W9 y9 x; c
  123.         }: i( G( A# D0 A4 G9 b; \
  124. }
复制代码
$ D  q6 n  Y1 k! m5 H
05. 执行结果
- f& r5 i5 u9 E4 K8 ~7 Y+ b# m
  1. 任务2已经执行了1次
    % P+ Q# `- L! G4 x0 m
  2. 任务1已经运行1次9 s) V% e, v. ^( o
  3. 任务2已经执行了2次
    # U! l3 C1 j( j* ]8 a; C
  4. 任务1已经运行2次* [1 m6 U5 a7 \2 {( u
  5. 任务2已经执行了3次# K4 V/ h( G! Z4 [+ Y9 u; J
  6. 任务1已经运行3次  |1 _% I# b2 C3 y( l
  7. 任务2已经执行了4次2 w+ z+ M. _, ~6 d
  8. 任务1已经运行4次# j: s, _/ {9 f  P- `6 ?
  9. 任务2已经执行了5次
    : b" u, H. \' R. A/ R
  10. 任务1已经运行5次
    0 c$ W, I' c: R0 V
  11. 任务1挂起了任务2
    . m* T! K; n% q
  12. 任务1已经运行6次9 J- b5 o. S. }. m& _- Q
  13. 任务1已经运行7次
    3 r; Z; _8 W1 P. I0 a' K
  14. 任务1已经运行8次* b7 I* D& S  l0 f! S! ?
  15. 任务1已经运行9次
    ! d8 b5 M! E; s6 v- C
  16. 任务1已经运行10次
    + Q, q6 A& i: d9 G
  17. 任务2已经执行了6次
    8 L$ U" }! X. ?
  18. 任务2已经执行了7次  a! f4 n! p6 Z1 a* V% f- `
  19. 任务1已经运行11次7 g4 t, O- o5 x& Z+ z- e
  20. 任务2已经执行了8次3 l  b" c, M( [3 K7 Y. m
  21. 7 ]- T5 l9 f( W2 i9 P
复制代码

7 ~; S7 s/ _, P
赞 收藏 评论0 发布时间:2022-6-18 17:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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