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

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

[复制链接]
TLLED 发布时间:2018-4-17 10:26
接上篇:STM32超低功耗平台上的RTOS培训 -- 实验1 任务创建) o' W) T9 n" j6 y9 M! x
/ |7 t" `1 l4 {; w! k

; C+ Z. _+ F- V2 [" S9 k
' K) X; m! b8 u9 W; mFreeRTOS中断方式的二值信号量是实现中断函数与任务之间的同步。

8 A! s: D$ n# V  M+ ~; F- F4 t& G% O9 k9 V$ B% M0 P
1 _$ P1 }) {! G+ D2 Z4 |3 A
    程序任务框图:( U3 Q, P/ _# r! X4 {
    下面是本程序实现中断函数与任务之间同步的框图:
% ~3 A+ V% c7 _/ D- m3 i9 s+ I0 C
      1.jpg
+ j. s- n' w8 t; P# ]+ W1 C, K4 u( F$ W9 U) r

0 ?: F: I3 U, j6 j4 {     程序执行的条件:
. G; t( v1 f- R    > 创建两个任务:一个任务vAppStartTask()用于LED2指示灯闪烁;
" Y( j- _8 i! v/ P                              一个任务prvAppButtonTask()用与等待中断后,通过串口发送按键次数;) C( a" U/ M! n7 u
    > 二值信号量的初始值为0,按键中断调用xSemaphoreGiveFromISR();函数释放信号量。任务prvAppButtonTask()调用xSemaphoreTake()函数获取信号量资源。/ u! C2 ]! q6 P+ z9 ?
   执行过程描述:) `/ X& M9 F/ e0 a" a, l6 E! x
    > 任务vAppStartTask()用于LED2指示灯闪烁,和信号量之前没有关联;
6 N0 ^. U5 |" R9 f2 {8 f9 C; r    > 任务prvAppButtonTask()运行过程中调用xSemaphoreTake()函数,由于信号量的初始值为0,没有信号量资源可用,任务prvAppButtonTask()由运行态进入到阻塞态,串口无数据输出。- g% H  t1 J1 i# I% i
    > 按键后,发生外部中断,中断发生,中断程序中调用xSemaphoreGiveFromISR()函数,释放信号量资源,信号量数值加1,此时信号量计数值为1,任务prvAppButtonTask()由阻塞态进入就绪态,在调度器的作用下由就绪态进入到运行态。任务prvAppButtonTask()获得信号量后,信号量数值减1,此时信号量值又变成0。
) V& B% z0 t2 O    > 再次循环执,任务prvAppButtonTask()由于没有信号量资源可用,再次进入阻塞态重复执行。
- H2 }( G, d# ?1 z2 a8 z
; j& x  B: e8 Q6 W* s
    程序执行:4 I* p% R7 x, B2 {; E8 e
        > 板子上LD2闪烁# y( ~4 x# ]% g' N$ k
        > 串口输出数据: 按一下板子上B1 USER按键,串口输出一帧数据。! B, F. L" l+ _8 g; E, ~
    2.jpg
5 k! f/ c) J1 z2 l( J1 l
* r  `, ^& D  Y, q! H    程序相关的代码:为了便于查看有关信号量相关的函数位置,只截取程序中相关函数。' @: f4 D, L1 b3 U1 K
2 X1 o- B! ]; d# C4 N
int main(void)
" j) ?# I2 E, _0 b  o! S{
% F" A5 V# P/ H1 L- _5 Q9 f8 b        HAL_Init();1 Z! n, x0 R; [5 C- P! b6 N( S( @+ M
        SystemClock_Config();) m4 G& N/ l: C* A8 R0 k
        __HAL_RCC_PWR_CLK_ENABLE(); //Modified by ST MCU China Team, Added by JWR 2018.01.29
+ S8 }- f0 }! E: c% n- T1 a9 e        
) f8 [+ F3 c3 |' x        /* Initialize LED */
. V6 c  K1 G0 |; J        BSP_LED_Init(LED1);7 u. [% z4 N! z! }1 X
        BSP_LED_Init(LED2);( V5 C+ S/ z9 _' A
        
  N; J, [4 K% t2 }/ |( G" e& P        /* Initialize buttons */( z- Q1 Q+ U: r4 Z* ?
        BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
, O: z: p4 F. v3 a. I; ~        
; ?4 m- q1 }1 q3 V, `        /* Configure  Uart */# M8 }- J! i- [/ H/ m% s  t
        BSP_Uart_Init();
( g; E; X% u+ u        
8 z& Q) z6 B! Q9 L* r+ l& H9 r        
( G! f. D- @' @8 d( I: Q1 W. [        //vSemaphoreCreateBinary( xTestSemaphore );
! T0 X/ z- v3 K8 u        xTestSemaphore = xSemaphoreCreateBinary();   //创建二值信号量,首次创建信号量计数值为0
% i2 I7 P4 u8 m; j/ ?6 o9 n2 b        xTaskCreate(
: R: r$ b- r& I  U& R. h  z                     vAppStartTask, , t" o  M6 _% }
                     "Start", & F5 o+ A4 `% a+ w0 G' q) L
                     configMINIMAL_STACK_SIZE, $ s0 \. W' S6 O, T! u4 i6 t! y
                     NULL, 0 b' |, m+ S; S! X: F0 M0 ~
                     Start_TASK_PRIORITY, / b8 ~1 j4 p" G- n8 Z
                     ( TaskHandle_t * ) NULL
+ H/ O- q, M5 g2 q0 N% t1 u                    );
- |7 N# V- P3 t* z& [  Q        3 G' {  v5 ?* P
        xTaskCreate( 3 y6 L! j$ E* I% K: Q. [
                      prvAppButtonTask, & ^  M1 T* V5 @! ]
                      "ButTest",
, i6 h6 N1 @* q& r0 @" {                      configMINIMAL_STACK_SIZE,
, y* M) p) T1 [6 P7 n! _                      ( void * ) NULL,
+ a; W: D, k3 g7 }. t                      But_TEST_PRIORITY, - w1 @4 j6 M: e9 W
                      NULL % P- K+ v' I. w2 E- H: U, [
                   );
9 f0 x# W# Y8 @/ p/ s0 a' P+ N        * `' m9 U7 b* k6 @' T2 V8 |1 p8 Y% G
        vTaskStartScheduler();
9 n, I. M1 Q; R- M$ B        for (;;);, q) Y& s& k$ N9 p# h
}
  B# u) F3 }, S0 U% `  z: T9 K% _2 F' t% w0 z( t# g& C% t
/**
9 @" X# H0 U. n) p3 l* @brief  Start a Task.
% p: q  W: {" y/ K, _0 E- a* @param  argument: Not used$ d+ j  Z2 A, u  K
* @retval None
! w4 q7 M- f1 i. C/ V& M*/
. L( j/ N' G( j9 ]  [static void vAppStartTask( void *pvParameters )
4 G( [; d, d  _' [/ f8 g( s{
3 H; _! n5 k8 E- N: I) f% C7 V  r        (void) pvParameters;: I$ i" U. @6 x4 `8 n2 z3 j0 [- X
        
" g/ q7 H/ @4 V: f% Y        for(;;)9 t0 q  d% f% o2 |1 t/ A/ p
        {. D, @/ S5 X: ]% C: d1 D" h) o
                BSP_LED_Toggle(LED2);
! ?: T8 S0 X1 W) ]5 J- M  D. }# ]                vTaskDelay(200);
9 w" e2 K! A$ `% m; R        }. f" K8 ]$ T/ N1 m) M0 x) [6 y
}7 A& A9 a" x" @
8 [/ P  O( @( c% A5 x9 S9 Q: D8 S
/**
! ^4 V: Y: `- C( R* @brief  Button Task.5 O9 X+ A  J9 q5 H5 `  s8 p/ t  _5 \) G
* @param  argument: Not used
/ J1 X( y0 ?, [* @retval None" N, d- O9 Y" }8 o; r
*/
4 z- {( x8 J* wstatic void prvAppButtonTask( void *pvParameters )' @! {) e, S0 H/ l) H& w9 T' o
{% ~  K( n8 ]- p$ s, D- h7 C" V
        configASSERT( xTestSemaphore ); // The assert 函数确定信号量是否有效
$ }  B( i9 O% N5 {        
* i, D, k/ Y) Y4 Q$ z' v0 {/ m& d        //获取信号量,等待时间为0,则xSemaphoreTake()在信号量无效时会立刻返回2 L0 z  }* ^2 {
        xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );# q  a; s5 K8 V( J2 A! \( W
        5 F3 ^6 }$ |% d+ ?8 x+ A
        for( ;; )+ A2 W- z7 B0 x# S3 |% w; k* |
        {
; j( ^7 j. ?  R/ \1 C+ d                xSemaphoreTake( xTestSemaphore, portMAX_DELAY ); //获取信号量,超时时间为portMAX_DELAY值$ u. P! [% t- L) Q% f4 H
                ulButtonPressCounts++;- k- [2 d8 b* p
                printf("Button Press Counts:%d\r\n",ulButtonPressCounts);
( z$ e7 b, J  I5 A+ h        }% z* f/ z* W4 i2 A3 P
}
, r/ c# T; s0 @$ i- z
5 ?4 Y1 a9 \7 n9 W- t; V3 ?/**' _  s* ~. K, t8 Z; X7 @8 z
* @brief EXTI line detection callback.8 f1 o' e1 Y& W
* @param GPIO_Pin: Specifies the pins connected EXTI line
# f; U2 C7 H& z, Y5 }* @retval None
7 q5 }' T5 r) N5 p0 G*/& a( K" Y) g+ }8 v) D
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin), C) W6 s' V% Q
{7 J; w& `: @' T" Q- g4 o" L. e" ^
        if(GPIO_Pin == KEY_BUTTON_PIN); P0 r+ K6 e) p+ Q- b# r# k
        {- H, b2 I& x+ r3 M; |
                if (uwIncrementState == 0)3 W, |/ K* |, w: p# W/ W: o
                {
+ ?0 I1 j4 \  r) A) ^4 D. V                        /* Change the Push button state */: s, ~! c3 M% b- v
                        uwIncrementState = 1;2 l1 L' M, Q: M  h1 {. U$ K
                }0 G- g# N* r5 m! o
                else
4 s2 i7 g# v! R, T                {$ c" c) E, A! X. o
                        /* Change the Push button state */! r7 D" s  Q# J4 Q
                        uwIncrementState = 0;
1 [1 p3 l; f! v" m9 |' ]# G% S                }+ T: w2 s8 R1 I, C5 ]
        }  8 H/ w) O( X7 ^" R8 l) q& D8 g
}
! D; x) \$ z2 J5 Z* ?, s
9 V+ Y& s$ l) ^2 H& Q/**$ L$ o3 b' [8 K8 x. ]
* @brief  EXTI15_10 IRQ5 _0 i5 P+ x0 G% a6 I: V- h
* @param  None- V" Z; G; n$ F* z% u/ P
* @retval None7 T9 x5 g/ J' j8 @/ J6 V. C
*/
, l2 {% A) A" d3 `5 jvoid EXTI15_10_IRQHandler(void); N/ f0 H5 x4 }" V! E& D/ t+ `
{
9 u8 v0 G: K5 w$ F        ' R/ w/ C# A9 t( ]5 l
        static BaseType_t xHigherPriorityTaskWoken;  //高优先级任务是否被唤醒的状态保存                    9 X# T4 X) A  j
        ( D: M# \& s6 w- F) _5 k
        HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);    //中断消息处理                             
4 X( {( |, F3 c% U* P5 C      
0 I- {6 l  w! a" {        if (utime_tick >= 200)
3 m3 v" j/ @2 O9 `2 X4 T" \        {
/ i7 e4 p/ e0 a                /* The second parameter of the send sync signal is used to save , p$ L  Z5 [8 o0 \
                whether a high-priority task is ready.*/5 `) u# \, y7 [. k4 N8 n: W5 V
                xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );        ( [5 K2 G9 x: @4 T
                utime_tick = 0;
! K4 y3 Z7 c. t  |, i        }
/ M9 @+ U2 ~3 m2 a- M        //如果 xHigherPriorityTaskWoken = pdTRUE,则切换到当前最高任务执行,然后退出中断 ; J6 ~: g7 g7 e7 y2 e
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );" Y) I. C! F) S8 ~- c! w
}
9 r! {  f& F0 [5 A
% s+ W/ I  B$ P5 e6 m) A
: k7 o6 g9 t- r* U! g/**
  |, R( W8 B' X( N* @brief  FreeRTOS Tick Hook FUNC
& B# z0 z# d. H* @param  None6 x* O% d; N& K$ i7 k# F
* @retval None# v9 i( w- B8 X8 z4 _& R
*/" |5 x0 N- S  g0 G
void vApplicationTickHook()
# C4 a4 W# Y! ]6 V{
; n4 l( j  \* _5 r% e% [: J        utime_tick++;        /*Use for button glitch filter,It's not for the freertos kernel*/
, g! t) q+ Z# W/ g2 P; K! X        if (utime_tick >= 65535)1 X8 \4 ?  z0 B
        {
/ |1 F5 r0 z2 o9 T! s( P# S% h                utime_tick = 200;
, W5 [! \. c! ^) N* w& ]        }! `7 `; r3 N4 D) r3 @7 h
}4 E7 B. L; @+ s: d2 i

% g9 s4 C8 o% p7 ^' ^8 i
; c& j6 f+ W0 S0 K6 Z/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
: e9 y( k% H6 q: x! e$ [4 {- D$ V5 g' W: u5 [% ~4 [+ w
2 ]/ a1 @4 |, v: {- z" j, c! C

& ~, @5 M7 i/ B% y0 e4 h6 C9 L
" S" R+ ~) r+ `* l+ {- v# N9 ?; Z* \" \: ^
$ P2 d" a9 \* w5 J

2 R+ T, \" I; }# q* P; f" V3 m7 D# e' U7 Y

) p) Y: [0 l! G6 R
8 L1 R  d2 J. X- d) d0 n2 t! X3 S8 b; u
收藏 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 手机版