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

举报
yd_274589494 发表于 2023/07/25 11:29:24 2023/07/25
【摘要】 @TOC 前言本文主要介绍什么是二值信号量和二值信号量的基本操作。 一、什么是二值信号量信号量名副其实就是一个信号可以进行任务之前信息的交互,二值信号量通常用于互斥访问或同步。二值信号量就是一个只能保存一个数据的队列,这个队列要么是空要么是有他就只有两种状态。 二、cubeMX配置1.选择添加一个二值信号量2.设置二值信号量这里比较简单我们只需要设置一下二值信号量的名字即可。 三、代码编写1...

@TOC


前言

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

一、什么是二值信号量

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

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

总结

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。