STM32FreeRTOS二值信号量的基本介绍和操作
文章目录
前言
本文主要介绍什么是二值信号量和二值信号量的基本操作。
一、什么是二值信号量
信号量名副其实就是一个信号可以进行任务之前信息的交互,二值信号量通常用于互斥访问或同步。二值信号量就是一个只能保存一个数据的队列,这个队列要么是空要么是有他就只有两种状态。
二、cubeMX配置
1.选择添加一个二值信号量
2.设置二值信号量
这里比较简单我们只需要设置一下二值信号量的名字即可。
三、代码编写
1.创建二值信号量
这部分代码cubeMX会帮我们书写好
/* definition and creation of myBinarySem01 */ osSemaphoreDef(myBinarySem01); myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1); /* USER CODE BEGIN RTOS_SEMAPHORES */
2.产生二值信号量函数
本函数cubeMX对其进行了封装,其本质还是调用了xSemaphoreGiveFromISR和xSemaphoreGive两个函数。
/* @brief Release a Semaphore token* @param semaphore_id semaphore object referenced with \ref osSemaphore.* @retval status code that indicates the execution status of the function.* @note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.*/osStatus osSemaphoreRelease (osSemaphoreId semaphore_id){ osStatus result = osOK; portBASE_TYPE taskWoken = pdFALSE; if (inHandlerMode()) { if (xSemaphoreGiveFromISR(semaphore_id, &taskWoken) != pdTRUE) { return osErrorOS; } portEND_SWITCHING_ISR(taskWoken); } else { if (xSemaphoreGive(semaphore_id) != pdTRUE) { result = osErrorOS; } } return result;}
3.接收二值信号量函数
本函数cubeMX也对其进行了封装,其本质还是调用了xSemaphoreTakeFromISR和xSemaphoreTake两个函数。
当二值信号量接收成功的时候会返回osOK。
/* @brief Wait until a Semaphore token becomes available* @param semaphore_id semaphore object referenced with \ref osSemaphore.* @param millisec timeout value or 0 in case of no time-out.* @retval number of available tokens, or -1 in case of incorrect parameters.* @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.*/int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec){ TickType_t ticks; portBASE_TYPE taskWoken = pdFALSE; if (semaphore_id == NULL) { return osErrorParameter; } ticks = 0; if (millisec == osWaitForever) { ticks = portMAX_DELAY; } else if (millisec != 0) { ticks = millisec / portTICK_PERIOD_MS; if (ticks == 0) { ticks = 1; } } if (inHandlerMode()) { if (xSemaphoreTakeFromISR(semaphore_id, &taskWoken) != pdTRUE) { return osErrorOS; }portEND_SWITCHING_ISR(taskWoken); } else if (xSemaphoreTake(semaphore_id, ticks) != pdTRUE) { return osErrorOS; } return osOK;}
四、二值信号量具体操作
osThreadId Task1TaskHandle;osThreadId Task2TaskHandle;void Task1Task(void const * argument);void Task2Task(void const * argument);osThreadDef(Task1TaskName, Task1Task, osPriorityNormal, 0, 128);Task1TaskHandle = osThreadCreate(osThread(Task1TaskName), NULL);osThreadDef(Task2TaskName, Task2Task, osPriorityNormal, 0, 128);Task2TaskHandle = osThreadCreate(osThread(Task2TaskName), NULL);//产生二值信号量任务void Task1Task(void const * argument){static u8 i=0;for(;;){//调用10次再产生二值信号量if(++i==10){osSemaphoreRelease(myBinarySem01Handle);//产生二值信号量}osDelay(5);//调用延时才会释放资源}}//接收二值信号量任务void Task2Task(void const * argument){for(;;){if(osOK==osSemaphoreWait(myBinarySem01Handle,portMAX_DELAY))//等待二值信号量采用死等的方式 { //等待二值信号量成功 }osDelay(5);//调用延时才会释放资源}}
总结
二值信号量的大致操作和介绍就是这样了。