信号量——二值信号量

2023-05-16

信号量——二值信号量

信号量简介

信号量是操作系统的重要部分,信号量一般用来进行资源管理和任务同步。FreeRTOS中信号量分为二值信号量、互斥信号量、计数信号量和递归互斥信号量,应用场景各不同。

在这里插入图片描述

二值信号量

二值信号量简述

二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常相似,但互斥信号量有优先级,二值信号量没有。因此二值信号量更适合用于同步,而互斥信号量适用于简单的互斥访问。二值信号量就是只有一个队列项的队列,这个特殊队列只有两种情况满的或者空的。

二值信号量函数

二值信号量创建

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二值信号量获取

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二值信号量释放

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二值信号量实验

要求

在这里插入图片描述

程序

主程序

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "beep.h"
#include "string.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"


//优先级
#define START_TASK_PRIO		1
#define TASK1_TASK_PRIO		2
#define DATAPROCESS_TASK_PRIO 3

//堆栈大小
#define START_STK_SIZE 		256 
#define TASK1_STK_SIZE 		256  
#define DATAPROCESS_STK_SIZE  256  
//句柄
TaskHandle_t StartTask_Handler;
TaskHandle_t Task1Task_Handler;
TaskHandle_t DataProcess_Handler;
//任务函数
void start_task(void *pvParameters);
void task1_task(void *pvParameters);
void DataProcess_task(void *pvParameters);

//二值信号量句柄
SemaphoreHandle_t BinarySemaphore;	

//用于命令解析用的命令值
#define LED1ON	1
#define LED1OFF	2
#define BEEPON	3
#define BEEPOFF	4
#define COMMANDERR	0XFF

//字符串小写转大写
void LowerToCap(u8 *str,u8 len)
{
	u8 i;
	for(i=0;i<len;i++)
	{
		if((96<str[i])&&(str[i]<123))	//小写字母
		 str[i]=str[i]-32;				//转大写字母
	}
}

//命令函数,将字符串变成命令
u8 CommandProcess(u8 *str)
{
	u8 CommandValue=COMMANDERR;
	if(strcmp((char*)str,"LED1ON")==0) CommandValue=LED1ON;
	else if(strcmp((char*)str,"LED1OFF")==0) CommandValue=LED1OFF;
	else if(strcmp((char*)str,"BEEPON")==0) CommandValue=BEEPON;
	else if(strcmp((char*)str,"BEEPOFF")==0) CommandValue=BEEPOFF;
	return CommandValue;
}

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	delay_init(168);			
	uart_init(115200);     				
	LED_Init();		        			
	KEY_Init();						
	BEEP_Init();					

	my_mem_init(SRAMIN);            

	
	//创建任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名字
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传给任务的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //  任务句柄          
    vTaskStartScheduler();          //开启任务调度器
}

//开始任务
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
	
	//创建二值信号量
	BinarySemaphore=xSemaphoreCreateBinary();	
    //创建任务1
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建任务2
    xTaskCreate((TaskFunction_t )DataProcess_task,     
                (const char*    )"keyprocess_task",   
                (uint16_t       )DATAPROCESS_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )DATAPROCESS_TASK_PRIO,
                (TaskHandle_t*  )&DataProcess_Handler); 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//task1任务
void task1_task(void *pvParameters)
{
	while(1)
	{
		LED0=!LED0;
        vTaskDelay(500);             	
	}
}

//DataProcess_task任务
void DataProcess_task(void *pvParameters)
{
	u8 len=0;
	u8 CommandValue=COMMANDERR;
	BaseType_t err=pdFALSE;
	
	u8 *CommandStr;

	while(1)
	{
		if(BinarySemaphore!=NULL)
		{
			err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY);	//获取信号量
			if(err==pdTRUE)										//成功
			{
				len=USART_RX_STA&0x3fff;						//得到数据长度
				CommandStr=mymalloc(SRAMIN,len+1);				//申请内存
			
				CommandStr[len]='\0';							//加结束符
				LowerToCap(CommandStr,len);						//转大写	
				CommandValue=CommandProcess(CommandStr);		//命令解析
				if(CommandValue!=COMMANDERR)
				{
				
					printf("命令:%s\r\n",CommandStr);
					switch(CommandValue)						//处理命令
					{
						case LED1ON: 
							LED1=0;
							break;
						case LED1OFF:
							LED1=1;
							break;
						case BEEPON:
							BEEP=1;
							break;
						case BEEPOFF:
							BEEP=0;
							break;
					}
				}
				else
				{
					printf("命令无效!!\r\n");
				}
				USART_RX_STA=0;
				memset(USART_RX_BUF,0,USART_REC_LEN);			//串口接受缓存区清0
				myfree(SRAMIN,CommandStr);						//释放内存
			}
		}
		else if(err==pdFALSE)
		{
			vTaskDelay(10);      
		}
	}
}


串口中断服务函数程序


```c
extern SemaphoreHandle_t BinarySemaphore;	//二值信号量句柄

void USART1_IRQHandler(void)                	//中断服务函数
{
	u8 Res;
	BaseType_t xHigherPriorityTaskWoken;
	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接受
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收数据
		if((USART_RX_STA&0x8000)==0)//接受未完成
		{
			if(USART_RX_STA&0x4000)//接收到0x0d
			{
				if(Res!=0x0a)USART_RX_STA=0;//接受错误
				else USART_RX_STA|=0x8000;	//接收成功
			}
			else //没有收到0X0D
			{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接受出错  
				}		 
			}
		}   		 
	} 
	
	//释放二值信号量
	if((USART_RX_STA&0x8000)&&(BinarySemaphore!=NULL))//接收到数据,并且是二值信号量
	{
		xSemaphoreGiveFromISR(BinarySemaphore,&xHigherPriorityTaskWoken);	//释放二值信号量
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//任务切换
	}
} 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

信号量——二值信号量 的相关文章

  • 二维小游戏,飞机大战,图片素材

    二维小游戏 xff0c 飞机大战 xff0c 图片素材 高清大图下载链接 https download csdn net download qq 45706825 15042600
  • hallib_RTC

    RTC 一 配置参数 1 2 只有使能RTC之后才能选LSE 二 编写应用代码 1 在mspinit里面加上这个函数 xff0c 打开秒中断 xff0c 这个函数在 h文件里面 span class token function HAL R
  • hullib_Tim3TiggerAdc1

    Tim3TiggerAdc1 只有Tim3才可以用更新 xff08 TIM TRGO UPDATE xff09 触发adc xff0c 其他定时器都要用输出比较模式才可以 一 cubmax配置 1 配置tim3为500ms更新 xff0c
  • hullib_AdcBase

    AdcBase 也就是不用中断 xff0c 每次用软件触发的简单操作 一 cubmax配置 1 选好通道就可以了 xff0c 其他都不用管 二 需要编写的代码 1 在main函数while里面写上 span class token keyw
  • hullib_eeprom

    EEPROM 这个模拟iic真的搞了好久啊 xff0c 最后发现这个24c02写完之后至少要延时4ms再来读才可以 xff0c 要不然读的时候都是NACK 一 时序 自己看数据手册吧
  • hullib_PwmCapture

    PwmCapture 需要两个channel 一 cubemx配置 一个上升沿捕获 xff0c 一个下降沿捕获 打开中断 二 自己写的代码 1 开启两个通道的中断 span class token function HAL TIM IC S
  • 2021-03-16

    hullib Rtc 获取时间之后必须获取日期他才会有时间 HAL RTC GetTime amp hrtc amp sTime RTC FORMAT BIN HAL RTC GetDate amp hrtc amp sDate RTC F
  • hullib_PwmOutput

    hullib PwmOutput 一 cubmx需要配置的 1 这里一定是pwm Generation 而不是pwm outcompare 使用定时器的PWM模式只能在4个通道产生频率相同但占空比不同的输出信号 使用定时器的输出比较模式可以
  • 计算机类非全日制研究生

    北京市 10002 中国人民大学 院系所专业研究方向考试范围 159 信息学院 xff08 专业学位 xff09 085400 专业学位 电子信息 02 软件工程领域 xff08 非全 xff09 详情 159 信息学院 xff08 专业学
  • 史上最详细的Docker 镜像的制作-上传-拉取--部署(阿里云)

    Docker 镜像的制作 上传 拉取 部署 一 镜像 xff08 images xff09 1 什么是镜像 xff1f 2 镜像的组成和用途 xff08 1 xff09 Dockerfile xff08 2 xff09 scratch xf
  • 机动目标跟踪-Singer模型,当前统计模型,交互多模型与卡尔曼滤波的结合

    文章目录 非机动目标跟踪算法原理一 Singer 模型算法二 当前统计模型算法三 交互多模型算法 实验仿真一 低机动情况1 1 Singer模型参数设置1 2 当前统计模型参数设置1 3交互多模型参数设置1 4 对比分析 二 一般机动情况2
  • 用大白话解析函数调用,系统调用和API之间的关系

    一 官方的解释 大概了解一下 函数调用 函数调用是计算机编或运行时 xff0c 使用某个函数来完成相关命令 系统调用 系统调用是用户在程序中使用 访管指令 调用由操作系统提供的子功能集合 API 应用编程接口 xff08 Applicati
  • docker删除所有容器和镜像

    确保自己有权限 xff0c 一般先执行下面的命令获取管理员权限 span class token function sudo span span class token function su span 1 杀死运行的容器 xff1a sp
  • Docker镜像制作与仓库搭建

    Docker 1 xff0c docker镜像制作2 xff0c docker仓库搭建 1 xff0c docker镜像制作 docker官方和个人发布的镜像由于版本等各种原因 xff0c 漏洞较多 xff0c 已统计Docker Hub超

随机推荐

  • 2019年全国大学生电子设计竞赛赛题分享与浅析

    0 ti杯2019年全国大学生电子设计竞赛赛题已于今晨公布 其中赛题分为本科组与高职高专组 xff1a 本科组 xff1a A 电动小车动态无线充电系统 B 巡线机器人 C 线路负载及故障检测装置 D 简易电路特性测试仪 E 基于互联网的信
  • springboot整合canal实现对mysql数据库实时监控

    canal Canal介绍Mysql环境准备安装canalspringboot整合canal Canal介绍 官网地址 xff1a https github com alibaba canal canal k n l xff0c 译意为水道
  • tensorflow2.6.0安装 another metric with the same name already exists

    终端直接输入pip install tensorflow 61 61 2 6 0 但是这里有一点问题 span class token keyword import span os span class token keyword impo
  • Java编程心得体会

    初次学习Java编程的心得与体会 之前学习过c语言 xff0c python编程 xff0c 对比Java编程首先感觉到的区别就是Java环境配置比较复杂 xff0c 编程工具安装比较麻烦 课堂上老师讲到首先下载安装jdk xff0c 然后
  • Ubuntu18.04+ROS-melodic环境 px4+move_base仿真遇到的问题

    前前后后安了三个虚拟机 xff0c 折腾了快一个月了吧 第四次用双系统终于实现了 每次都有不同的坑 1 错误 xff1a gz symbol lookup error usr lib x86 64 linux gnu libgazebo c
  • 【谷粒学院】项目总结

    做谷粒学院这个项目大概花了2个多月的时间 xff0c 期间遇到了很多问题 xff0c 想要记录下来 xff0c 希望可以对别人有所帮助 首先谷粒学院项目我是不太推荐时间紧张的友友拿来做为毕设项目的 xff0c 原因是里面涉及到的技术 服务很
  • 完美解决make -f Makefile.unx报错问题 +Centos

    这里写自定义目录标题 本人亲测成功 导读 xff1a 我用这个命令主要是针对编译hadoop的 xff0c 其中有个isa l安装 xff0c 是英特尔 ISA L技术即 xff08 Intel Intelligent Storage Ac
  • 关于Gitee创建存储库多人协作流程

    关于Gitee创建存储库多人协作流程 主要解决在IDEA工具开发下通过Gtiee多人协作 xff0c 共同开发 前期准备 IDEA xff1a IDEA当前文档使用版本为2021 3 1 Git xff1a IDEA安装Gitee插件 流程
  • ajax上传文件,图片并显示与删除(spring boot)

    思路 xff1a 先上传文件然后在读出来 之前本人都是用form提交上传文件 xff0c 现在写个ajax的文件上传 先看下效果 xff1a 上传并在页面显示 关键代码 xff1a 在启动类里面加入 span class token com
  • opencv-python——调用摄像头或导入视频实现颜色识别并画框

    采用opencv进行颜色识别有个好处就是他的框可以是具有角度的长方体框 xff0c 不局限于平行点的 文章目录 颜色识别实现过程1 调用摄像头 导入视频或读入照片2 找出所需颜色对应的HSV阈值3 找出二值化后的图片中的特征点并进行画框 完
  • Ubuntu18.04——python2安装opencv4.1版本并代替ROS自带的低版本opencv

    软件环境 Ubuntu 18 04系统ROS melodic 查看安装ROS默认安装的CV2位置 改个名 xff0c 不要是cv2就ok xff1a 查看是否移除 可以发现还有一个cv2的so文件 xff0c 所以我们需要将这个也移除 改个
  • 直流电机驱动电路设计-----学习笔记

    直流电机驱动电路的设计目标 在直流电机驱动电路的设计中 xff0c 主要考虑一下几点 xff1a 1 功能 xff1a 电机是单向还是双向转动 需不需要调速 对于单向的电机驱动 xff0c 只要用一个大功率三极管或场效应管或继电器直接带动电
  • ROS——问题解决:rqt工具包中image_view消失;bash: rosrun rqt_image_view未找到命令

    重装rqt工具 span class token function sudo span span class token function apt get span span class token function install spa
  • VS Code——Git插件使用指南

    文章目录 一 基于VScode本地新建工程并上传到Github1 新建工程文件夹并用Vscode打开该文件夹2 初始化存储库3 暂存更改4 提交暂存更改5 同步到Github中6 在Github中查看项目 二 Git clone到本地后进行
  • Ubuntu18.04——查看CPU, GPU,内存利用率

    htop查看CPU和内存利用率 sudo apt install htop 启动htop htop 查看NVIDIA GPU利用率 nvidia smi 以每秒1次的刷新频率实时查看 nvidia smi l 1
  • Ubuntu18.04——基于X86和Arm安装并配置Realsense-ros环境

    文章目录 基础安装1 安装ROS2 安装Realsense驱动以及依赖库 xff08 1 xff09 X86安装librealsense更新 xff08 2 xff09 Arm编译安装librealsense xff08 或者Apt无法下载
  • 【Rt-Thread】STM32输出PWM

    1 实验目标 STM32输出不同频率的占空比为50 的PWM信号 xff0c 控制蜂鸣器音调 2 硬件部分 2 1 模块介绍 xff08 1 xff09 主控芯片 F405RGT6 xff08 2 xff09 蜂鸣器 低电平触发 2 2 接
  • 考研复试实用指南

    Preface 考研初试已经结束 xff0c 但是考研这场仗还没打完 xff0c 接下来 xff0c 我们将走入复试的战场 考研复试并不是走过场 xff0c 是有严格的淘汰比例的 xff1b 考研复试并不是关系网 xff0c 是有公开而透明
  • 2020oop第一次练习 6-3 字符串 - 6. 查找子串(BF算法) (10分)

    C语言标准函数库中包括 strstr 函数 xff0c 在主串中查找子串 作为练习 xff0c 我们自己编写一个功能与之相同的函数 函数原型 char StrStr const char txt const char pat 说明 xff1
  • 信号量——二值信号量

    信号量 二值信号量 信号量简介 信号量是操作系统的重要部分 xff0c 信号量一般用来进行资源管理和任务同步 FreeRTOS中信号量分为二值信号量 互斥信号量 计数信号量和递归互斥信号量 xff0c 应用场景各不同 二值信号量 二值信号量