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

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

[复制链接]
BinWin 发布时间:2018-4-14 23:11
接上篇:RTOS超低功耗平台应用---FreeRTOS启动&任务创建
  |: ?' Q/ Q$ W" u1 [  X+ M/ ?# S3 K) |7 N

' ^5 l0 h6 F1 t4 H$ Q
) Q4 q# i9 Y1 m4 r! ?, x% n) U( R     首先了解一下信号量,一般信号量主要实现两个功能:
- Q! g- P3 z; w     1,两个任务之间或者中断函数跟任务之间的同步功能
6 @( }8 u" G8 y" y; ?  K9 V     2,多个共享资源的管理( Q+ f# s( o( O
    FreeRTOS针对这两种功能分别提供了二值信号量和计数信号量,其中二值信号量可以理解成计数,即初始化为仅有一个资源可以使用。6 a! p3 ~/ o; u( k4 U0 l; L
    实验是创建一个线程,该线程通过ISR发出的信号量打印按钮按下计数,包含一个LED闪烁任务。( _5 l- u+ z6 F1 ^; ^0 t
  1. /**+ D4 _8 L1 b5 p+ T+ C( p
  2. * @brief  Start a Task.* D3 f- Q- @/ H6 p( \5 j, O7 _
  3. * @param  argument: Not used5 N2 G3 i$ ^2 i( z0 }  W
  4. * @retval None9 b; n9 K0 [9 {0 e' M5 }; A5 b
  5. */$ x: @  e8 X/ Z9 q& k+ c' C2 L
  6. static void vAppStartTask( void *pvParameters )
    2 y, i- E1 I' s2 A$ ^; B
  7. {
    # {% R0 k" P/ h
  8.         (void) pvParameters;
    ; X# l7 F7 r, g- B. v" G' u
  9.         
    & X; R* V$ L: o8 v) \4 E( s) M3 B  n
  10.         for(;;)9 b# y# D) b. y4 [* A  m4 ?
  11.         {5 {' }" a3 c, H( V* O
  12.                 BSP_LED_Toggle(LED2);/ j+ T- Z0 H" f
  13.                
    ! [& N) D6 {) J! q( u4 a
  14.                 vTaskDelay(200);
    7 V/ Z- G( o- @1 b. s1 L
  15.         }# {0 t" l8 B! A8 B5 f& a! M, f$ o
  16. }
    ; Q4 V0 C! W  {6 H6 \
  17. 7 r7 {# H2 P9 v4 b( d
  18. /**
    ; O" j* X5 I( Z3 E, c% b8 Q
  19. * @brief  Button Task.
    " |9 h  W8 h9 l& Z+ d0 G% q
  20. * @param  argument: Not used4 d, ]4 m  ~* Q: \
  21. * @retval None: N7 U& F* x5 s7 [- {
  22. */9 \! P" s# w" @# p
  23. static void prvAppButtonTask( void *pvParameters )
    9 V" m6 `) S1 V, f
  24. {
    3 I: s0 K0 C: F  r  {
  25.         configASSERT( xTestSemaphore ); /* The assert function determines whether the semaphore is valid. */2 ~1 u7 o( j# m- H
  26.         / I* W/ _- L# ?1 `- @8 a
  27.         /* This is the task used as an example of how to synchronise a task with: d& \1 |5 g. n
  28.         an interrupt.  Each time the button interrupt gives the semaphore, this task# f' J2 b+ U2 A2 J: M! e) ]
  29.         will unblock, increment its execution counter, then return to block
    # f- [4 A* Y2 F' g( q
  30.         again. */
    8 ~6 ]: H/ v7 O# |- c. t
  31.         
    ! a8 b1 v6 q3 O8 o
  32.         /* Take the semaphore before started to ensure it is in the correct
    : ^2 I; C$ N3 T5 q( P
  33.         state. */
    / d6 o; g; u) s1 v
  34.         xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
    ) B8 a; a2 H/ R5 S( c; ]
  35.         
    $ ]) d# l2 C! {* N5 t/ J" _! r
  36.         for( ;; ). Q% w$ ^1 Q7 F, `/ a$ o" W
  37.         {8 k1 T0 Z. ~! q6 a/ f' b
  38.                 xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
    , y# v9 X! A. ?- Y+ p- J
  39.                 ulButtonPressCounts++;
    & d9 x8 r4 j! ?8 V' L! r/ n; G9 N
  40.                 printf("Button Press Counts:%d\r\n",ulButtonPressCounts);
    - r$ c8 _* @2 @2 Q
  41.         }3 ?% W) b5 }$ S
  42. }
    ! M$ Q; V& L: @/ V- K2 Y* r# N$ [

  43. + V) z" f9 f* E4 [- _
  44. /**8 M9 j1 x0 Z& s$ v
  45. * @brief EXTI line detection callback.3 H+ C) E) c, s' L0 U* M. h
  46. * @param GPIO_Pin: Specifies the pins connected EXTI line
    ( h# e6 ^$ t0 ]  j0 ]
  47. * @retval None
    # _  r3 J  E" ^7 ~" ?# G5 F
  48. */6 |7 M( N  M" o2 {/ |3 A$ \8 O
  49. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin), K$ e  }( C5 C
  50. {
    + Z# q1 i: [+ M& O( V+ R
  51.         if(GPIO_Pin == KEY_BUTTON_PIN)
    & I  T$ n1 }( u# k* Q5 @- {" `
  52.         {
    5 x8 @/ \+ }2 k
  53.                 if (uwIncrementState == 0)
    : q- M0 `3 i/ t. r( a0 O% [
  54.                 {
    ' [+ f. M% R* ]- b( f- \- Z
  55.                         /* Change the Push button state */& S  E8 K* f& Y$ c6 n# M4 D/ v
  56.                         uwIncrementState = 1;
    , `% a! Z$ f4 ?7 k- ?! ]- |
  57.                 }. g) ]/ C# @8 J$ {4 f
  58.                 else
    8 e8 d. \7 Y" C$ H; m
  59.                 {
    4 G+ Y; L0 f3 M9 i
  60.                         /* Change the Push button state */
    & t  _/ I9 q2 H1 @+ G# S& F1 {
  61.                         uwIncrementState = 0;
    8 n1 D1 f/ B" h, Q8 \+ I
  62.                 }
    % _4 @3 ^5 U( o& H% Z
  63.         }  5 h9 z% u" `: U2 O
  64. }' r: c4 m* o, C/ p( t$ G: W
复制代码
    主函数中使用xSemaphoreCreateBinary() 创建信号量,
  1. xTestSemaphore = xSemaphoreCreateBinary();
复制代码
    按键检测任务中使用xSemaphoreTake()函数来获取信号量。按键检测使用外部中断,信号量使用完毕后的释放也是在终端服务函数中,如下
3 Z) v3 X7 x* C% ^, ~1 [) c
  1. xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );  //获取信号,传入创建的信号量句柄xTestSemaphore
复制代码
  1. /**
    " e  U& P1 E, I" r
  2. * @brief  EXTI15_10 IRQ
    5 N: a" C( u( r( |# E& |7 i7 Y. d2 f
  3. * @param  None
    + M1 ^3 U( o* d1 a% _7 L
  4. * @retval None
    ) s6 X4 G$ Y( y) q8 }
  5. */4 k4 Q) ^/ j4 J5 O: D" h' _7 v
  6. void EXTI15_10_IRQHandler(void)
    % `8 O9 x- `- M( O
  7. {
    & P8 g! b% _8 ^+ k3 w) F" l1 N
  8.         , C# n  Q* P: b* z/ n! T4 e8 N
  9.         static BaseType_t xHigherPriorityTaskWoken;                      * B3 a+ ~3 T& k  p6 q
  10.         5 q. E* w8 u+ g
  11.         /* Inerrupt message handling */- Q9 M! P: w8 j5 c# `/ B( q
  12.         HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);                1 q& n4 |; I7 z6 n5 Z0 H. [: G
  13.         ( P1 u$ N  _$ l6 D
  14.         /* The handler releases a semaphore.1 ?& U& b- ~) Y% S
  15.         xHigherPriorityTaskWoken has been initialised to zero. */
    % F( e/ Y' L$ P! g3 B- F
  16.         
    3 Y  l, A5 y9 _0 o) g  z
  17.         if (utime_tick >= 200)
    ) q" Y: w6 X1 M: I# t
  18.         {1 t7 ~% `5 u. J9 c
  19.                 /* The second parameter of the send sync signal is used to save
    ! V2 L, `+ {+ B! g' A) S
  20.                 whether a high-priority task is ready.*/) \+ q: X9 Y: L; k# X9 Z! h& w5 H2 |
  21.                 xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );        
    " ]  a: P& D5 m/ F5 l* S1 L
  22.                 utime_tick = 0;
    " y! N- t& e) F1 `7 g( ?
  23.         }
复制代码
/ ~  m5 m+ d* T" Q
7 b- Z' P) ^0 O5 B1 S& }
       程序运行后会执行LED闪烁任务按键计数任务,当获取到信号量后计数值加1,同时释放信号量共下次资源可用。运行效果如下       C(HBH$]QP{3[)V]GZJ6EWHF.png " t+ o/ O* D  ]/ q9 s5 y

! u2 V5 y. v6 x
收藏 评论0 发布时间:2018-4-14 23:11

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版