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 }
测试结果如下图所示: