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

RTOS超低功耗平台应用---信号量应用

[复制链接]
BinWin 发布时间:2018-4-14 23:11
接上篇:RTOS超低功耗平台应用---FreeRTOS启动&任务创建, a; x0 N. }. [" ~+ W: R& E
6 H2 p: d. b) d& r$ L
' b2 |1 [7 g6 ?5 V# b- `6 X

1 R/ B3 f9 q# V; \) E* f     首先了解一下信号量,一般信号量主要实现两个功能:
; q2 w. {+ {$ T     1,两个任务之间或者中断函数跟任务之间的同步功能& c/ Q1 m6 B) V9 Z- H3 N! k
     2,多个共享资源的管理1 M2 V* `" F7 M/ o' L' u
    FreeRTOS针对这两种功能分别提供了二值信号量和计数信号量,其中二值信号量可以理解成计数,即初始化为仅有一个资源可以使用。
; T) _4 k$ @6 N& [    实验是创建一个线程,该线程通过ISR发出的信号量打印按钮按下计数,包含一个LED闪烁任务。4 I: t4 Z# W; M- j8 W
  1. /**
    2 x8 b! `5 h( y, T8 F" _$ n# m
  2. * @brief  Start a Task.
    ! s/ q' Y% Z9 v  E- }
  3. * @param  argument: Not used" e/ ?6 e3 q* z# X2 S
  4. * @retval None
    ( D; m0 n! C0 B7 w; O
  5. */
    + k/ `# ^" Z/ F3 D: B& U( D- s
  6. static void vAppStartTask( void *pvParameters )8 r' @/ Q7 g( s: i
  7. {
      g/ ^+ Z# w0 g
  8.         (void) pvParameters;
    # n! m" B; o* Q
  9.         
    2 |% W/ N4 a9 ]! T% @
  10.         for(;;)0 A; }* j: B) {9 }1 ?
  11.         {
    9 W( I" [: ^! h# t0 i" _4 V. [
  12.                 BSP_LED_Toggle(LED2);
    7 {, v  h  D' b: Q4 v! m) m
  13.                 9 a. B' s9 l+ u( ^3 l1 ~
  14.                 vTaskDelay(200);
    7 H$ a6 n' W! j' O, H3 ~
  15.         }" D, c8 t/ m8 i  _2 B# w
  16. }
    # b8 Z3 t2 X$ h

  17. . D* o* n3 a; t
  18. /**& _1 {" Y% u* {* w2 i" c
  19. * @brief  Button Task.' i; K: X) y" {9 k( P+ u0 }
  20. * @param  argument: Not used7 h. i- G0 v4 @$ D& ~
  21. * @retval None
    $ n9 E/ r2 O3 E8 V
  22. */
    4 n( R* D6 Q8 |3 d. {! a
  23. static void prvAppButtonTask( void *pvParameters )
    0 W* t" I1 V5 ]0 q0 N2 S! \0 E
  24. {
    ; f7 v  v' n7 z+ w" d; f
  25.         configASSERT( xTestSemaphore ); /* The assert function determines whether the semaphore is valid. */
    $ j" @. M5 x9 _! R9 t
  26.         4 d/ h6 z8 ]4 C' t/ z$ I. R
  27.         /* This is the task used as an example of how to synchronise a task with
    1 q/ z' g# f# b
  28.         an interrupt.  Each time the button interrupt gives the semaphore, this task
    ; Q. l, F% i. O8 @: Q; O6 T1 p
  29.         will unblock, increment its execution counter, then return to block
    ; d/ L4 A/ t/ Q4 C' L6 {( c9 F' h
  30.         again. */3 x3 h3 Y+ R* i% h
  31.         & e! Z3 e' x/ I/ k
  32.         /* Take the semaphore before started to ensure it is in the correct
    . Z% A4 j6 [( g, p4 z9 ]
  33.         state. */
    , P4 x* ?) q5 X) X7 Q
  34.         xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
    $ O  J( U9 |# Q4 `* T: F0 \
  35.         5 Q6 T; k* Y! J  S% v7 g3 v! s! J
  36.         for( ;; )
    ) S  T0 i, a; l5 r
  37.         {0 d  }9 k" N* I) V7 ~
  38.                 xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
    & m) l& z8 X- ~& v( s# q
  39.                 ulButtonPressCounts++;
    ) z! z+ n0 ]. O% `
  40.                 printf("Button Press Counts:%d\r\n",ulButtonPressCounts);3 v* _/ Z" N: }- d& T5 U
  41.         }" [0 n4 d7 L" w( e
  42. }
    & S: p9 {" f, G' B4 g. ^

  43.   M9 p7 z9 w: p
  44. /**
    ( t  C' ?% U( ]4 H" i
  45. * @brief EXTI line detection callback.+ u$ x* j2 E$ J' S* d9 V* G
  46. * @param GPIO_Pin: Specifies the pins connected EXTI line
    * M) e. r  e6 a- _# r
  47. * @retval None& B& a8 U- r7 _5 T
  48. */
    ! l+ {) K. p% [
  49. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)/ v. ^( f8 a* B9 C- K
  50. {
    : _/ a: ^* d4 s$ h3 a8 ~
  51.         if(GPIO_Pin == KEY_BUTTON_PIN)
    ; o' s/ U0 e' V. m8 Y4 z/ \
  52.         {
    ' v8 B1 D1 b% \$ {3 |3 S. G% Y
  53.                 if (uwIncrementState == 0)  \; @& d# l0 k& R; x1 b1 l6 x( {0 N+ Y  @
  54.                 {1 z* x2 R8 K$ q3 E# d
  55.                         /* Change the Push button state */
    & y. ?7 k1 l; P  U" x+ s
  56.                         uwIncrementState = 1;2 O8 X) Q) |4 O- z: ?
  57.                 }
    8 Q0 Z1 E; k2 A3 V
  58.                 else
    4 b. Z! y5 ^2 k4 [. v* `( F
  59.                 {
    ) j% v) v! x# p/ S/ O% h& h) `, ^
  60.                         /* Change the Push button state */
    " y% Y0 v+ Q) t: R
  61.                         uwIncrementState = 0;# e2 _6 y/ ^) H6 m. E0 G
  62.                 }' J9 h% D4 @/ H9 E2 @$ |* @* r( Q
  63.         }  
    6 g$ C, t5 v8 [6 \" U# y( v
  64. }
    : R+ P" f7 e8 V. q# |' E# R$ D  {4 q
复制代码
    主函数中使用xSemaphoreCreateBinary() 创建信号量,
  1. xTestSemaphore = xSemaphoreCreateBinary();
复制代码
    按键检测任务中使用xSemaphoreTake()函数来获取信号量。按键检测使用外部中断,信号量使用完毕后的释放也是在终端服务函数中,如下9 h9 F) G* ^% E* K4 o6 P8 c
  1. xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );  //获取信号,传入创建的信号量句柄xTestSemaphore
复制代码
  1. /**9 M/ h$ j0 C  `1 n5 k
  2. * @brief  EXTI15_10 IRQ) E# y0 C( @2 A! [3 I+ \
  3. * @param  None
    6 Z7 b9 ]; p# a6 h6 \
  4. * @retval None$ i0 x5 p& y2 q) d2 `% J4 z) p
  5. */
    / R, J; {' Z1 s) [; I* ]( {2 C+ o
  6. void EXTI15_10_IRQHandler(void)
    1 u: \3 G" e7 b' e& J" {
  7. {
    ' v$ K% X7 o, P5 V7 ]$ r8 [4 n
  8.         / ?  H" s8 V& @3 P* A2 X5 B
  9.         static BaseType_t xHigherPriorityTaskWoken;                      - S8 g+ V5 n+ j" c
  10.         
    : }1 Y5 [, @3 U1 w7 J$ r1 U
  11.         /* Inerrupt message handling */
    7 L8 p5 P+ u* {5 r
  12.         HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);                ' W& Y) }3 \% ~6 P" d
  13.         
    ' V. ~8 ~' b+ i
  14.         /* The handler releases a semaphore.
    * E0 G" V% `7 L. \3 `5 E1 x
  15.         xHigherPriorityTaskWoken has been initialised to zero. *// f- S& k0 S& @4 k
  16.         
    + ^' R  s: S- J, {
  17.         if (utime_tick >= 200)* b) V7 t6 I, q% u: w5 j0 j
  18.         {7 g7 Z. H7 e0 y' _) u
  19.                 /* The second parameter of the send sync signal is used to save $ y# }4 r( r( v$ H
  20.                 whether a high-priority task is ready.*/
    - C  W+ V6 L' y3 Y/ _; F
  21.                 xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );        6 S' S6 Y* D3 n4 E0 u
  22.                 utime_tick = 0;
    2 i. R$ T: \, a6 V1 A: T6 d+ U
  23.         }
复制代码
+ ~' R7 H* ?8 r2 C7 n* P' w

2 B- Z' \; ?! v! U       程序运行后会执行LED闪烁任务按键计数任务,当获取到信号量后计数值加1,同时释放信号量共下次资源可用。运行效果如下       C(HBH$]QP{3[)V]GZJ6EWHF.png
0 b  Z. A/ H+ }6 N% |4 ~
6 M$ s  g1 d/ r9 P9 S8 W2 q; y
赞 收藏 评论0 发布时间:2018-4-14 23:11

举报

0个回答

所属标签

相似技术帖

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