Stm32 二进制信号量在创建后解除阻塞?
尝试将STM32F4发现板上的二进制信号量与FreeRTOS一起使用会产生一些奇怪(甚至错误)的结果 首先,FreeRTOS的文档说明: 信号量handle_t xSemaphoreCreateBinary(void) 创建二进制信号量的函数。二进制信号量是 可用或不可用,因此为二进制 信号量是在“empty”状态下创建的,这意味着信号量 必须先给出,然后才能使用 xSemaphoreTake()函数 这很好,因为在这种情况下,一些Thread1会等待前面创建的信号量,直到它解除阻塞(Thread2提供信号量),所以听起来很好 所以,从运行FreeRTOS和下面代码的stm32f4发现板开始,人们会期望对osSemaphoreWait(myBinarySem01Handle,osWaitForever)的调用会阻止线程,直到另一个线程使用osSemaphoreRelease解除对它的阻止,但它不起作用。 似乎在创建信号量之后,需要调用osSemaphoreWait两次才能使其工作。Stm32 二进制信号量在创建后解除阻塞?,stm32,freertos,Stm32,Freertos,尝试将STM32F4发现板上的二进制信号量与FreeRTOS一起使用会产生一些奇怪(甚至错误)的结果 首先,FreeRTOS的文档说明: 信号量handle_t xSemaphoreCreateBinary(void) 创建二进制信号量的函数。二进制信号量是 可用或不可用,因此为二进制 信号量是在“empty”状态下创建的,这意味着信号量 必须先给出,然后才能使用 xSemaphoreTake()函数 这很好,因为在这种情况下,一些Thread1会等待前面创建的信号量,直到它解除阻塞(Threa
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
/* USER CODE BEGIN Includes */
#include "gpio.h"
/* USER CODE END Includes */
/* Variables -----------------------------------------------------------------*/
osThreadId defaultTaskHandle;
osThreadId myTask02Handle;
osSemaphoreId myBinarySem01Handle;
osSemaphoreId myBinarySem02Handle;
osSemaphoreId myCountingSem01Handle;
osSemaphoreId myCountingSem02Handle;
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Function prototypes -------------------------------------------------------*/
void StartDefaultTask(void const * argument);
void StartTask02(void const * argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
/* Hook prototypes */
/* Init FreeRTOS */
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* Create the semaphores(s) */
/* definition and creation of myBinarySem01 */
osSemaphoreDef(myBinarySem01);
myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);
/* definition and creation of myBinarySem02 */
osSemaphoreDef(myBinarySem02);
myBinarySem02Handle = osSemaphoreCreate(osSemaphore(myBinarySem02), 1);
/* definition and creation of myCountingSem01 */
osSemaphoreDef(myCountingSem01);
myCountingSem01Handle = osSemaphoreCreate(osSemaphore(myCountingSem01), 2);
/* definition and creation of myCountingSem02 */
osSemaphoreDef(myCountingSem02);
myCountingSem02Handle = osSemaphoreCreate(osSemaphore(myCountingSem02), 2);
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of myTask02 */
osThreadDef(myTask02, StartTask02, osPriorityNormal, 0, 128);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
}
/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
HAL_GPIO_TogglePin(LD6_GPIO_Port,LD6_Pin);
osSemaphoreWait(myBinarySem01Handle,osWaitForever);
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(LD6_GPIO_Port,LD6_Pin);
osDelay(1000);
}
/* USER CODE END StartDefaultTask */
}
/* StartTask02 function */
void StartTask02(void const * argument)
{
HAL_GPIO_TogglePin(LD5_GPIO_Port,LD5_Pin);
osDelay(5000);
osSemaphoreRelease(myBinarySem01Handle);
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(LD5_GPIO_Port,LD5_Pin);
osDelay(2000);
}
/* USER CODE END StartTask02 */
}
/* USER CODE BEGIN Application */
/* USER CODE END Application */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
那么,这种行为的原因是什么呢?它在文档中明确指出sempahore应该在创建后进行阻止。阅读更多文档后发现了问题,vSemaphoreCreateBinary()宏的语义与xSemaphoreCreateBinary()函数不同 vSemaphoreCreateBinary()宏在第一次调用xSemaphoreTake()时不会阻塞,这与xSemaphoreCreateBinary()在第一次调用xSemaphoreTake()时阻塞大不相同
之所以发生这种情况,是因为osSemaphoreCreate()函数正在调用vSemaphoreCreateBinary()函数,如上所述,该函数创建一个非空的二进制信号量