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

STM32超低功耗平台上的RTOS培训 -- 实验2 中断和任务同步(信....

[复制链接]
TLLED 发布时间:2018-4-17 10:26
接上篇:STM32超低功耗平台上的RTOS培训 -- 实验1 任务创建
. ]! V3 N; I+ z8 Y) H, w
4 g1 k* k0 E! c  S4 y6 o" T: @! M9 w. v$ U+ l  b/ i

- V% c8 F3 g5 W9 Q, s- ~FreeRTOS中断方式的二值信号量是实现中断函数与任务之间的同步。

% r: H$ E- B9 I- y* f$ I5 b: F4 S5 A  N1 ?7 |- ~3 _
- C# T; J8 t' w
    程序任务框图:
* Y0 \, i8 M- P- K+ d: B    下面是本程序实现中断函数与任务之间同步的框图:
9 D! n* [5 v! `
      1.jpg ; M6 \! @' w# O+ |
- d1 ~3 Z% m) p. \0 H9 d
  g- M* b! O1 n: @
     程序执行的条件:7 L+ H( G4 t! H
    > 创建两个任务:一个任务vAppStartTask()用于LED2指示灯闪烁;
7 N3 j, {: ^! t! ]( h                              一个任务prvAppButtonTask()用与等待中断后,通过串口发送按键次数;8 C2 j6 x. F' F- X+ b
    > 二值信号量的初始值为0,按键中断调用xSemaphoreGiveFromISR();函数释放信号量。任务prvAppButtonTask()调用xSemaphoreTake()函数获取信号量资源。% P7 x$ o# O; G8 D
   执行过程描述:
/ P1 V* D0 I; B# u, ^3 n( r7 U8 B    > 任务vAppStartTask()用于LED2指示灯闪烁,和信号量之前没有关联;
# S) N) |3 H+ y' i3 H    > 任务prvAppButtonTask()运行过程中调用xSemaphoreTake()函数,由于信号量的初始值为0,没有信号量资源可用,任务prvAppButtonTask()由运行态进入到阻塞态,串口无数据输出。! k1 c: l" z6 T6 ~. {4 n
    > 按键后,发生外部中断,中断发生,中断程序中调用xSemaphoreGiveFromISR()函数,释放信号量资源,信号量数值加1,此时信号量计数值为1,任务prvAppButtonTask()由阻塞态进入就绪态,在调度器的作用下由就绪态进入到运行态。任务prvAppButtonTask()获得信号量后,信号量数值减1,此时信号量值又变成0。
: |/ Q. K6 T" j! v4 Z    > 再次循环执,任务prvAppButtonTask()由于没有信号量资源可用,再次进入阻塞态重复执行。/ x2 ?) f) H1 M5 w* A/ f. v

1 p3 X+ m& H) ?9 R, y1 @& G0 Y    程序执行:$ m: o% c( B7 V& G* R% @# i% d, \
        > 板子上LD2闪烁: d- J8 i; {2 v8 p: |; A
        > 串口输出数据: 按一下板子上B1 USER按键,串口输出一帧数据。0 h; A' ]8 d) I! W1 C
    2.jpg
- u9 P0 _/ u7 f( T0 m5 x3 v" l8 z) v" v' a
    程序相关的代码:为了便于查看有关信号量相关的函数位置,只截取程序中相关函数。
9 g2 I2 ]  F  V& @: {2 @; x( u$ U  Y
int main(void)
9 K/ I! {3 }9 ~! x" D; A, T{
: g9 g) i6 y  ^0 Q- R        HAL_Init();
6 D2 c  {4 |" y/ r        SystemClock_Config();
2 R, A  ?6 ?" x, n        __HAL_RCC_PWR_CLK_ENABLE(); //Modified by ST MCU China Team, Added by JWR 2018.01.29
) \5 w- P3 ]% P: h; K        
* @) Y" W% R5 a1 {        /* Initialize LED */
1 l% {. \& z, k4 ]        BSP_LED_Init(LED1);
- t3 e3 _' a4 z! T  R$ m        BSP_LED_Init(LED2);
8 s0 z" O+ o" F9 m        
( Y. O* b# r5 W$ y. E  D        /* Initialize buttons */! N, z3 n" c+ Z
        BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
1 O2 v2 N% v2 J8 B        
+ ?4 j/ i! V0 [' a        /* Configure  Uart */7 ]7 r3 K9 a; v9 U5 j" g. }! h3 K6 C- E
        BSP_Uart_Init();; {" ?+ o; J" F
        
/ z; k& o) L, i  H( ~        
9 g5 ^9 B  c2 l4 }        //vSemaphoreCreateBinary( xTestSemaphore );: d# g# T8 S8 K
        xTestSemaphore = xSemaphoreCreateBinary();   //创建二值信号量,首次创建信号量计数值为06 w) Y# ~0 X/ q( \
        xTaskCreate( . S" f5 }$ F  i& P& |
                     vAppStartTask,
. ]6 L7 S) T( K! ]4 Z                     "Start", & J8 ?# {3 }/ E) g6 T' w6 f) @! s' i
                     configMINIMAL_STACK_SIZE, & \7 ]0 }7 w8 Q# `( }" f9 r! T
                     NULL,
# H/ T6 S+ g, w$ \" m                     Start_TASK_PRIORITY, ! [9 [7 K9 B) p
                     ( TaskHandle_t * ) NULL
7 g" ~* j) z& _; q9 m: s8 g* @4 t1 H% N                    );8 b" c; }. n) D) {
        
6 l, d! ~' z7 B: d' [6 s7 r        xTaskCreate( . K" ?/ G; o! @( }& n9 S
                      prvAppButtonTask,
: i6 o% b1 ^( F" \                      "ButTest", - V/ t0 |. _9 A9 U0 L  f
                      configMINIMAL_STACK_SIZE,
: h0 s' u: e+ i  Q; {                      ( void * ) NULL, ) B7 z* Y( _9 t1 R( m
                      But_TEST_PRIORITY, # w5 Z0 @5 r" G" b  L0 Z& [
                      NULL
$ X- Y4 Y/ c' Q. ?$ t. _' i                   );2 e) Y+ z4 p$ |$ G  h2 K
        
0 j2 G. S0 l+ p& M1 W: Q/ k, R        vTaskStartScheduler();" b7 y4 l' t: j% w0 z' |* U3 Q0 f
        for (;;);- b0 I/ W* }, h. v. n8 Z
}
# t6 d3 Y4 y6 P  n; x) t3 s0 r; \" w. A4 y6 Q6 S0 O5 F
/**/ r4 X! D# w. q4 d7 x: ?
* @brief  Start a Task.
- q( I) X  w  m# [: e1 y  K% a2 Y+ q* @param  argument: Not used' J# V5 J, d# B- c6 q: {! Q3 a
* @retval None
$ A8 }; i4 L  S. d' Z% P* k*/- T# C( f1 c( o
static void vAppStartTask( void *pvParameters )
+ f2 X) T& s* \7 V; l) \{4 T! O' @8 I8 f3 h0 L9 m0 D# p$ I
        (void) pvParameters;
: a$ N" R; p* o) M! K0 L' R        7 j, R& i7 N+ N! j3 x5 v" S2 `" m
        for(;;)
& G4 L: T2 w0 o8 X7 I. ~9 f9 D        {( G4 o( b. |' m- J# S. c* r
                BSP_LED_Toggle(LED2);7 m: A5 Z9 V. {: s/ M0 w6 {2 @! g: c
                vTaskDelay(200);
; R* ~2 E; P% c$ X* R8 U2 _        }
5 B& O; ?& ^4 `# n# s- j$ j}' w. x* j! `$ P' t5 O  p
2 t4 \0 @$ D" H* t2 Z) @
/**
- D5 [6 o' F6 r) H* @brief  Button Task.
" a0 _) x' Q0 M' e# q) v* @param  argument: Not used
/ H7 w4 o. Q: {' P* c2 P* @retval None& }5 L8 e$ P: Q% D- p# Y
*/( `7 c  M" M8 L: G( k
static void prvAppButtonTask( void *pvParameters )
& c: `: X3 p8 k/ s{1 c1 l) `" a" v2 r
        configASSERT( xTestSemaphore ); // The assert 函数确定信号量是否有效
: H7 p+ h) |4 _. u        
6 g8 s0 z6 b8 q2 J# P7 @, t  ]8 r        //获取信号量,等待时间为0,则xSemaphoreTake()在信号量无效时会立刻返回8 X0 g. E- r; i' K) u5 Q
        xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );0 K7 K; |1 C' c' j
        
- r* a( `) k- l' E' B" @, R        for( ;; )  y$ q9 Q# l3 r
        {! y* F1 ]$ @) P0 G/ Z: x
                xSemaphoreTake( xTestSemaphore, portMAX_DELAY ); //获取信号量,超时时间为portMAX_DELAY值" Q8 A* a9 a* M7 R( R9 @: Q5 q
                ulButtonPressCounts++;9 d0 ?& d6 f/ q5 k, }
                printf("Button Press Counts:%d\r\n",ulButtonPressCounts);
3 g2 [3 }- N& S9 s* b        }. o3 S! O) ]' V. X8 K" Z
}
+ H* Y" ]; w; Z0 U( b+ J7 M) x/ h0 ~5 r
; F% z$ R% p1 a- L6 W- ]/**
6 d; v3 W) y8 y* @brief EXTI line detection callback.
  ^3 v0 D+ b  n+ Q3 ?! D% `4 j* @param GPIO_Pin: Specifies the pins connected EXTI line
$ E0 a* m8 q. Z1 J9 b* @retval None
8 o( T* W/ O) O, b/ Z*/
6 g$ Y% g% e6 @% uvoid HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
* Q$ l5 {$ |2 h0 V* y3 o{
+ X/ Q! `7 _8 b9 x5 J5 v; D        if(GPIO_Pin == KEY_BUTTON_PIN)
. m4 \6 j6 l4 U  B9 m) u        {" A; ]% |7 m1 G/ m) _. \
                if (uwIncrementState == 0)+ z. a5 p1 j+ O8 H3 ~8 {
                {6 o. j- N# p! C
                        /* Change the Push button state */
: x6 M- p: o; H" b5 M                        uwIncrementState = 1;. z( b$ w0 a0 f
                }+ o4 B% i. Z& @& Y
                else
: t+ ~/ u8 s; i( P" c6 Y" e: C, W                {
' j1 V3 F/ {3 N7 u/ \$ n                        /* Change the Push button state */
- V" W4 V; q8 X* f1 L                        uwIncrementState = 0;6 O2 h+ K( Y" m4 f
                }! W; T( C5 }7 M$ j
        }  
) E# p2 }( f! c0 n, c! S: S}/ t" b; N% K7 Q, L# q1 p
/ {, u; a2 {+ {& P2 k, [
/**
7 H  R2 p( q) ?, \, }* @brief  EXTI15_10 IRQ# A( }1 v3 f. i, \, z. \0 f
* @param  None3 T" i, q3 `; n; B4 q6 s  l+ `" ^7 A
* @retval None
" v4 L! g* M: N8 d*/  c1 D  H# o+ J
void EXTI15_10_IRQHandler(void)8 N& K8 Y1 N% s* Z4 d2 ^
{2 f: `/ N7 e( }2 l; H" J/ K4 W& d
        1 u7 s! v2 w' X  n% Z. k, @
        static BaseType_t xHigherPriorityTaskWoken;  //高优先级任务是否被唤醒的状态保存                    
. i/ a' k8 z) t0 @        
8 @* D1 z& C0 g$ d0 A( X5 u        HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);    //中断消息处理                             
$ }! G( X% s' a) j% M) [! \7 G      
3 ^& q. c7 K( c8 M) X        if (utime_tick >= 200)
4 P: m& }9 W, P+ Q- r3 a* x        {
) S2 R# X& Z2 z' j; {                /* The second parameter of the send sync signal is used to save # z% T  _3 {/ ~# Y+ I4 y
                whether a high-priority task is ready.*/
; `9 p1 ^9 c) G9 f                xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );          {4 Z+ S8 l# x2 |2 y
                utime_tick = 0;
, p, R, |' d5 j% K, d        }9 t0 T/ U, \8 Z5 F5 H
        //如果 xHigherPriorityTaskWoken = pdTRUE,则切换到当前最高任务执行,然后退出中断 ) d7 q( |1 |  N6 Q+ I
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );9 P, e5 Y0 t* P  I0 W. K3 z# i
}' B7 `3 I0 v: x. D3 U

& c2 j9 P$ J0 G$ u! |( |: p
5 P" x  {9 |8 g+ \3 Q/ f/**
' e1 _; O2 I: Z- a! ~* @brief  FreeRTOS Tick Hook FUNC
  r" S0 Z; z! T3 r* @param  None/ Y9 w5 ?7 f4 S7 y( F6 }6 g
* @retval None; N! J3 l' U5 s  P; m. M
*/
9 O- |% t& q& {* B. b6 ?' D6 f% M. Uvoid vApplicationTickHook()
- ]' r4 |* v, o{
: b1 n2 c. F2 T7 N7 H        utime_tick++;        /*Use for button glitch filter,It's not for the freertos kernel*/3 |: L) r$ ^( {9 j  t
        if (utime_tick >= 65535)
3 _3 p, p8 c& j        {
5 H; [! C, F: H. M( o) `, p! i                utime_tick = 200;4 X% s9 s4 K& ^7 n5 p1 ~: f
        }2 G. b. k% B  w% @
}6 ]1 W* _) R) w) K

/ C  i) K  n3 y+ s' h" |& H: y9 b5 V$ g( l1 f0 ^# x0 Z
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
: b2 |1 A% C9 S4 f/ V1 i
  I6 d5 L9 {0 |1 T1 P4 f5 @
) I! e* D/ @% T9 m7 _
) e8 N3 ]( l0 j+ h$ s$ v; \

7 C$ r7 C1 K! D5 S# O7 _; f, S
, L6 S$ T3 h4 u/ v( @1 L/ l

8 |  V. r$ N3 g# i+ T
, c& U# ~/ l8 j7 o7 I: W5 ?# D; ?7 g

% C! x8 H/ @# i- f: R- ]9 z6 D$ l$ G7 o" J
收藏 1 评论2 发布时间:2018-4-17 10:26

举报

2个回答
zero99 回答时间:2018-4-17 14:53:16
支持下
蓝夜 回答时间:2018-7-21 10:48:13
写的很好,突出了重点

所属标签

相似分享

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