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

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

[复制链接]
BinWin 发布时间:2018-4-14 23:11
接上篇:RTOS超低功耗平台应用---FreeRTOS启动&任务创建1 O* \" t. X7 v7 @

/ G$ {7 ]% c1 @7 Q) w& A& L# ]# K' O

8 K& i, }% B& Q# h# X+ e' t8 X     首先了解一下信号量,一般信号量主要实现两个功能:
1 k1 G- v/ i: S- E* F! y: [     1,两个任务之间或者中断函数跟任务之间的同步功能# ~8 V2 @2 e+ d. ?( t; `# d  p. b
     2,多个共享资源的管理8 ^0 c) D4 ~: S# E# {
    FreeRTOS针对这两种功能分别提供了二值信号量和计数信号量,其中二值信号量可以理解成计数,即初始化为仅有一个资源可以使用。
2 t/ V7 Q$ u4 k- d  F    实验是创建一个线程,该线程通过ISR发出的信号量打印按钮按下计数,包含一个LED闪烁任务。/ w* \4 O& G6 {$ }9 k
  1. /**' P, G* H& a) {; y8 l
  2. * @brief  Start a Task.
    * m& N& t* ?0 ~
  3. * @param  argument: Not used" Q/ e% S$ }& m
  4. * @retval None
    9 L& @$ X( I( j& ]( V; l
  5. */
    3 \, s4 o) r' J9 n% n& S+ g
  6. static void vAppStartTask( void *pvParameters )
    ; e& [8 e( i( J4 P+ k; x' f
  7. {7 r9 |9 z& K4 X7 ~( a& {! s
  8.         (void) pvParameters;$ Y5 n/ N4 L/ F: f4 ?8 a
  9.         1 @6 |& n- Y  E4 n
  10.         for(;;)
    7 v3 v5 j3 o4 }1 ]& {( g; v6 ~9 [9 q
  11.         {
    6 ]' [% C( q* G9 [( w
  12.                 BSP_LED_Toggle(LED2);5 P3 b' a8 d) q$ |& {4 A
  13.                
    $ b" g% |; j& i0 `. J
  14.                 vTaskDelay(200);
    % {( W# A& A" u) k+ v
  15.         }* u8 f- f9 H, e+ M+ c/ H* T. j2 Q
  16. }
    0 J" h7 K0 ^4 a+ {: [

  17. 9 ]! v& Z$ l  j- F  [6 n
  18. /**$ @) Y( X. X2 J/ K, ]  m
  19. * @brief  Button Task.
    ) E6 F2 V* R. K9 I% O
  20. * @param  argument: Not used) G" O) F) p6 q/ {7 }, o3 ]
  21. * @retval None: S& V" k/ x3 X8 e  G
  22. */) h( [% N; m7 E2 k$ G+ P0 L
  23. static void prvAppButtonTask( void *pvParameters )
    4 S4 l9 p: l' i1 f( f; ^
  24. {
    7 Z0 A; Z$ l  o5 H# Z7 d8 G' ^* \  J+ j
  25.         configASSERT( xTestSemaphore ); /* The assert function determines whether the semaphore is valid. */
    , N  {6 }: K* E+ p& P% p$ R4 S
  26.         $ O& H; y# o; R& |1 e9 P
  27.         /* This is the task used as an example of how to synchronise a task with
    # k9 \* j1 V+ ]: z) F) G
  28.         an interrupt.  Each time the button interrupt gives the semaphore, this task
    ; u" `3 V; n0 D( z
  29.         will unblock, increment its execution counter, then return to block
    ) z$ q0 u2 ^+ v  T; P! V: \
  30.         again. */0 ^! a! M2 w0 @  q4 T% j+ l6 N- P+ K2 s
  31.         
    ' F# b3 v. K! f: ?# \( w  v8 G
  32.         /* Take the semaphore before started to ensure it is in the correct
    : ?# _3 }  F& Q; S6 y' s) V- L
  33.         state. */
    1 C( K( z  J! @9 k
  34.         xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
    ! T6 ]) ~0 @# c) G+ K% R
  35.         
    / F$ k: d! X& m4 H% E( w
  36.         for( ;; )
    2 P$ p* `  d; _$ Z
  37.         {& E: \5 E. g) O4 r- b& {2 W" l
  38.                 xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
    5 i" B2 ^1 i0 U( h8 A
  39.                 ulButtonPressCounts++;
    5 a: r+ ]' Z% ^8 _3 C) k
  40.                 printf("Button Press Counts:%d\r\n",ulButtonPressCounts);7 E3 Y8 r) f( q. F' j+ i  E2 s% l" l3 ?
  41.         }/ y  v( J& H% g
  42. }
    - c7 D6 f+ [5 @& C

  43. 4 ]1 Z, `; P3 D: |* I0 [3 d
  44. /**; x1 ?" W- [8 g7 Y
  45. * @brief EXTI line detection callback.
    ! }" Q  g3 z7 t' t8 ?% u
  46. * @param GPIO_Pin: Specifies the pins connected EXTI line
    ) w/ {* E" L8 g$ J4 r2 y) x
  47. * @retval None
    * Z4 H% l) {5 p
  48. */3 T" C1 D6 Y- ?. J$ g0 O
  49. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)9 S% B9 J5 t3 A" f: \
  50. {
    * O- s! ^; l( l: W
  51.         if(GPIO_Pin == KEY_BUTTON_PIN)
    2 C( J4 u1 X! ]0 E
  52.         {
    ! e# ]/ u$ P7 A& l, z$ B
  53.                 if (uwIncrementState == 0)
    : H: ~$ q1 a+ K- h3 U2 t2 Z
  54.                 {
    * {: j$ a: w7 F
  55.                         /* Change the Push button state *// K" l3 y& t( M5 b
  56.                         uwIncrementState = 1;1 P7 k' b- F! Q  T- o; l- \
  57.                 }
    6 B0 C8 G4 q6 v: ^
  58.                 else! M* [; b' X- C4 g
  59.                 {3 g7 Q; a) L: @+ W( Y8 _
  60.                         /* Change the Push button state */
    - @7 C1 g9 T8 O/ `* ^" b
  61.                         uwIncrementState = 0;
    9 F, M+ r  r2 ]2 A" X
  62.                 }; N2 B) _/ A7 z7 w3 I
  63.         }  
    % o5 T. M0 g/ Z  E2 e
  64. }
    , m3 k& G1 ?) r9 d5 F1 e
复制代码
    主函数中使用xSemaphoreCreateBinary() 创建信号量,
  1. xTestSemaphore = xSemaphoreCreateBinary();
复制代码
    按键检测任务中使用xSemaphoreTake()函数来获取信号量。按键检测使用外部中断,信号量使用完毕后的释放也是在终端服务函数中,如下
) `- n, j" H+ i6 k% x
  1. xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );  //获取信号,传入创建的信号量句柄xTestSemaphore
复制代码
  1. /**
    $ @( Q8 b( J. @
  2. * @brief  EXTI15_10 IRQ5 S+ Y4 }8 Z3 w  a6 S
  3. * @param  None
    1 A3 e4 s0 X+ T
  4. * @retval None
    ; L, i2 [/ R8 R
  5. */
    6 ]& [' B% j' s
  6. void EXTI15_10_IRQHandler(void)( Z: K6 O$ {% }2 p9 G4 B
  7. {5 D: P- D1 F0 o( a' {
  8.         
    - r, M2 a: M% Q5 J( [6 z! X: I- Y
  9.         static BaseType_t xHigherPriorityTaskWoken;                     
    ) ~# U: D% f. c, V' V/ d" {
  10.         
    * E' O( u% _8 Y, j6 q' ~( K
  11.         /* Inerrupt message handling */9 K8 n  A7 C- `# B: J3 U
  12.         HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);                % E; @( R2 `6 M6 f4 R
  13.         
    . U4 D" m! N/ {- P
  14.         /* The handler releases a semaphore.
    ! u3 O; T! ^; h6 r* b8 r4 ]
  15.         xHigherPriorityTaskWoken has been initialised to zero. */
    8 N- p8 M- P' E
  16.         - N/ b" T5 z, j% L/ f% P+ q* U; w- J
  17.         if (utime_tick >= 200)7 K, q0 L6 f' g0 t7 E) z+ c% y
  18.         {
    : }( S1 b) y2 F3 s# [: q3 l
  19.                 /* The second parameter of the send sync signal is used to save ' A- a: f* B4 y: x% B# I
  20.                 whether a high-priority task is ready.*/
    3 A1 B  F- I9 P2 ]5 O8 L
  21.                 xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );        * P  S% G( u' q3 _3 o  T8 M
  22.                 utime_tick = 0;! R& z  G  h5 X5 ^" O4 P' A* g  P
  23.         }
复制代码

2 }+ o/ k# ]6 s! @0 ?) V& O% t* v5 {1 m' \' }0 s
       程序运行后会执行LED闪烁任务按键计数任务,当获取到信号量后计数值加1,同时释放信号量共下次资源可用。运行效果如下       C(HBH$]QP{3[)V]GZJ6EWHF.png ! r, X8 p; U7 V$ s1 a0 ^, T0 {% R+ r

4 R, k+ Q' }6 C
收藏 评论0 发布时间:2018-4-14 23:11

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版