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

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

[复制链接]
STMCU小助手 发布时间:2022-6-18 17:00
01. 概述
7 r/ M  [" g' u8 [, o1 T任务挂起和恢复,当某个任务要停止运行一段时间就可以将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。FreeRTOS的任务挂起和恢复API函数如下表所示:! x: z& H2 [8 j" H& w* \+ n- _
/ E/ n( i4 m% J( y& h
20201123174926358.png
6 E6 o% ?5 z. @4 h& ~7 x. l
; o+ A+ v: e) O8 ]02. vTaskSuspend函数
. q. K" H5 {0 r+ D) {" g
  1. void vTaskSuspend( TaskHandle_t xTaskToSuspend )- H+ C' Y$ P$ ?/ c! o
  2. 功能:
    5 g  D" q( z' r& g0 [$ m  K
  3.     将某个任务设置为挂起状态,进入挂起状态的任务永远都不会进入运行态。退出挂起状态的唯一的方法就是调用任务恢复函数。$ [; T" l+ |1 e

  4. % m0 _7 d* U" O1 s8 B
  5. 参数:4 }" ^& q# y  G$ x2 x
  6.     xTaskToSuspend 要挂起的任务句柄。为NULL表示挂起当前任务。# P# B- X) t! z
  7. $ g  g, o1 l4 O6 E
  8. 返回值:) K( g8 D7 g: s( L
  9.    无
复制代码

6 @, r( s) H/ V. {' x* S温馨提示:: U# D! A$ a: J  @5 D
( u% W/ V7 J3 p$ @/ c3 K5 _5 i& `
调用vTaskSuspend函数是不会累计的:即使多次调用vTaskSuspend ()函数将一个任务挂起,也只需调用一次vTaskResume ()函数就能使挂起的任务解除挂起状态。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必须设置成1,此函数才有效。- N9 J% `0 H, |( ]9 v7 J

: U' p! N, D( J8 }8 q应用示例:
- G$ ~2 g" w/ B
  n* a. M3 k" t
  1. void vFunction( void )" M" k9 y3 p" a- @0 H
  2. {
    5 B1 @# v; B' c8 I$ n" ]& L
  3.      xTaskHandlexHandle;
    , g  @! N, A' Y* I6 h
  4.      // 创建任务,保存任务句柄.
    4 ~/ N+ ]8 _6 @8 N; N
  5.      xTaskCreate( vTaskCode, "TASK_NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );3 {( `5 e3 X  C9 d% m
  6.      // ...7 `* K. A( s2 t; B4 H- j0 n% [6 ~
  7.      // 使用句柄挂起创建的任务.
    ; P% V7 x* W* X+ @* z
  8.      vTaskSuspend( xHandle );
    6 B3 U" M+ i( ~$ V2 a
  9.      // .... h% k- L( p7 X8 ?5 }8 H/ W
  10.      // 任务不再运行,除非其它任务调用了vTaskResume(xHandle )
    9 y9 v# \. ?3 P
  11.      //...  d+ z) H1 M$ U5 Y, C
  12.      // 挂起本任务.
    - q. }4 ]9 l" F
  13.      vTaskSuspend( NULL );
    . `, w0 S2 V- G7 F  h
  14.      // 除非另一个任务使用handle调用了vTaskResume,否则永远不会执行到这里
    * G" y! U1 c% ^5 B, O3 q  ^
  15. }
复制代码

8 w: X( m/ t& R: _" Q$ S03. vTaskResume函数! @& X6 N. M- T% J
  1. void vTaskResume( TaskHandle_t xTaskToResume )9 Z2 y" G9 B( Q; D. ?3 u
  2. 功能:3 t8 L, l4 s1 x- L+ a1 W; @9 M) j
  3.      恢复挂起的任务
    ' ]0 o- k2 c) Y0 d0 q
  4. 参数:! R/ {! t. k9 c# n3 j
  5.     xTaskToResume 要恢复运行的任务句柄
    1 ~+ A( o' y6 B, m0 c
  6. 返回值:
    ; _& }  G7 z. W- v1 x
  7.     无
    + [, n5 K0 b0 l, E1 e  P; `' F
复制代码

  x& H. m3 ~+ K5 i4 i1 t9 E% x温馨提示:
; U) }, `/ Q3 o  t

& g  ]$ k( ~) J0 {$ H, x0 \- R通过调用一次或多次vTaskSuspend()挂起的任务,可以调用一次vTaskResume ()函数来再次恢复运行。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必须置1,此函数才有效。# u3 k, h! d- D6 \1 T

0 U3 j6 X: u; r  W* k7 h! _应用示例:
2 h, ~& {! b2 R# b/ Z3 u, H% p! W
' U' k3 q4 z. h
  1. void vFunction( void )3 h% d9 b& s7 p
  2. {
    . r) b5 u( ^7 ~! s( u+ }
  3.      xTaskHandle xHandle;
    2 }6 f1 W( b( O+ s* S' ?
  4.      // 创建任务,保存任务句柄. G( ~4 \+ ]  ?, E' f& T
  5.      xTaskCreate( vTaskCode, "TASK_NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    5 @, h& x, Y2 z7 _" H
  6.      // ...
    , _5 O7 f' N8 t# R; q2 C9 e8 {
  7.      // 使用句柄挂起创建的任务3 N3 i; |" T* |4 Z4 Y# c+ B
  8.      vTaskSuspend( xHandle );( @$ _+ I( n. h& ?, G$ z
  9.      // ...8 ]" B5 N1 P$ r- S# V2 i
  10.      //任务不再运行,除非其它任务调用了vTaskResume(xHandle )   
    $ A2 L) c& B1 X# F( M. r" [
  11.           //...  |2 u. k) r* Y- ^5 _/ R$ z5 A
  12.      // 恢复挂起的任务.
    . X$ D8 ?- c& m" v7 q3 K
  13.      vTaskResume( xHandle );
    $ b  p6 i& W9 C* ~7 N9 [
  14.      // 任务再一次得到处理器时间
    - a6 @& v, l3 a7 b# W/ A
  15.      // 任务优先级与之前相同
    : N7 b/ E" q# s6 U
  16. }
复制代码
7 P3 G  d! ]: C- g: r' b
04. xTaskResumeFromISR函数
% y, f) c* e2 A
  1. BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume )) \2 n/ X' F( i: U+ z2 p4 t
  2. 功能:
    ) ^/ B5 o1 F" d; K6 T( L
  3.     用于恢复一个挂起的任务,用在ISR中
    ' y* v2 ]7 y3 O1 X
  4. 参数:6 p& H/ _" o/ [$ j# R! o
  5.     xTaskToResume 要恢复运行的任务句柄
    4 w2 r& X% y3 U5 \9 {
  6. 返回值:
    / ]/ p7 d, ?+ m) g) F& j
  7.     如果恢复任务后需要上下文切换返回pdTRUE,否则返回pdFALSE。由ISR确定是否需要上下文切换。
复制代码

- ^3 c  ^9 Q1 ]温馨提示:
9 i" f# E7 r, {  l8 j+ c7 V9 N$ z9 c8 Z- Y* X! g7 ]
通过调用一次或多次vTaskSuspend()函数而挂起的任务,只需调用一次xTaskResumeFromISR()函数即可恢复运行。
3 U  U7 s! Z# o6 W2 o6 o: k5 A7 l1 w6 c8 z5 H
xTaskResumeFromISR()不可用于任务和中断间的同步,如果中断恰巧在任务被挂起之前到达,这就会导致一次中断丢失(任务还没有挂起,调用xTaskResumeFromISR()函数是没有意义的,只能等下一次中断)。这种情况下,可以使用信号量作为同步机制。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须设置成1,此函数才有效。6 ^$ v! s/ b! h" M* b

/ P, V( i* {+ w/ f% r0 k) S应用示例:
0 K% r9 x* j6 m* g1 \5 L& E# K. C8 \2 i7 ?; O9 u; Q
  1. xTaskHandle xHandle;               //注意这是一个全局变量
    / a' A% f3 J% \( [0 L9 s; q

  2. 8 N2 J; P' I5 r
  3. void vAFunction( void )
    - l: Z8 z1 A' M/ K8 E# n
  4. {: C2 a* Q3 k2 J
  5.      // 创建任务并保存任务句柄
    8 _6 x6 z2 W5 D4 F/ }' X
  6.      xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    2 }4 d4 Q4 n* f  ^
  7. 6 d' B, r9 u( X6 k& o  k( b7 H
  8.      // ... 剩余代码.
    8 S% E7 ?" o* L" O
  9. }' a$ X, p  Y- t: X- h: C+ w/ ]
  10.   m# @0 N! o) [& t+ Y
  11. void vTaskCode( void *pvParameters )
    6 Z" ?7 b/ f4 y; h7 D' k: `3 y
  12. {
    8 L8 v  G9 y" F8 X1 B; h1 w
  13.      for( ;; )
    $ A) F, b* i: |/ [  k/ n
  14.      {& h, p2 v. C( J# [9 I
  15.          // ... 在这里执行一些其它功能
    4 N' P2 ^* z1 [

  16. 6 K8 u* u& r' X# y. q! `, U
  17.          // 挂起自己
    2 F! L& f4 Z1 E1 g
  18.          vTaskSuspend( NULL );( \! }9 w1 K" Z: j1 h

  19. ' [7 j4 P7 o* J1 h0 V& y1 p
  20.          //直到ISR恢复它之前,任务会一直挂起8 {+ e/ C5 H5 O, M
  21.      }
    . f. l/ _. H# r
  22. }- J; A+ h4 s; ~' b$ P
  23. # B# ], R- c$ g$ H: C$ Y. p4 O
  24. void vAnExampleISR( void )* I" V& O, g3 k# }* V. T/ x
  25. {  X/ [, H, c6 V( r6 g
  26.      portBASE_TYPExYieldRequired;
    ' m9 ?" o7 c- b- B% N2 m

  27. ) f; d* M- S6 l, I/ k# F; f
  28.      // 恢复被挂起的任务! u' ^1 T4 u6 Y: j) |
  29.      xYieldRequired = xTaskResumeFromISR(xHandle );
    # C- }: j, P7 V% M

  30. 4 w# p0 n5 }* T  n' s" ?
  31.      if( xYieldRequired == pdTRUE ): `% D+ O+ A& S7 S/ W
  32.      {9 G8 X" M. `; A
  33.          // 我们应该进行一次上下文切换
    , i8 Y: }# U: `/ O
  34.          // 注:  如何做取决于你具体使用,可查看说明文档和例程+ r! _7 e7 x. s$ j& J& y5 j7 S- m  E
  35.          portYIELD_FROM_ISR();5 L: ~7 b$ f, [* M
  36.      }5 N, \( Z3 H" \! K) K2 X; E
  37. }
    5 W) Z, w( V0 u; v# i! v+ _

  38. : f% Z# j' N2 s* C7 L0 p1 d3 V
复制代码
% s/ |( r& J. S5 v/ E& A
赞 收藏 评论0 发布时间:2022-6-18 17:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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