> 文档中心 > STM32FreeRTOS二值信号量的基本介绍和操作

STM32FreeRTOS二值信号量的基本介绍和操作

文章目录

  • 前言
  • 一、什么是二值信号量
  • 二、cubeMX配置
  • 三、代码编写
  • 四、二值信号量具体操作
  • 总结

前言

本文主要介绍什么是二值信号量和二值信号量的基本操作。

一、什么是二值信号量

信号量名副其实就是一个信号可以进行任务之前信息的交互,二值信号量通常用于互斥访问或同步。二值信号量就是一个只能保存一个数据的队列,这个队列要么是空要么是有他就只有两种状态。

二、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);//调用延时才会释放资源}}

总结

二值信号量的大致操作和介绍就是这样了。