前言
本文主要介绍什么是二值信号量和二值信号量的基本操作。
一、什么是二值信号量
信号量名副其实就是一个信号可以进行任务之前信息的交互,二值信号量通常用于互斥访问或同步。二值信号量就是一个只能保存一个数据的队列,这个队列要么是空要么是有他就只有两种状态。
二、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);//调用延时才会释放资源
- }
- }
复制代码 总结
二值信号量的大致操作和介绍就是这样了。
|