尝试在FreeRTOS上使用STM32F4发现板上的二进制信号量会产生一些奇怪的(甚至是错误的)结果。二元信号在创建后解锁?
首先,对FreeRTOS的文件说:
SemaphoreHandle_t xSemaphoreCreateBinary(无效);
创建二进制信号量的函数。二进制信号量可以是 ,或者不可用,因此是二进制的。
信号量是在'空'状态下创建的,这意味着信号量 必须先使用xSemaphoreTake()函数获取(获取)之后才能给出。
这很好,因为在那种情况下,一些Thread1等待先前创建的信号量直到它解除阻塞(Thread2给出信号量),所以它听起来非常棒!
因此与运行FreeRTOS操作系统和下面的代码STM32F4发现板开始,人会想到调用osSemaphoreWait(myBinarySem01Handle,osWaitForever),直到另一个线程与osSemaphoreRelease疏导它会阻塞线程,但它不工作。 似乎信号量创建后,它需要调用osSemaphoreWait两次,使其工作。
/* 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应该在创建之后被阻止。