34 freertos任务通知--代替消息队列(任务邮箱)覆盖和非覆盖

三十四、 freertos任务通知–代替消息队列(任务邮箱)覆盖和非覆盖

/**
**************************************************************************************************/
#include <stdio.h>
#include <limits.h>//标准C库文件,定义了各种类型的范围
#include "board.h"
#include "led.h"
#include "key.h"
#include "uart.h"
//#include "tim_mrt.h"


/*** System oscillator rate and clock rate on the CLKIN pin  ****/
/**/const uint32_t OscRateIn = MAIN_OSC_XTAL_FREQ_HZ;		 /**/
/**/const uint32_t ExtRateIn = EXT_CLOCK_IN_FREQ_HZ;		 /**/
 //系统复位
#define	System_restart	(LPC_SWM->PINENABLE0 = 0xffffffffUL) /**/
/**********************End**************************************/



#include "FreeRTOSConfig.h"
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"//事件头文件
#include "queue.h"//队列头文件
#include "semphr.h"//信号量头文件
#include "timers.h"//软件定时器头文件

/**************************** 任务句柄 ********************************/

#define TASK_STACK_SIZE 32//每个任务的栈大小

#define KEY1_EVENT (0x01 << 0)//设置事件掩码的位 0
#define KEY2_EVENT (0x01 << 1)//设置事件掩码的位 1

static xTaskHandle LED_TaskHandle=NULL;
static xTaskHandle KEY_TaskHandle=NULL;
	



/*************************** 宏定义 ************************************/
#define USE_CHAR 0 /* 测试字符串的时候配置为 1 ,测试变量配置为 0 */




/* Sets up system hardware 
**********************************************************************
  * @ 函数名  : BSP_Init
  * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
  * @ 参数    :   
  * @ 返回值  : 无
*********************************************************************/
static void prvSetupHardware(void)
{

	SystemCoreClockUpdate();

	DEBUGINIT();
	led_Init() ;	
	Key_INIT();
//	MRT_Init();
	DEBUGOUT("%u MHz\n",SystemCoreClock/1000000);
	Board_UARTPutSTR("build date: " __DATE__ " build time: " __TIME__ "\n");

}

/**********************************************************************
 * @ 函数名 :  
 * @ 功能说明:  接收发送通知
 * @ 参数 :
 * @ 返回值 : 无
 ********************************************************************/
static void LED_Task(void* parameter)
{
	BaseType_t xReturn=pdTRUE;
 	u32	r_event=0;//接收事件
	
	const TickType_t xMaxBlockTime = pdMS_TO_TICKS(500); /* 设置最大等待时间为 500ms */
	while(1)
	{

		/*
			第一个参数 ulBitsToClearOnEntry 的作用(函数执行前):
				ulNotifiedValue &= ~ulBitsToClearOnEntry
				简单的说就是参数 ulBitsToClearOnEntry 那个位是 1,那么 ulNotifiedValue
				的那个位就会被清零。
				这里 ulBitsToClearOnEntry = 0x00000000 就是函数执行前保留所有位。
			第二个参数 ulBitsToClearOnExit 的作用(函数退出前):
					ulNotifiedValue &= ~ulBitsToClearOnExit
				简单的说就是参数 ulBitsToClearOnEntry 那个位是 1,那么 ulNotifiedValue
				的那个位就会被清零。
				这里 ulBitsToClearOnExit = 0xFFFFFFFF 就是函数退出前清楚所有位。
			注: ulNotifiedValue 表示任务 LED_Task 的任务控制块里面的变量,用来做消息邮箱数据的存取。
		*/
		/*获取一个任务通知,没有获取到一直等待 */
		xReturn=xTaskNotifyWait(0x0,//进入函数的时候不清除任务 bit
								0xFFFFFFFF,//退出函数的时候清除所有的 bitR
								&r_event,// 保存 ulNotifiedValue 到变量  
								xMaxBlockTime);/* 最大允许延迟时间 */
		/* 此函数只会返回 pdPASS */
		if(pdTRUE ==xReturn)
		{
			 printf("接收到消息邮箱数据 ulValue = %d\r\n", r_event);
		
		}			
		else
			Board_LED_Toggle(1);
		
//		vTaskDelay(200);
	}
}


/**********************************************************************
 * @ 函数名 :   
 * @ 功能说明: 发送任务
 * @ 参数 :
 * @ 返回值 : 无
 ********************************************************************/
static void KEY_Task(void* parameter)
{
//	BaseType_t xReturn =pdPASS;
	uint8_t ucCount = 0;
	
	u8 key2=0;
	while(1)
	{
		u8 key=0;
		if(Scan_Key())
			vTaskDelay(20);
		else continue;
		if(!Scan_Key())continue;
		else
		{
			key=Scan_Key();
			key2=key;
		}
		while(Scan_Key()){};//等按键抬起
		
		if(key2)
		{

			switch(key2)
			{
				case 1:
				{
					/* K1键按下 */
					printf ( "KEY1 被按下\n" );
					 /* 触发一个事件 1 */
					printf("K1 键按下,发送消息邮箱数据给任务 LED_Task ,覆盖方式\r\n");
					xTaskNotify(LED_TaskHandle, /* 目标任务 */
								ucCount++, /* 发送数据 */
								eSetValueWithOverwrite);/* 如果目标任务上次的数据还没有处理,会被覆盖*/
					
					Board_LED_Toggle(6);
					
				}break;
				case 2:
				{
					 /* K2键按下 */
					printf ( "KEY2 被按下\n" );
					
					/* 非覆盖模式的数据发送 */
					if(xTaskNotify(LED_TaskHandle, ucCount++, eSetValueWithoutOverwrite) == pdPASS)
					{
						/* 目标任务的消息邮箱数据被更新 */
						printf("任务 LED_Task 的消息邮箱被更新\r\n");
					}
					else
					{
						/* 目标任务的消息邮箱数据未更新,因为上次的数据还没有处理,不能进行覆盖 */
						printf("任务 LED_Task 的消息邮箱数据未被更新\r\n");
					}
					
					
					Board_LED_Toggle(5);
					
				}break;
				case 3:
				{
					 /* K3键按下*/
					 
 					
				}break;
				default:break;
			}
			key2=0;
		}
			
	}
}

/***********************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  **********************************************************************/
static void AppTaskCreate(void)
{
	BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
	taskENTER_CRITICAL();//进入临界区,禁止中断打断
	
	xReturn = xTaskCreate(LED_Task,
							"Give_Task",
							TASK_STACK_SIZE*4,
							NULL,
							2,
							&LED_TaskHandle);
	if (pdPASS == xReturn)
		printf("创建 Receive1_Task 任务成功!\r\n");
	

	xReturn = xTaskCreate(KEY_Task,
							"KEY_Task",
							TASK_STACK_SIZE*5,
							NULL,
							1,
							&KEY_TaskHandle);
	if (pdPASS == xReturn)
		printf("创建 Send_Task 任务成功!\r\n");

	taskEXIT_CRITICAL(); //退出临界区	

}

/**
 * @brief	main routine for blinky example
 * @return	Function should not exit.
 */
int main(void)
{
	
	prvSetupHardware();
	Board_UARTPutSTR("LPC824 FreeRTOS 任务通知任务间通信 \n");

	

	AppTaskCreate();

	vTaskStartScheduler();//任务调度

	/* Loop forever */
	while (1) {
			printf("FreeRTOS 运行失败\n\r");
 	}
	
	
}

K1键按下,发送消息邮箱数据给任务LED_Task,覆盖方式。
K2键按下,发送消息邮箱数据给任务LED_Task,非覆盖方式。

实验现象:
key按键任务里面,当KEY1和KEY2都按下后,LED任务打印出来。
LED任务接收。

使用函数:
发送 xTaskNotify();
接收 xTaskNotifyWait();

版权声明:本文为CSDN博主「春风得意吃火锅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_17208955/article/details/122350855

生成海报
点赞 0

春风得意吃火锅

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32学习笔记—ADC

1、adc简介 2、函数配置 3、代码 1、adc简介 在ADC就是模数转换器,将模拟量转换成数字量,举个例子就是将电压转换位数字量,STM32拥有1-3个ADC(模数转换器),这些