FreeRTOS操作系统的应用

1.回顾

移植操作系统时:使用了哪三个中断服务函数?

       SVC中断服务函数:任务切换

       PendSVC中断服务函数:任务挂起

       SysTick中断服务函数:给操作系统提供时间基准

知识点内容回顾:会用

二值信号量:任务同步、确保任务的限号顺序

计数信号量:资源管理

互斥锁:保护共享资源,多个任务使用同一个资源(串口、变量)

队列:任务间数据的传输

2.事件组 一对多

相当于是一个标志位,可以实现一个任务对多个任务的同步效果

WIFI串口将数据解析、KQM6600串口数据解析、SU03T串口收到数据解析

裸机时:

        一直判断空闲标志,定义一个标志位,判断标志位没有位置时,就returen1;

操作系统:

        同样是判断这三个串口是否收到数据要去解析。若果数据没有到来,让任务直接阻塞释放CPU取执行其他任务。事件组就可以实现这个效果

事件组相关API:

        event_groups.h

        EventGroupHandlle_t  XEventGroupCreate(void);

        创建一个新的RTOS事件组,并返回 可以引用创建的时间组的句柄

设置事件组:

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToSet );

xEventGroup:要设置的事件组 。该 必须已通过 通过调用 xEventGroupCreate() 创建。

uxBitsToSet:指定要在事件组中设置的一个或者多个位的按位值。例如,将 uxBitsToSet 设置为 0x08,可仅设置位 3。 将 uxBitsToSet 设置 为 0x09,可设置位 3 和位 0。

返回:

        调用 xEventGroupSetBits() 返回时事件组的值。

        返回值可能会 清除 uxBitsToSet 参数指定的位,有如下两个原因:

  1. 如果设置某个位导致正在等待该位的任务 解除阻塞态, 则可能该位 已被自动清除(请参阅 xEventGroupWaitBits() 的 xClearBitOnExit 参数)。

  2. 将执行任何处于阻塞态(或就绪态)且优先级 高于调用 xEventGroupSetBits() 的任务, 并可能在调用 xEventGroupSetBits() 返回之前 更改事件组值。

在RTOS事件组中设置位(标志)。无法从中断调用此函数。

 xEventGroupSetBitsFromISR() 是可从中断调用的版本。

在事件组中设置位将自动解除 所有等待位的任务的阻塞态。

INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS 和INCLUDE_xTimerPendFunctionCall 必须在FreeRTOSConfig.h中全部设置为1,才能使用xEventGroupSetBitsFromISR() 函数。

 BaseType_t xEventGroupSetBitsFromISR(
                          EventGroupHandle_t xEventGroup,
                          const EventBits_t uxBitsToSet,
                          BaseType_t *pxHigherPriorityTaskWoken );
xEventGroup  

要设置位的事件组。 该 必须已通过 通过调用 xEventGroupCreate() 创建。

uxBitsToSet  指定要设置的一个或多个位的按位值。 例如,要设置位3,便将uxBitsToSet设置为0x08。 将 uxBitsToSet 设置 位3和位0,便将uxBitsToSet设置为0x09。

pxHigherPriorityTaskWoken  如上所述,调用此函数 将意味着给RTOS守护进程任务发送一条消息。 如果 守护进程任务的优先级高于 当前正在运行的任务(中断中断的任务), 那么xEventGroupSetBitsFromISR()会将*pxHigherPriorityTaskWoken设置为pdTRUE, 指示应在中断退出之前 请求上下文切换。 因此 必须将 *pxHigherPriorityTaskWoken 初始化为 pdFALSE。 请参阅 下面的代码示例。

返回:

如果消息已发送到RTOS守护进程任务,则返回pdPASS, 否则将返回pdFAIL。 如果 计时器服务队列已满,则将返回pdFAIL 。

//创建事件组句柄
/*******************事件组句柄***********************/
EventGroupHandle_t Event;
//main函数里
	//创建事件
	Event = xEventGroupCreate();
TaskHandle_t KEY_TaskHandle;
void Key_Task(void *p)
{
	uint8_t ret = 0;
	while(1)
	{
		switch(Get_Key_Val())
		{
			case 1:
				ret = xEventGroupSetBits(Event,0x01);//001
			
			break;
			case 2:
				ret = xEventGroupSetBits(Event,0x02);//011
				
				break;
			case 3:break;
			case 4:
				ret = xEventGroupSetBits(Event,0x04);//111
				
			break;//给出一个技术信号量
		}
		vTaskDelay(10);//MS级别的延时,带有阻塞性质,任务会从运行态变为阻塞态
	}
}






//任务本体点灯
TaskHandle_t LED_TaskHandle;
void LED_Task(void *p)
{
	uint8_t ret = 0;
	su03t_u5Cofing();
	kqm_U4Config();
	while(1)
	{           //111  101 = 5   //句柄 //指定要测试的事件位
		ret =  xEventGroupWaitBits(Event,0x07,pdFALSE,pdFALSE,portMAX_DELAY);
		if((ret&0x01)==0x01)
		{
			KQM_DealData();
			printf("RET:%d\r\n",ret);
		}
		if((ret&0x01)==0x02)
		{
			SU03T_DealData();
			printf("RET:%d\r\n",ret);
		}
		if((ret&0x04) == 0x04)
		{
			WIFI_Anylze();
			printf("RET:%d\r\n",ret);
		}
		//Led_Toggle(1);
		vTaskDelay(200);
	}
}

事件组也是用来同步。可以实现一对多。

  1. 创建
  2. 一个任务设置标志位
  3. 一个任务获取标志位

事件组等待获取函数:

event_groups.h

 EventBits_t xEventGroupWaitBits(
                       const EventGroupHandle_t xEventGroup,
                       const EventBits_t uxBitsToWaitFor,
                       const BaseType_t xClearOnExit,
                       const BaseType_t xWaitForAllBits,
                       TickType_t xTicksToWait );

读取 RTOS 事件组中的位,选择性地进入“已阻塞”状态(已设置 超时值)以等待设置单个位或一组位。无法从中断调用此函数。

参数:

        

xEventGroup  正在测试位的事件组。 此前 必须已通过 xEventGroupCreate() 创建好事件组。
uxBitsToWaitFor  指定事件组中要测试的一个或多个事件位 的按位值。 例如,要等待第 0 位和/或第 2 位, 请将 uxBitsToWaitFor 设置为 0x05。 要等待第 0 位和/或第 1 位和/或第 2 位, 请设置 uxBitsToWaitFor 为 0x07, 以此类推。

uxBitsToWaitFor 不得设置为 0。

xClearOnExit  如果 xClearOnExit 设置为 pdTRUE, 那么在作为 uxBitsToWaitFor 参数传递的值中设置的任何位 会在 xEventGroupWaitBits() 返回某个值之前在事件组中清除掉, 前提是 xEventGroupWaitBits() 因超时以外的原因而返回值 。 超时值由 xTicksToWait 参数设置。

如果 xClearOnExit 设置为 pdFALSE, 那么当调用 xEventGroupWaitBits() 返回时,事件组中设置的位不会改变。

xWaitForAllBits  xWaitForAllBits 用于创建逻辑与测试 (必须设置所有位)或逻辑或测试(必须设置一个 或多个位),如下所示:

如果 xWaitForAllBits 设置为 pdTRUE, 那么当在作为 uxBitsToWaitFor 参数传递的值中设置的所有位 均已在事件组中设置好,或指定的阻塞时间已过期,则 xEventGroupWaitBits() 会返回相应值。

如果 xWaitForAllBits 设置为 pdFALSE,那么当在作为 uxBitsToWaitFor 参数传递的值中设置的任何位已在事件组中设置好, 或指定的阻塞时间已过期,则 xEventGroupWaitBits() 会返回相应值。

xTicksToWait  等待 uxBitsToWaitFor 指定的一个/所有(取决于 xWaitForAllBits 的值)位完成设置的最大时间 (单位:tick)。

返回:

事件位等待完成设置或阻塞时间过期时 的事件组值。 如果 高优先级任务或中断在调用任务解除“已阻塞”状态和退出 xEventGroupWaitBits() 函数之间更改了事件位的值, 则事件组中事件位的当前值将与返回值不同 。

测试返回值以确定 哪些位已完成设置。 如果 xEventGroupWaitBits() 因为超时值过期而返回, 则并非在等待的所有位都会进行设置。 如果 xEventGroupWaitBits() 因为它所等待的位均已完成设置而返回相应值, 则返回值是自动清除 (原因是 xClearOnExit 参数设置为 pdTRUE)任何位之前的事件组值。

//任务本体点灯
TaskHandle_t LED_TaskHandle;
void LED_Task(void *p)
{
	uint8_t ret = 0;
	su03t_u5Cofing();
	kqm_U4Config();
	while(1)
	{           //111  101 = 5   //句柄 //指定要测试的事件位
		ret =  xEventGroupWaitBits(Event,0x07,pdFALSE,pdFALSE,portMAX_DELAY);
		if((ret&0x01)==0x01)
		{
			KQM_DealData();
			printf("RET:%d\r\n",ret);
		}
		if((ret&0x01)==0x02)
		{
			SU03T_DealData();
			printf("RET:%d\r\n",ret);
		}
		if((ret&0x04) == 0x04)
		{
			WIFI_Anylze();
			printf("RET:%d\r\n",ret);
		}
		//Led_Toggle(1);
		vTaskDelay(200);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值