了解了二元信號量相關的一些概念,可以設計相關程序進行驗證,基於STM32Cube生成的代碼。
TASK1比TASK2優先級高,驗證的初衷是TASK1S首先運行,而TASK2由於無法獲取信號量而阻塞,5S之后TASK1釋放信號量,TASK2獲得信號量解除阻塞可以執行
由於FreeRTOS的新舊版本的API不同,導致現象不同於預期,問題就在xSemaphoreCreateBinary與vSemaphoreCreateBinary的區別
用vSemaphoreCreateBinary創建的二元信號量,初始值為“滿”,因為創建的同時釋放了信號量
1 #define vSemaphoreCreateBinary( xSemaphore ) \ 2 { \ 3 ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ 4 if( ( xSemaphore ) != NULL ) \ 5 { \ 6 ( void ) xSemaphoreGive( ( xSemaphore ) ); \ 7 } \ 8 }
而xSemaphoreCreateBinary創建二元信號量,初始值為“空 ”
1 osSemaphoreDef(myBinarySem); 2 myBinarySemHandle = osSemaphoreCreate(osSemaphore(myBinarySem), 1); 3 4 osThreadDef(vTask1, Task1, osPriorityAboveNormal, 0, 128); 5 vTask1Handle = osThreadCreate(osThread(vTask1), NULL); 6 7 /* definition and creation of vTask2 */ 8 osThreadDef(vTask2, Task2, osPriorityNormal, 0, 128); 9 vTask2Handle = osThreadCreate(osThread(vTask2), NULL); 10 11 /* Task1 function */ 12 void Task1(void const * argument) 13 { 14 15 /* USER CODE BEGIN Task1 */ 16 static uint32_t cnt = 0; 17 /* Infinite loop */ 18 for(;;) 19 { 20 Debug_Printf("Task1 is running,will be in the ready state!\n"); 21 osDelay(1000); 22 cnt++; 23 if(cnt == 5) 24 { 25 osSemaphoreRelease(myBinarySemHandle); 26 cnt = 0; 27 } 28 } 29 /* USER CODE END Task1 */ 30 } 31 32 /* Task2 function */ 33 void Task2(void const * argument) 34 { 35 /* USER CODE BEGIN Task2 */ 36 /* Infinite loop */ 37 for(;;) 38 { 39 if(osOK == osSemaphoreWait(myBinarySemHandle,osWaitForever)) 40 Debug_Printf("Task2 is running!\n"); 41 //osDelay(50); 42 } 43 /* USER CODE END Task2 */ 44 }
當使用vSemaphoreCreateBinary如下打印信息,TASK2一開始並沒有阻塞
當使用xSemaphoreCreateBinary如下打印信息,前5S,TAKS2一直被阻塞