请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
TLLED 发布时间:2018-4-17 10:26
接上篇:STM32超低功耗平台上的RTOS培训 -- 实验1 任务创建
8 g* E, |! G6 A8 H1 R" B. [/ U( I$ c& J" F& c2 P2 c- i

/ }7 M- \1 v1 n' Z- D* B0 I# W: o  V( e" N2 S
FreeRTOS中断方式的二值信号量是实现中断函数与任务之间的同步。
- ]( ?* l9 k( n' `8 \6 i4 c$ R! o
- T3 Q) ^+ N2 `6 W' A
5 K2 l$ l7 F- Q5 O: c. G
    程序任务框图:3 p4 p# F; z+ K$ i; _! E; v0 U* ?
    下面是本程序实现中断函数与任务之间同步的框图:
3 s! P% G, D1 J/ B$ p
      1.jpg
5 D6 c& s. i5 E/ T5 R6 W
8 {3 S' b) d: ]' a4 |8 B; m( B" \+ L! K! ]
     程序执行的条件:% R! F+ E# @" K% ~' W# p
    > 创建两个任务:一个任务vAppStartTask()用于LED2指示灯闪烁;: g4 y3 J: L7 o5 {! G
                              一个任务prvAppButtonTask()用与等待中断后,通过串口发送按键次数;" {7 i( o3 D6 o. `5 n
    > 二值信号量的初始值为0,按键中断调用xSemaphoreGiveFromISR();函数释放信号量。任务prvAppButtonTask()调用xSemaphoreTake()函数获取信号量资源。9 `( X3 I. A. S, q& v: u
   执行过程描述:
8 z2 j: Q  K" T1 Q6 Q: M: f! N    > 任务vAppStartTask()用于LED2指示灯闪烁,和信号量之前没有关联;6 g6 K* D1 D3 i4 r  E
    > 任务prvAppButtonTask()运行过程中调用xSemaphoreTake()函数,由于信号量的初始值为0,没有信号量资源可用,任务prvAppButtonTask()由运行态进入到阻塞态,串口无数据输出。
4 m5 U3 g4 x+ b. ^$ x) z8 j% t    > 按键后,发生外部中断,中断发生,中断程序中调用xSemaphoreGiveFromISR()函数,释放信号量资源,信号量数值加1,此时信号量计数值为1,任务prvAppButtonTask()由阻塞态进入就绪态,在调度器的作用下由就绪态进入到运行态。任务prvAppButtonTask()获得信号量后,信号量数值减1,此时信号量值又变成0。
# M* [8 X1 c# Q' I+ x+ }  Q' S4 ^    > 再次循环执,任务prvAppButtonTask()由于没有信号量资源可用,再次进入阻塞态重复执行。
1 C1 }4 q: ]! }) Y$ e$ ?; D- X

2 P) X+ U0 r) `    程序执行:
9 t, M& {  ]* G        > 板子上LD2闪烁5 }+ c  \4 h; m  I
        > 串口输出数据: 按一下板子上B1 USER按键,串口输出一帧数据。
6 b' l8 R$ c+ e+ {    2.jpg " s# P( B2 f' t* E

9 _) Z3 G, k7 M* |! T    程序相关的代码:为了便于查看有关信号量相关的函数位置,只截取程序中相关函数。6 ]7 K9 d- q" k
) g. k- D! U6 E0 U
int main(void)
( S, `4 p# |: a! D- B{
' F+ h6 F9 P2 w! r1 K. j5 q8 d) @) ?        HAL_Init();
9 b2 @# X2 m1 X" k3 J( x+ T8 D        SystemClock_Config();" w# [) j, Z; H; [) ~
        __HAL_RCC_PWR_CLK_ENABLE(); //Modified by ST MCU China Team, Added by JWR 2018.01.29
% V* `- i+ l- `/ d        + m( g- D! T7 z7 F& p
        /* Initialize LED */3 A+ Y/ D9 P# L: u3 M
        BSP_LED_Init(LED1);
' X; T+ ^. g5 A9 F        BSP_LED_Init(LED2);# F# F9 \- Q9 g, t. i
        
- |! T  t0 J3 ~# f6 Y        /* Initialize buttons */6 Y& u9 M% f" [2 }, m
        BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
6 s' H+ Q: m1 ]/ w        ! a3 B0 g$ y1 R' S2 r. V7 g6 |
        /* Configure  Uart */
5 U! M) H) y# r        BSP_Uart_Init();8 s- A: r6 x9 K' T9 P8 C- C
        
; f2 T/ b7 B& V( j( F4 ~        " b: T: B* e: i% T# W/ [* S
        //vSemaphoreCreateBinary( xTestSemaphore );+ P1 V$ j+ Q8 S8 @1 E$ i8 f, M
        xTestSemaphore = xSemaphoreCreateBinary();   //创建二值信号量,首次创建信号量计数值为0
/ e+ c# }2 S+ P) n        xTaskCreate(
& Y" E( \. o/ b8 q+ X# e  p                     vAppStartTask, ' n, c* f8 S' u+ Q$ ]4 ?( [
                     "Start",
1 V- Z6 p4 A( }7 Y: `5 P                     configMINIMAL_STACK_SIZE, 3 n1 {1 F; E8 X9 f6 Z& j% `* u6 Q  ~
                     NULL,
/ [, C2 a" y; n( W" q6 S5 w                     Start_TASK_PRIORITY, * s* U/ |" W5 `; T- Z3 H1 y4 Z
                     ( TaskHandle_t * ) NULL
) V" t. R* R* Y9 Q# h                    );
( Z4 g+ o  @+ \8 F6 X        
: h; S2 j, U! g9 z/ `( f        xTaskCreate( ) Q  D3 ]0 R; \" }( H
                      prvAppButtonTask,
# u; a7 M# N, s4 j                      "ButTest", / s9 ^$ A* X! I: s9 P
                      configMINIMAL_STACK_SIZE,
- O( }8 V* H- g6 v& k+ o: q0 v                      ( void * ) NULL, 4 _% N, w1 M. |, J. N0 O
                      But_TEST_PRIORITY,
9 h- P7 S( z6 l" n9 w( p& D4 u9 P" u                      NULL + D4 W8 o2 L$ p
                   );: w. v! l4 w; I
        
0 }9 X- t9 z% ?, e        vTaskStartScheduler();6 ?% }. C  \0 `9 [3 Y
        for (;;);
2 @9 Q1 t/ |2 a, z}- s+ V% U: D$ @0 }3 o$ N, x2 Z
8 ]' G( O; }) X3 A; i
/**
8 A9 X2 B$ P# z& l9 A) f* @brief  Start a Task.- u6 O2 T2 `. U+ B" j
* @param  argument: Not used
3 h9 f8 n  }: j* N2 r* @retval None
0 D% M: D) I1 m1 d*/
# H7 U, D+ a' e- Kstatic void vAppStartTask( void *pvParameters )
% |) U$ J9 w' K2 Z+ X3 a" j{
8 ?- l+ K  t2 d" [        (void) pvParameters;
6 q3 B# \0 l" [- q. A  L        * W  P% j, e5 P- A4 q0 V2 }
        for(;;)
; h0 j6 D3 e4 h+ f$ X6 V  n2 B        {
/ w; h. f1 V# a6 `$ E( Y7 X- _2 N                BSP_LED_Toggle(LED2);
) j. u, v. @7 U! r8 h                vTaskDelay(200);+ X5 e( n1 s" s9 N
        }* {5 G: p" L$ [! R  ^
}
+ J9 ]+ `) j0 I5 K" g+ M+ F
! ^; U2 e; C! O; f* H6 q) s( d/**8 R5 G- Y* h4 ^2 F. _" V' K
* @brief  Button Task.
* ?- f. c5 o8 `8 p+ ]: q- k* @param  argument: Not used
; a! F3 Q' Y' r; g* @retval None% Z: h, T8 `; g! j$ I  J
*/
! l% M+ Q2 K/ A2 G6 Sstatic void prvAppButtonTask( void *pvParameters )
2 L: H. F  T/ N8 r{! V  c+ W$ B5 c9 \
        configASSERT( xTestSemaphore ); // The assert 函数确定信号量是否有效$ V: O  p. `5 l- s: o' t
        
4 n$ ^3 t$ \  R- `" D        //获取信号量,等待时间为0,则xSemaphoreTake()在信号量无效时会立刻返回; l( p3 i* b2 p
        xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );9 H0 V2 v* J4 p! R
        " }; G  N: @9 A3 h
        for( ;; )
" e0 e7 N2 I7 p+ a        {9 h' e4 U' A& l9 B
                xSemaphoreTake( xTestSemaphore, portMAX_DELAY ); //获取信号量,超时时间为portMAX_DELAY值
+ l  u8 F9 h) m9 I( {: D+ A( S                ulButtonPressCounts++;
- A9 t" g4 U4 V4 \7 o0 A" [; v                printf("Button Press Counts:%d\r\n",ulButtonPressCounts);
0 E/ v3 r3 A8 |# N9 o5 D        }) C/ R# R2 ?' w) L5 f- L% V9 t# `
}. r. `$ y. ~( {
1 y4 s( z7 U) ^8 M& ?5 T. U
/**/ `$ P. J, a; N' K( @
* @brief EXTI line detection callback.
& [* @: X8 L$ V3 O4 k% |* @param GPIO_Pin: Specifies the pins connected EXTI line* r* @' B8 ^! H+ A3 T( @6 ?
* @retval None
& n. f: d: U/ i*/
  p% P1 h6 f) I* Cvoid HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)* D2 ]( ]* Q! G0 N% Z
{
6 p- `2 y% @2 O3 I2 n        if(GPIO_Pin == KEY_BUTTON_PIN)9 r3 D" v8 Q( }0 a2 c; ~% k
        {
. v& }, c) j9 N' Y$ A                if (uwIncrementState == 0)
+ Z" `  q+ M4 X& Z                {) K3 Y/ ~1 p5 s  w: N3 Y2 b& k, R
                        /* Change the Push button state */# U5 v/ K5 u5 \5 ]
                        uwIncrementState = 1;
$ ~0 i" D& _. v9 P8 q/ c                }
" i* l: I& I2 K* h5 ]                else5 F1 R" g1 i' ?1 L& h0 B: e
                {
7 H% L4 q7 P" N; O# V                        /* Change the Push button state */
  P& e  l3 T1 [+ R& D; B( B                        uwIncrementState = 0;5 W- b3 E4 B! W
                }
& g2 Z  R. ]9 F$ Y6 }3 ]: j+ R        }  3 F5 s4 m  Y8 I/ ?0 w& _
}! q$ R* G  `" G0 x* \# l

3 \. b, ]5 u5 R8 t8 p: ~0 Z/**
0 v' F) S5 G: Y+ M2 {, \( |* @brief  EXTI15_10 IRQ( h, D6 s* _# u6 }1 V/ m8 k
* @param  None9 `$ `! V9 c+ \4 E; S
* @retval None0 |0 m0 i4 \$ q" I  _# C" w1 h
*/
3 d2 P3 S7 A% E$ S9 }void EXTI15_10_IRQHandler(void); q% i7 B$ X9 D  I
{
+ [, r  _$ {% U8 V& t, U        9 _' o4 `/ L$ f- e" l+ V
        static BaseType_t xHigherPriorityTaskWoken;  //高优先级任务是否被唤醒的状态保存                    
& [! `4 e# |" J4 @+ Q4 {$ ^        3 _! e6 x  |  ^) A. E& @
        HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);    //中断消息处理                             
. W2 U) F% `0 V" g0 }! p. {# e7 E       & F% X/ L8 w/ R* V; w' ~) k
        if (utime_tick >= 200)
7 d6 a( J& d1 I        {
5 e  i, C; V% {9 s' a: f                /* The second parameter of the send sync signal is used to save
2 n4 f' s# x9 d, d# ^7 n1 F                whether a high-priority task is ready.*// e( x2 o& r7 N, @  ~
                xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );        
; f  G- s% ]. S5 b" u* N9 B% a                utime_tick = 0;1 a- z+ ^9 W8 d& ^
        }! Y; b& X, b$ r6 _
        //如果 xHigherPriorityTaskWoken = pdTRUE,则切换到当前最高任务执行,然后退出中断 7 h: I9 R+ J( n  C" N, W
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
5 L' X% w# I$ t* U8 l" h7 p6 B( X}) s2 m  @1 k1 S
9 u5 G0 I8 R5 z* g
& {! J# i& K. l* Y( g
/**
! d5 {( o- X2 n, S. b( ~* @brief  FreeRTOS Tick Hook FUNC  W1 p1 D5 i) U: j( s
* @param  None' N( P6 f6 |6 y1 f4 l6 I9 j
* @retval None
" b8 g: C9 p0 t' N& q9 _*/
- Q7 s1 A; c1 G0 I, H0 r+ p) B+ Bvoid vApplicationTickHook(); R: q; ~: {6 U+ q: B, W6 m' G* r
{9 R/ G9 T8 X1 F+ h9 G
        utime_tick++;        /*Use for button glitch filter,It's not for the freertos kernel*/
& l6 d: L2 s0 x0 y# i( T# m0 O5 q        if (utime_tick >= 65535)
! u" F8 X3 S* W/ [( F+ P. C4 v# C        {
. p; Z  {, N. ~" \                utime_tick = 200;
' n; @6 T) x4 b2 h# i& R( s; L1 u        }# t. Z7 Y# r$ u& B: Z5 z9 ~
}/ k8 j/ _2 {6 ?0 `+ l. O

6 p: w( T! I' \# g) Z" Y; Z. s
# Q' L! e7 e# t/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
4 v7 h% w! s4 `' F1 B' d3 A$ q# D7 Q; @" n; P' G; x" o

8 R+ `4 F; S4 [1 i/ ~
6 S7 D  p6 Z0 {  y& M4 \
! V+ N0 J. V3 C6 t* Z7 a# E4 q

  m$ u6 i' T/ t& n! W6 b, f( Q

- ]7 M8 Y& W1 z3 Z
( O. r/ O# l0 w* x$ G1 J! c7 ~7 D
! H- ~1 D7 d' r9 @7 |/ [* s- m) s5 I/ `) C. t1 t+ Q; x- f/ y

8 [  n2 ^7 F8 [) n* O! P! k8 E, w
收藏 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 手机版