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

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

[复制链接]
STMCU小助手 发布时间:2022-3-26 14:00
01. 概述; j) w  U, n( Y: m+ N
任务挂起和恢复,当某个任务要停止运行一段时间就可以将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。FreeRTOS的任务挂起和恢复API函数如下表所示:
9 l' w7 B/ E$ P2 B! ?: g0 x- m
- k. {3 c% W$ ~+ r/ } 20201123174926358.png   N0 ]0 h& i3 u

4 E4 \( a( j7 F02. vTaskSuspend函数
6 W9 I, m! |7 v. M5 k
  1. void vTaskSuspend( TaskHandle_t xTaskToSuspend )6 Y$ ?7 j' g- h( e9 T0 u3 k0 r
  2. 功能:
    4 s+ N9 X; I. V# Q# K: G* H
  3.     将某个任务设置为挂起状态,进入挂起状态的任务永远都不会进入运行态。退出挂起状态的唯一的方法就是调用任务恢复函数。
    $ ~3 d9 T1 H: ^
  4. & ~4 ^1 M" f/ u! H
  5. 参数:! x3 j  F$ Q: E# C! e
  6.     xTaskToSuspend 要挂起的任务句柄。为NULL表示挂起当前任务。, _# n: f/ m# `5 j# V3 x

  7. 5 J# i+ ^# V# L5 _& t0 e
  8. 返回值:
    & X4 e, c: A' X# g" q
  9.    无
复制代码
1 G# V2 X- E/ S" A1 \7 d
温馨提示:
7 }1 V/ L% e# m
) ?% l  ^3 N8 J& h调用vTaskSuspend函数是不会累计的:即使多次调用vTaskSuspend ()函数将一个任务挂起,也只需调用一次vTaskResume ()函数就能使挂起的任务解除挂起状态。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必须设置成1,此函数才有效。
3 X, {9 O8 s% D. k4 \4 r5 J1 s& C0 _, x! Z* G. V6 S, z) }2 V) [
应用示例:; N5 `- }. m/ N9 Q( e
; c8 \1 ^4 D! d* ]- s
  1. void vFunction( void )# x- t) o4 u3 Q, z0 t, C
  2. {7 G) V. I4 s" t0 K* ^4 r
  3.      xTaskHandlexHandle;" d! c% i+ B6 O1 v2 {- y% W
  4.      // 创建任务,保存任务句柄.$ w1 M6 i; K( q, N9 r) F: @/ R3 q
  5.      xTaskCreate( vTaskCode, "TASK_NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    ) c. ^6 [' y0 e4 Y6 }
  6.      // ...
    + `* p+ ?" Q) [( e
  7.      // 使用句柄挂起创建的任务.
    # [  e# I' b5 f& Y
  8.      vTaskSuspend( xHandle );3 D. @, n0 k! n) M( D, R- P# g: D
  9.      // ...
    4 e  r, D! \1 D7 C
  10.      // 任务不再运行,除非其它任务调用了vTaskResume(xHandle )
    $ j/ d( a) A. R0 ]; [7 m5 s
  11.      //...
    # M: z* P0 P' B3 w" F
  12.      // 挂起本任务.: D- g* n( @" m  j3 |
  13.      vTaskSuspend( NULL );" a+ w) e+ c" H+ l$ O
  14.      // 除非另一个任务使用handle调用了vTaskResume,否则永远不会执行到这里
    - H) d3 f/ q6 R- x" M. g3 g
  15. }
复制代码

/ \* @0 C; J9 `/ T03. vTaskResume函数
! {/ A  k9 S; y0 [! j. q; }/ o
  1. void vTaskResume( TaskHandle_t xTaskToResume )
    ' k) ^' U% e! p/ [: C, p
  2. 功能:
    * y' n5 p5 H: j
  3.      恢复挂起的任务, q" X  \' y" T* Q" \
  4. 参数:
    5 S1 K' g1 ^) W2 V1 s8 H6 B1 r! R
  5.     xTaskToResume 要恢复运行的任务句柄0 K) ~, b4 s' F
  6. 返回值:
    ; v$ ^2 P* L! F9 m. C8 L9 d) [5 H
  7.     无
复制代码
# L7 N6 m0 s6 j) E, F& |
温馨提示:, t5 B8 l  P, Z" j5 f. q

/ ]7 v5 N: F' X' H7 t通过调用一次或多次vTaskSuspend()挂起的任务,可以调用一次vTaskResume ()函数来再次恢复运行。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必须置1,此函数才有效。
8 E$ m9 ~' ]4 b6 x2 t2 R- O+ ?0 z) T, ?% h& m: b
应用示例:8 n4 d' Y/ n% I

; L6 }# P( Q0 v1 ], R
  1. void vFunction( void )
    ! e& j6 G5 z5 V
  2. {
    6 L3 |( x- P8 F( v5 d
  3.      xTaskHandle xHandle;
    ) N! t1 B2 {; k/ k" G+ p- {
  4.      // 创建任务,保存任务句柄: h* m+ R* {7 e) ]& H
  5.      xTaskCreate( vTaskCode, "TASK_NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );! g. t) O- }+ ~7 l
  6.      // ...
    / C% J4 T" O$ R0 A( E7 E
  7.      // 使用句柄挂起创建的任务: b- X$ H  t" t; S* R
  8.      vTaskSuspend( xHandle );' s3 r0 W' i. x  x, l- [
  9.      // ...
    - ?1 R( E/ ?) E( U, N) U
  10.      //任务不再运行,除非其它任务调用了vTaskResume(xHandle )    + Y# |9 Z8 Z  E3 J' O4 o3 Z" J
  11.           //...* N" }5 N. V' a6 [* Z' j8 r! k% U
  12.      // 恢复挂起的任务.6 K% ^( |: P. F1 R8 X1 u+ n1 ]+ R9 C
  13.      vTaskResume( xHandle );  b, f, s' t- i0 ^2 F
  14.      // 任务再一次得到处理器时间
    5 [! D( k- X9 t2 M9 p
  15.      // 任务优先级与之前相同
    ; A9 n0 z7 K* @  b: d
  16. }
复制代码
9 V5 l- E+ j, W/ `
04. xTaskResumeFromISR函数1 r5 A5 j2 a+ I* \3 s& l, i) S
BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume ); I* o" w; f2 R& \( o
功能:
* ]) }( V3 X0 h( ?5 `( P2 l    用于恢复一个挂起的任务,用在ISR中
$ j" z6 N" q+ L1 }- {: \参数:/ n" \& r4 v- ~+ g  Q6 Q; W+ Q
    xTaskToResume 要恢复运行的任务句柄& a8 s) s6 n3 D& G( u
返回值:* m7 \+ H* C' l$ D" C+ r
    如果恢复任务后需要上下文切换返回pdTRUE,否则返回pdFALSE。由ISR确定是否需要上下文切换。( ?% f7 f* t  S8 x7 H
3 J4 p2 B0 J( P, F
温馨提示:
# j- h3 c. o) o
3 a5 l" @9 P& k9 E% K通过调用一次或多次vTaskSuspend()函数而挂起的任务,只需调用一次xTaskResumeFromISR()函数即可恢复运行。
  m! Z, s, H' f  y$ w* `4 G( F6 f2 O4 u9 l# t+ u
xTaskResumeFromISR()不可用于任务和中断间的同步,如果中断恰巧在任务被挂起之前到达,这就会导致一次中断丢失(任务还没有挂起,调用xTaskResumeFromISR()函数是没有意义的,只能等下一次中断)。这种情况下,可以使用信号量作为同步机制。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须设置成1,此函数才有效。
  Z+ Y+ B2 Z& a9 w2 T, J# @6 ?5 B% e% |
应用示例:, G" c2 Y& G% K
' Y: w/ U; K7 u6 @
  1. xTaskHandle xHandle;               //注意这是一个全局变量/ w, d5 x5 p) }5 `4 k  C
  2. % U  [8 i8 \# `0 W0 a) s
  3. void vAFunction( void )5 e/ Q( p4 h: D1 f, @8 G% A7 H* k
  4. {
    8 a* m- V: Y) E' f( e" S
  5.      // 创建任务并保存任务句柄9 w- c8 _7 S4 \6 M! y7 |( B
  6.      xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );: c' M5 R4 }. C# L) f/ h
  7. ( u0 Y$ ]& y& k/ ?0 U+ z; e5 V
  8.      // ... 剩余代码.
    ' `* U# n$ K" |5 Q. ~
  9. }7 d7 q% u+ ~0 J4 m' v6 E! W+ _/ ~  ~
  10. ! w- ~% Y6 b6 z3 A! U- X9 X
  11. void vTaskCode( void *pvParameters )
    ' ^$ P9 r% S/ F
  12. {
    ' \7 H- q5 C+ C6 y$ ^6 G
  13.      for( ;; )
    & O+ R  V# d' x( b) ]/ x: C8 w
  14.      {& V8 P( s- E" T/ |' S
  15.          // ... 在这里执行一些其它功能
    2 x9 P! C4 o2 ]0 j

  16. 1 E& D3 ~7 E+ M* B$ n8 ]; L- Q
  17.          // 挂起自己
    5 q+ b" c! J0 y. w/ _: c8 g  c
  18.          vTaskSuspend( NULL );* G/ s# @6 x- y) p+ ^/ O' Q% g9 T1 H
  19. % M& z) I/ N0 f) Q3 C' a; ?/ S; }" p
  20.          //直到ISR恢复它之前,任务会一直挂起
    ' z" k5 U7 K! O8 q5 Z
  21.      }
    4 k$ a, n' ^* p; a' B2 S; B6 Q
  22. }
    7 G/ B; x" H7 G" @
  23. % u* o) T. L  @3 I# G/ a! x
  24. void vAnExampleISR( void )
    2 E: [6 }' k  [) _- `4 r
  25. {, e1 X4 t! z7 |. w5 [9 K* G
  26.      portBASE_TYPExYieldRequired;) h5 F1 S: G7 ]& t  {

  27. ' X7 R( B. V7 |2 [! G
  28.      // 恢复被挂起的任务1 ~5 B* [+ d) ^* b
  29.      xYieldRequired = xTaskResumeFromISR(xHandle );
    5 e" O7 d. H; U- t. N) S8 ^
  30. , Q% @0 ?+ j, z4 Q' g3 z- k  Y
  31.      if( xYieldRequired == pdTRUE )
    0 [; J/ o& f+ {8 ]/ s1 c
  32.      {0 a1 \1 ~8 A4 Z, [
  33.          // 我们应该进行一次上下文切换
    $ |* \% }9 ?# d9 _3 u5 x5 l
  34.          // 注:  如何做取决于你具体使用,可查看说明文档和例程7 x+ G6 h& d" H6 V1 W" {
  35.          portYIELD_FROM_ISR();
    9 M0 ~) v6 r4 ^
  36.      }
    5 J& j) M1 O  d7 Q2 z, p6 J* C1 G  u
  37. }
复制代码
6 V/ b% z5 u) z! ?9 ^: v' x0 T. g% b

1 f( k3 e; G2 y+ ]( q, F
9 g. b& Y0 L1 ]! q4 p, I% N; G0 ^1 a% P) o) W1 J5 I. e
赞 收藏 评论0 发布时间:2022-3-26 14:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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