FreeRTOS信号量---二值信号量

信号量可以用来进行资源管理和任务同步,FreeRTOS中信号量又分为二值信号量、计算型信号量、互斥信号量和递归互斥信号量。

0x01 二值信号量

二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的,任务和中断不用在乎队列中存的是什么消息,只需要知道这个队列是满的还是空的,可以利用这个机制完成任务与中断之间的同步。

1. 创建二值信号量

在这里插入图片描述
vSemaphoreCreateBinary

vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
  • xSemaphore :保存创建成功的二值信号量
    此函数是老版本FreeRTOS创建二值信号量函数,新版本已经不再使用。

xSemaphoreCreateBinary:

SemaphoreHandle_t xSemaphoreCreateBinary( void )

此函数是新版本FreeRTOS中统一使用此函数来创建二值信号量,使用此函数创建二值信号量的话,信号量所需要的内存是有FreeRTOS的内存管理部分动态分配的,此函数创建好的二值信号量默认是空的,也就是说创建好的二值信号量使用函数xSemaphoreTask是获取不到的。

xSemaphoreCreateBinaryStatic

SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
  • pxSemaphoreBuffer :保存信号量结构体
    此函数创建二值信号量所需要的内存需要由用户分配
2. 释放信号量

在这里插入图片描述

xSemaphoreGive

xSemaphoreGive( SemaphoreHandle_t xSemaphore )
  • xSemaphore:要释放的信号量句柄
    此函数用于释放二值信号量、计数型信号量或互斥信号量

xSemaphoreGiveFromISR

 xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken)
  • xSemaphore:要释放的信号量句柄
  • BaseType_t *pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换,此值为pdTRUE的时候在退出中断之前一定要进行一次任务切换

此函数只能用来释放二值信号量和计数型信号量

3. 获取信号量

在这里插入图片描述
xSemaphoreTake

xSemaphoreTake(*                   SemaphoreHandle_t xSemaphore,*                   TickType_t xBlockTime*               )
  • SemaphoreHandle_t xSemaphore:要获取信号量的句柄
  • TickType_t xBlockTime:阻塞时间
    此函数用于获取二值信号量、计数型信号量或互斥信号量

xSemaphoreTakeFromISR

 xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken)
  • SemaphoreHandle_t xSemaphore:要获取信号量的句柄
  • BaseType_t *pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换,等于pdTURE一定进行任务切换
4. 验证

设计一个通过串口发送指定的指令来控制开发版上的LED1和BEEP开关的实验。指令如下:
LED1ON:打开LED1
LED1OFF:关闭LED1
BEEFON:打开BEEF
BEEFOFF:关闭BEEF
设计三个任务,功能如下:
start_task:用来创建其他2个任务
task1_task:控制LED0闪烁,提示系统正在运行
DataProcess_task:指令处理任务,根据接收到的指令来控制不同的外设
实验中还创建一个二值信号量BinarySemaphore用于完成串口中断和任务DataProcess_task之间的同步。

DataProcess_task函数

void DataProcess_task(void *pvParameters)
{u8 len = 0;u8 CommandValue = COMMANDERR;BaseType_t err = pdFALSE;u8 *CommandStr;POINT_COLOR = BLUE;while(1){if(BinarySemaphore!=NULL){err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY);	//获取信号量if(err==pdTRUE)										//获取信号量成功{len=USART_RX_STA&0x3fff;						//得到此次接收到的数据长度CommandStr=mymalloc(SRAMIN,len+1);				//申请内存sprintf((char*)CommandStr,"%s",USART_RX_BUF);CommandStr[len]='\0';							//加上字符串结尾符号LowerToCap(CommandStr,len);						//将字符串转换为大写		CommandValue=CommandProcess(CommandStr);		//命令解析if(CommandValue!=COMMANDERR){LCD_Fill(10,90,210,110,WHITE);				//清除显示区域LCD_ShowString(10,90,200,16,16,CommandStr);	//在LCD上显示命令printf("命令为:%s\r\n",CommandStr);switch(CommandValue)						//处理命令{case LED1ON: LED1=0;break;case LED1OFF:LED1=1;break;case BEEPON:BEEP=0;break;case BEEPOFF:BEEP=1;break;}}else{printf("无效的命令,请重新输入!!\r\n");}USART_RX_STA=0;memset(USART_RX_BUF,0,USART_REC_LEN);			//串口接收缓冲区清零myfree(SRAMIN,CommandStr);						//释放内存}}else if(err==pdFALSE){vTaskDelay(10);      //延时10ms,也就是10个时钟节拍	}}
}

DataProcess_task是用来申请获取信号量,如果申请到了,就往下执行,如果没事申请到,就会一直阻塞,申请到之后,对数据做处理,然后做出相应的回应。

串口1中断服务程序

//串口1中断服务程序
void USART1_IRQHandler(void)                	
{ u32 timeout=0;u32 maxDelay=0x1FFFF;BaseType_t xHigherPriorityTaskWoken;HAL_UART_IRQHandler(&UART1_Handler);	//调用HAL库中断处理公用函数timeout=0;while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪{timeout++;超时处理if(timeout>maxDelay) break;		}  timeout=0;while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1{timeout++; //超时处理if(timeout>maxDelay) break;	}//释放二值信号量if((USART_RX_STA&0x8000)&&(BinarySemaphore!=NULL))//接收到数据,并且二值信号量有效{xSemaphoreGiveFromISR(BinarySemaphore,&xHigherPriorityTaskWoken);	//释放二值信号量portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换}
} 

串口1中断服务程序是用来接收串口发送的数据,如果接收完毕,将会释放二值信号量,DataProcess_task才能往下执行,如果没有接收完数据或者没有接收到数据,DataProcess_task会一直阻塞。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 上 rpm包管理工具的基本使用

查询是否安装某个包:rpm -q 包名查询所有已安装的包:rpm -q a查询未安装包的文件信息:rpm -qilp 未安装的包安装包:rpm -i 包测试安装包:rpm -i test 包删除包:rpm -e 包名测试删除包:rpm -e te…

ios 内存使用陷阱

在iphone开发过程中,代码中的内存泄露我们很容易用内存检测工具leaks 检测出来,并一一改之,但有些是因为ios 的缺陷和用法上的错误,leaks 检测工具并不能检测出来,你只会看到大量的内存被使用,最后收到didR…

FreeRTOS软件定时器

软件定时器允许设置一段时间,当设置的时间达到后就执行指定的功能函数,被软件定时器调用的功能函数叫做定时器的回调函数。软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何阻塞任务的API函数,比…

Java类class isAssignableFrom()方法及示例

类class isAssignableFrom()方法 (Class class isAssignableFrom() method) isAssignableFrom() method is available in java.lang package. isAssignableFrom()方法在java.lang包中可用。 isAssignableFrom() method is used to check whether the class or an interface den…

关于 列表实例

wss3.0工具中有个列表实例项目。此项目的作用是在自定义网站或自定义字段时使用默认值。也就是定义其默认的数据。 格式详见微软msdn:http://msdn.microsoft.com/zh-cn/library/ms478860.aspx转载于:https://www.cnblogs.com/heavencloud/archive/2009/03/20/141793…

WP7之Application Bar控件

Microsoft.Phone.Shell命名空间中定义了ApplicationBar及其相关类(ApplicationBarIconButton和ApplicationBarMenuItem),这些类派生自Object,并完全独立于常规Silverlight编程中的DependencyObject,UIElement和FrameworkElement类层次结构。A…

TomCat使用以及端口号被占用的处理方法

一.HTTP协议 什么是HTTP协议 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 HTTP请求 HTTP响应 2.如何处理端口被占用 方法一&#xff…

FreeRTOS事件标志组

使用信号量来同步的话,任务只能与单个事务或任务进行同步,有时候某个任务可能会需要与多个事件或任务进行同步,此时信号量就无能为力了,FreeRTOS为此提供了一个可选的解决方法,那就是事件标志组。 0x01 事件标志组 事…

FusionCharts等产品简介

以前做柱状图、饼形图等图表都是根据数据绘制出来的静态图,偶然看到别人的一套系统,居然可以让柱状图的柱子动画般的逐个出现,效果还是很不错的。不要跟我抬杠说不就是展现数据嘛,静态图表有什么不好,要知道用户一般可…

c#foreach循环_C#| 使用foreach循环打印整数数组

c#foreach循环Given an integer array and we have to print its elements using "foreach loop" in C#. 给定一个整数数组,我们必须在C#中使用“ foreach循环”打印其元素 。 Syntax for foreach loop: foreach循环的语法: fore…

Eclipse和Tomcat绑定并且将上传资源到Tomcat上

步骤如下: 创建一个Dynamic Web Project(图一) Target runtime 选择Apache Tomcat v7.0版本(图二) 切记要选择 v7.0 和2.5 (若没有图二选项见图三) 然后,点击window --> Prefer…

浅析.NET平台编程语言的未来走向

在去年的PDC2008召开期间,微软逐步公开了围绕.NET和编程语言的很多想法,据此我们可以饶有兴趣地对.NET的未来预测一番。 .NET平台以运行在通用语言运行时(Common Language Runtime,CLR)上的C#和VB.NET作为开端。CLR是通用语言架构(Common Lan…

FreeRTOS任务通知

从v8.2.0版本开始,FreeRTOS新增了任务通知这个功能,可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西,使用任务通知的话效率会更高。 任务通知在FreeRTOS是一个可选的选项,要使用任务通知的话就需要将宏configUSE_T…

kinect在openni下也能玩抠出人物换背景

之前想了个很拉风的名字《用kinect玩穿越》,但是现在功能还不是很完善,细节处理也不是很好,脸皮没有足够的厚,所以呢还是叫换背景吧。 这里面包含两个技术要点: 一、抠出活动人物 在微软的SDK里深度图像的前3位即0-2位…

物联网基础知识_联网| 基础知识能力问答 套装1

物联网基础知识1) There are the following statements that are given below, which of them are correct about the computer network? A computer network is an interconnection between multiple devices to share hardware resources and information.A computer networ…

Emit学习-基础篇-基本概念介绍

之前的Hello World例子应该已经让我们对Emit有了一个模糊的了解,那么Emit到底是什么样一个东西,他又能实现些什么功能呢?昨天查了点资料,大致总结了下,由于才开始学习肯定有不完善的地方,希望大家能够批评指…

The FreeRTOS Distribution(介绍、移植、类型定义)

1 Understand the FreeRTOS Distribution 1.1 Definition :FreeRTOS Port FreeRTOS目前可以在20种不同的编译器构建,并且可以在30多种不同的处理器架构上运行,每个受支持的编译器和处理器组合被认为是一个单独的FreeRTOS Port。 1.2 Build…

notepad++节点_在C ++中删除链接列表的中间节点

notepad节点Given a single Linked List and we have to delete the middle the element of the Linked List. 给定一个链表,我们必须删除链表中间的元素。 If the length of the linked list is odd then delete (( n1)/2)th term of the linked list and if the…

SET ANSI_NULLS ON

指定在与 Null 值一起使用等于 () 和不等于 (<>) 比较运算符时采用符合 ISO 标准的行为。 当 SET ANSI_NULLS 为 ON 时&#xff0c;即使 column_name 中包含空值&#xff0c;使用 WHERE column_name NULL 的 SELECT 语句仍返回零行。即使 column_name 中包含非空值&…

Eclipse项目左上角出现大红色感叹号怎么办?

出现大红色感叹号是因为环境不匹配 解决方法&#xff1a; 右击出现大红色感叹号的项目 点击 Libraries&#xff0c;将有叉号的给Remove掉 然后再点击 Add Library —> JRE System Library —> Next 勾选第二个即可 之后&#xff0c;就不会出现大红色感叹号了。