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

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

[复制链接]
BinWin 发布时间:2018-4-14 23:11
接上篇:RTOS超低功耗平台应用---FreeRTOS启动&任务创建% O: X" p  r. W: D5 F* p6 `

" q) N# m3 i9 U2 c% P  P
: m- i% b& q' x0 x5 H
0 p# R$ E; {$ ?# P/ a. f7 R( N     首先了解一下信号量,一般信号量主要实现两个功能:
! w- O6 c# m2 H# H7 {. ^     1,两个任务之间或者中断函数跟任务之间的同步功能% S* @$ g0 X- Q, ~7 P; m$ v. H
     2,多个共享资源的管理
& D5 w+ ~/ H" i! v; \- ^  c    FreeRTOS针对这两种功能分别提供了二值信号量和计数信号量,其中二值信号量可以理解成计数,即初始化为仅有一个资源可以使用。( q+ |# f1 `" A* U+ n$ n" X
    实验是创建一个线程,该线程通过ISR发出的信号量打印按钮按下计数,包含一个LED闪烁任务。2 d& ?8 s8 @! g  {9 ]
  1. /**
    4 s, m  {3 b; l
  2. * @brief  Start a Task.' I; L' U* ~- i
  3. * @param  argument: Not used+ Q/ k: }/ D8 j4 v3 v0 x  e" j4 t! a
  4. * @retval None5 M, `: p- ~: @. F  J# P* v8 C" U
  5. */1 o" |5 F0 f2 V  B
  6. static void vAppStartTask( void *pvParameters )1 x2 s% O; B! r5 u0 K9 s6 V
  7. {3 E% V# X+ g2 ]% X
  8.         (void) pvParameters;. N" q1 t) f( r1 ^+ c( z4 j
  9.         
      J& d' ]* d& t! ?7 L! {- \
  10.         for(;;)6 ^& q& W& {5 ^, d  A3 K  q  w
  11.         {8 e  ~8 w3 M. m! l* H9 R1 z
  12.                 BSP_LED_Toggle(LED2);
    ! ~0 @1 m% N; c9 ~
  13.                
    + @, Q& n" i$ n" B( _, B) Q4 z; ~
  14.                 vTaskDelay(200);
    7 y- Q+ q# Y. m: h& l
  15.         }% L6 P9 l4 W4 O3 E8 [5 p! |
  16. }5 y) R+ c1 s* B! j* J$ S% r3 Q

  17. " o* ]2 B$ V7 `/ d% A+ v
  18. /**
    6 D0 n+ D5 F3 S/ Z: y2 Z0 A8 @* E
  19. * @brief  Button Task.) F+ H( i  S1 ]+ {  W/ t( _
  20. * @param  argument: Not used
    ; z/ U# a$ c' m! W/ L4 b
  21. * @retval None) r. F- h2 O- h% J; j
  22. */
    & d, g+ ?* g3 h+ d: D0 H
  23. static void prvAppButtonTask( void *pvParameters )# O; K3 [3 j( M8 X- D' M' }
  24. {
    + k3 ~8 B0 E% H2 F, T
  25.         configASSERT( xTestSemaphore ); /* The assert function determines whether the semaphore is valid. *// P+ F) Q, O1 f2 f
  26.         / S! i6 l! R2 W* m& J
  27.         /* This is the task used as an example of how to synchronise a task with
    : y1 ^/ H- V" c9 ~, y( o
  28.         an interrupt.  Each time the button interrupt gives the semaphore, this task7 p' Z& o+ ]7 E
  29.         will unblock, increment its execution counter, then return to block$ w# t5 l* B) I: Y. ]9 L
  30.         again. */7 K, G# L) o( D  u% ^6 H
  31.         
    1 S0 _5 Y# Q6 N. Z: `
  32.         /* Take the semaphore before started to ensure it is in the correct7 N3 ~( c" b9 r
  33.         state. */9 H1 U3 u' D9 |5 }
  34.         xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
    7 O% |# D) ~$ G% _7 d
  35.         1 y6 w+ ~! [& Q. Q
  36.         for( ;; )3 F* c+ B5 z5 s$ X/ R) B; u
  37.         {' i7 u$ u4 D+ I* m: m. X
  38.                 xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
    : I5 p0 h* {. v  h& B9 F
  39.                 ulButtonPressCounts++;
    , m" c" l) }1 z& E) D. e
  40.                 printf("Button Press Counts:%d\r\n",ulButtonPressCounts);
    + ?; u& M5 A: ~8 y
  41.         }
    ( d5 B% V  m* K7 @
  42. }* b8 c" J0 \) E8 j: \- t
  43. 7 v4 c6 t5 k* M! r) `
  44. /**
    + b) i4 F# ^5 i6 u" x6 N0 u  r0 j
  45. * @brief EXTI line detection callback.
    5 H. h2 z% M- Y9 \2 c$ v" O5 j
  46. * @param GPIO_Pin: Specifies the pins connected EXTI line
    " ?* i0 v& \) h# k
  47. * @retval None/ }, |8 h" O/ U1 F# g9 V
  48. */
    . e$ p! b# w; a2 T( e+ N
  49. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    ; Y! l- X# B3 r: \7 x% F
  50. {# @; t, k  \8 D' ^) V
  51.         if(GPIO_Pin == KEY_BUTTON_PIN)
    8 @9 d' Q" a4 M: Y' w7 p: ]
  52.         {$ b( `$ r' Z9 B) [
  53.                 if (uwIncrementState == 0)5 E6 y3 m) R' |+ S# @- i3 n* r
  54.                 {
    0 ?8 u# r& U: M: h, x
  55.                         /* Change the Push button state */2 c! T, e# A4 g7 \" Y
  56.                         uwIncrementState = 1;
    ; z4 _) ~1 a" t. ~6 ?; l8 B
  57.                 }9 s; D5 L2 `4 O' w4 E; X/ R9 q
  58.                 else
    6 O, I- s3 @0 @" u7 Y
  59.                 {
    4 p, _6 j, h/ z8 c' q3 p
  60.                         /* Change the Push button state */
    " A7 m8 V. V9 ]( e1 N. j
  61.                         uwIncrementState = 0;  G* }: P. h) j5 B6 [
  62.                 }4 M9 Z0 A( |7 g5 U, {. g. q
  63.         }  5 q$ T  o6 l2 y& z! l9 g1 Q: T
  64. }
    , D6 K  {  q. [  l6 }) ], R
复制代码
    主函数中使用xSemaphoreCreateBinary() 创建信号量,
  1. xTestSemaphore = xSemaphoreCreateBinary();
复制代码
    按键检测任务中使用xSemaphoreTake()函数来获取信号量。按键检测使用外部中断,信号量使用完毕后的释放也是在终端服务函数中,如下
& \* C: N0 }5 x
  1. xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );  //获取信号,传入创建的信号量句柄xTestSemaphore
复制代码
  1. /**. d. Q; f( G! c$ A$ ]: n
  2. * @brief  EXTI15_10 IRQ3 |3 V8 u+ V6 m5 X
  3. * @param  None
    ) s0 E( n9 e2 D$ ^+ [0 O7 m
  4. * @retval None
    & d( m" ~6 l* f1 D% l3 B
  5. */
      i% y  ^7 B; }) K, c) Q
  6. void EXTI15_10_IRQHandler(void)
    , z) u" Y1 ]( s& ?) s
  7. {% W6 ?1 M$ @9 [6 B7 J+ c
  8.         
    2 t* \: p! B/ Z
  9.         static BaseType_t xHigherPriorityTaskWoken;                      ! ~: b& A2 D: c, L& }
  10.         0 F6 k1 f, }- T/ O! V! d
  11.         /* Inerrupt message handling */
    , d4 `3 }" J4 A$ Q: Q4 P5 w+ r+ A
  12.         HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);                ! }& R$ M3 e: b
  13.         
    + O. V% H" X) F! H6 N  R
  14.         /* The handler releases a semaphore.
    & e. o4 h/ T3 v% J( w9 |& {0 ^9 Y
  15.         xHigherPriorityTaskWoken has been initialised to zero. */( ~5 r5 ]4 k7 ~5 n
  16.         
    1 O; y# O$ {' d$ I% }+ ]% S  h
  17.         if (utime_tick >= 200): x% a2 B3 f2 F8 k4 D
  18.         {
    ! V. h- P# y9 B0 S
  19.                 /* The second parameter of the send sync signal is used to save
    - Y- M6 _- ?. r6 O; m& k
  20.                 whether a high-priority task is ready.*/- q5 X! ]  s  i& I, ?
  21.                 xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );        
    # }# }& [4 C% s
  22.                 utime_tick = 0;
    9 g  J1 B- J# a1 v
  23.         }
复制代码

) [+ ^8 r! \# ]9 h  F
* [. v6 E& F, |$ i3 [       程序运行后会执行LED闪烁任务按键计数任务,当获取到信号量后计数值加1,同时释放信号量共下次资源可用。运行效果如下       C(HBH$]QP{3[)V]GZJ6EWHF.png
( W, Y2 [! n* x$ L
( w* m8 [/ o' i/ j+ p
赞 收藏 评论0 发布时间:2018-4-14 23:11

举报

0个回答

所属标签

相似技术帖

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