FreeRTOS--二元信号量--任务与中断的同步

一般二元信号量用于任务同步,利用二元信号量对任务与中断同步,中断服务例程中只是释放信号量,相当于把中断应该处理的事情放到了任务里进行处理,如果某个中断处理任务特别紧急,则相应的任务优先级可以设置为最高,以保证此任务随时抢占系统中的其他任务。

 

 

使用一个定时器TIM6,每隔3秒释放一次信号量,TASK2设置优先级最高,等待信号量而被阻塞,TASK1每间隔一秒打印信息。

 1  /* Create the thread(s) */
 2   /* definition and creation of vTask1 */
 3   osThreadDef(vTask1, Task1, osPriorityNormal, 0, 128);
 4   vTask1Handle = osThreadCreate(osThread(vTask1), NULL);
 5 
 6   /* definition and creation of vTask2 */
 7   osThreadDef(vTask2, Task2, osPriorityAboveNormal, 0, 128);
 8   vTask2Handle = osThreadCreate(osThread(vTask2), NULL);
 9 
10 /* Task1 function */
11 void Task1(void const * argument)
12 {
13 
14   /* USER CODE BEGIN Task1 */
15   /* Infinite loop */
16   for(;;)
17   {
18       printf("Task1 is running,will be in the ready state!\r\n");
19       osDelay(1000);
20   }
21   /* USER CODE END Task1 */
22 }
23 
24 /* Task2 function */
25 void Task2(void const * argument)
26 {
27   /* USER CODE BEGIN Task2 */
28   /* Infinite loop */
29   for(;;)
30   {
31       if(osOK == osSemaphoreWait(myBinarySemHandle,osWaitForever))
32           printf("Task2 is running!\r\n");
33   }
34   /* USER CODE END Task2 */
35 }
36 
37 
38 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
39 {
40   /* USER CODE BEGIN Callback 0 */
41 
42   /* USER CODE END Callback 0 */
43   if (htim->Instance == TIM1) {
44     HAL_IncTick();
45   }
46   /* USER CODE BEGIN Callback 1 */
47   if (htim->Instance == TIM6)
48   {
49       g_msCount++;
50       if(3000 == g_msCount)
51       {
52           g_msCount = 0;
53           osSemaphoreRelease(myBinarySemHandle);
54       }
55   }
56   /* USER CODE END Callback 1 */

在freeRTOS标准API中释放信号量要分为xSemaphoreGiveFromISR和xSemaphoreGive,前者用于中断ISR。在STM32CUbe封装的osSemaphoreRelease内部已经区分了两者,所以只需要调用osSemaphoreRelease即可

 1 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
 2 {
 3   osStatus result = osOK;
 4   portBASE_TYPE taskWoken = pdFALSE;
 5   
 6   
 7   if (inHandlerMode()) {
 8     if (xSemaphoreGiveFromISR(semaphore_id, &taskWoken) != pdTRUE) {
 9       return osErrorOS;
10     }
11     portEND_SWITCHING_ISR(taskWoken);
12   }
13   else {
14     if (xSemaphoreGive(semaphore_id) != pdTRUE) {
15       result = osErrorOS;
16     }
17   }
18   
19   return result;
20 }

 

测试结果如下图所示:

 

posted @ 2019-09-03 15:57  M&D  阅读(2724)  评论(0编辑  收藏  举报