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 }

 

測試結果如下圖所示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM