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

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

前言

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


一、什么是二值信号量

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


二、cubeMX配置

1.选择添加一个二值信号量

image.png2.设置二值信号量

这里比较简单我们只需要设置一下二值信号量的名字即可。

image.png

三、代码编写

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

总结

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

相关文章
|
6月前
|
存储 异构计算
LabVIEW FPGA中可重入和非可重入子VI的区别
LabVIEW FPGA中可重入和非可重入子VI的区别
54 0
|
4月前
STM32CubeMX FreeRTOS 互斥锁
STM32CubeMX FreeRTOS 互斥锁
163 12
|
4月前
|
Linux
【Linux】生产者消费者模型——环形队列RingQueue(信号量)
【Linux】生产者消费者模型——环形队列RingQueue(信号量)
41 0
|
5月前
|
消息中间件 API
【FreeRTOS(二)】FreeRTOS新手入门——计数型信号量和二进制信号量的基本使用并附代码解析
【FreeRTOS(二)】FreeRTOS新手入门——计数型信号量和二进制信号量的基本使用并附代码解析
|
6月前
LabVIEW编程NI 6602计数器DMA冲突例程与相关资料
LabVIEW编程NI 6602计数器DMA冲突例程与相关资料
54 7
【STM32】详解独立看门狗的本质和使用步骤&代码
【STM32】详解独立看门狗的本质和使用步骤&代码
|
6月前
|
存储 安全 Linux
【探索Linux】P.19(多线程 | 线程的概念 | 线程控制 | 分离线程)
【探索Linux】P.19(多线程 | 线程的概念 | 线程控制 | 分离线程)
50 0