三十八、freertos任务通知-任务间通信综合实验
#include
#include //标准C库文件,定义了各种类型的范围
#include "board.h"
#include "led.h"
#include "key.h"
#include "uart.h"
//#include "tim_mrt.h"
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)
//static void TIM_CallBack1(void);
//static void TIM_CallBack2(void);
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"//事件头文件
#include "queue.h"//队列头文件
#include "semphr.h"//信号量头文件
#include "timers.h"//软件定时器头文件
static xTaskHandle LED_TaskHandle=NULL;
static xTaskHandle KEY_TaskHandle=NULL;
#define TASK_STACK_SIZE 32//每个任务的栈大小
#define SEMAPHORE 1//任务计数信号量
//#define SEMAPHORE 2//任务二值信号量
//#define SEMAPHORE 3//任务事件标志组
#define BIT_0 (1 << 0)
#define BIT_1 (1 << 1)
//#define SEMAPHORE 4//任务消息邮箱(实现长度固定为 1的消息队列)
static void prvSetupHardware(void)
{
SystemCoreClockUpdate();
DEBUGINIT();
led_Init() ;
Key_INIT();
// MRT_Init();
DEBUGOUT("%u MHzn",SystemCoreClock/1000000);
Board_UARTPutSTR("build date: " __DATE__ " build time: " __TIME__ "n");
}
static void LED_Task(void* parameter)
{
uint32_t ulNotifiedValue;
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(500);
#if ( (3==SEMAPHORE)||(4==SEMAPHORE) )
uint32_t ulValue;
#endif
while(1)
{
#if (SEMAPHORE ==1) //任务计数信号量
ulNotifiedValue=ulTaskNotifyTake(pdFALSE,//
xMaxBlockTime);
if(ulNotifiedValue > 1)
{
printf("任务 LED_Task 接收到消息, ulNotifiedValue = %drn", ulNotifiedValue);
}
else if(ulNotifiedValue == 1)
{
printf("任务 LED_Task 接收到消息, ulNotifiedValue = %drn", ulNotifiedValue);
printf("计数信号量释放完,请用按键重新计数。");
}
else
Board_LED_Toggle(1);
vTaskDelay(2000);//2秒释放一次
#elif (SEMAPHORE ==2) //任务二值信号量
(void )ulNotifiedValue;
(void )xMaxBlockTime;
ulTaskNotifyTake(pdTRUE,//
portMAX_DELAY);
printf("任务 LED_Task 接收到消息n");
Board_LED_Toggle(1);
#elif ( (3==SEMAPHORE)||(4==SEMAPHORE) )
(void )ulNotifiedValue;
(void )xMaxBlockTime;
u32 xReturn = xTaskNotifyWait(0x00000000,
0xFFFFFFFF,
&ulValue,
xMaxBlockTime);
if( xReturn == pdPASS )
{
#if(3 ==SEMAPHORE)
if((ulValue & BIT_0) != 0)
{
printf("接收到 K1 按键按下消息, ulNotifiedValue = 0x%08xrn", ulValue);
}
if((ulValue & BIT_1) != 0)
{
printf("接收到 K2 按键按下消息, ulNotifiedValue = 0x%08xrn", ulValue);
}
#elif(4 ==SEMAPHORE)
printf("接收到消息邮箱数据 ulValue = %drn", ulValue);
#endif
}
else
Board_LED_Toggle(1);
#endif
}
}
static void KEY_Task(void* parameter)
{
// baseType_t xReturn =pdPASS;
#if (SEMAPHORE ==4)
u8 ucCount=0;
#endif
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:
{
// printf ( "KEY1 被按下n" );
Board_LED_Toggle(6);
#if ( (1==SEMAPHORE)||(2==SEMAPHOER) )
printf("K1 键按下,直接发送消息给任务 LED_Task rn");
xTaskNotifyGive(LED_TaskHandle);
#elif (3==SEMAPHORE)//任务事件标志组
printf("K1 键按下,任务 LED_Task 事件标志位 bit0 被置位 rn");
xTaskNotify(LED_TaskHandle,
BIT_0,
eSetBits);
#elif (4==SEMAPHORE)//任务消息邮箱
printf("K1 键按下,发送消息邮箱数据给任务 LED_Task,覆盖方式rn");
xTaskNotify(LED_TaskHandle,
ucCount++,
eSetValueWithOverwrite);
#endif
}break;
case 2:
{
// printf ( "KEY2 被按下n" );
Board_LED_Toggle(5);
#if (3==SEMAPHORE)
printf("K2 键按下,任务 LED_Task 事件标志位 bit1 被置位 rn");
xTaskNotify(LED_TaskHandle,
BIT_1,
eSetBits);
#elif (4==SEMAPHORE)//任务消息邮箱
printf("K2 键按下,发送消息邮箱数据给任务 LED_Task,非覆盖方式rn");
if(xTaskNotify(LED_TaskHandle, ucCount++, eSetValueWithoutOverwrite) == pdPASS)
{
printf("任务 LED_Task 的消息邮箱被更新rn");
}
else
{
printf("任务 LED_Task 的消息邮箱数据未被更新rn");
}
#endif
}break;
case 3:
{
}break;
default:break;
}
key2=0;
}
}
}
static void AppTaskCreate(void)
{
baseType_t xReturn = pdPASS;
taskENTER_CRITICAL();//进入临界区,禁止中断打断
xReturn = xTaskCreate( LED_Task,
"LED_Task",
TASK_STACK_SIZE*2,
NULL,
2,
&LED_TaskHandle);
if (pdPASS == xReturn)
printf("创建 Receive1_Task 任务成功!rn");
xReturn = xTaskCreate( KEY_Task,
"KEY_Task",
TASK_STACK_SIZE*2,
NULL,
1,
&KEY_TaskHandle);
if (pdPASS == xReturn)
printf("创建 Send_Task 任务成功!rn");
taskEXIT_CRITICAL(); //退出临界区
}
int main(void)
{
prvSetupHardware();
Board_UARTPutSTR("LPC824 FreeRTOS 任务通知任务间通信 n");
DEBUGSTR("任务通知n");
DEBUGSTR("任务1用发送通知,任务2接收通知 n");
AppTaskCreate();
vTaskStartScheduler();//任务调度
while (1) {
printf("FreeRTOS 运行失败nr");
}
}
void HardFault_Handler(void)
{
printf("硬件错误中断n");
while(1)
{
}
}
//#define SEMAPHORE 1//任务计数信号量
xTaskNotifyGive
vTaskNotifyGiveFromISR
ulTaskNotifyTake
//#define SEMAPHORE 2//任务二值信号量
xTaskNotifyGive
vTaskNotifyGiveFromISR
ulTaskNotifyTake
//#define SEMAPHORE 3//任务事件标志组
xTaskNotify
xTaskNotifyFromISR
xTaskNotifyWait
#define SEMAPHORE 4//任务消息邮箱
xTaskNotify
xTaskNotifyFromISR
xTaskNotifyWait