【FreeRTOS】小白进阶之如何使用FreeRTOS任务通知Notify

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liwei16611/article/details/82620736

简析 notify 使用基础。

基于 windows vs2012 运行效果:

每个 RTOS 任务都有一个 32 位的通知值,任务创建时,这个值被初始化为 0。RTOS 任务通知相当于直接向任务发送一个事件,接收到通知的任务可以解除阻塞状态,前提是这个阻塞事件是因等待通知而引起的。发送通知的同时,也可以可选的改变接收任务的通知值。

可以通过下列方法向接收任务更新通知:

a、不覆盖接收任务的通知值

b、覆盖接收任务的通知值

c、设置接收任务通知值的某些位

d、增加接收任务的通知值

1、头文件声明

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "supporting_functions.h"

// 中断号
#define mainINTERRUPT_NUMBER	3

static void vHandlerTask( void *pvParameters );
static void vPeriodicTask( void *pvParameters );

// 中断处理函数
static uint32_t ulExampleInterruptHandler( void );

// 延时
static const TickType_t xInterruptFrequency = pdMS_TO_TICKS( 500UL );

static TaskHandle_t xHandlerTask = NULL;

2、启动任务

int main( void )
{
	xTaskCreate( vHandlerTask, "Handler", 1000, NULL, 3, &xHandlerTask );

	xTaskCreate( vPeriodicTask, "Periodic", 1000, NULL, 1, NULL );

	vPortSetInterruptHandler( mainINTERRUPT_NUMBER, ulExampleInterruptHandler );
	
	vTaskStartScheduler();

	for( ;; );
	return 0;
}

3、Notify 接收任务

static void vHandlerTask( void *pvParameters )
{
	const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS( 10 );
	uint32_t ulEventsToProcess;

	for( ;; )
	{
		// 等待接收 notify
		ulEventsToProcess = ulTaskNotifyTake( pdTRUE, xMaxExpectedBlockTime );
		if( ulEventsToProcess != 0 )
		{
			while( ulEventsToProcess > 0 )
			{
				vPrintString( "Handler task - Processing event.\r\n" );
				ulEventsToProcess--;
			}
		}
	}
}

4、中断处理函数

static uint32_t ulExampleInterruptHandler( void )
{
	BaseType_t xHigherPriorityTaskWoken;

	xHigherPriorityTaskWoken = pdFALSE;

	// 发送 notify 到 任务
	vTaskNotifyGiveFromISR( xHandlerTask,
							&xHigherPriorityTaskWoken );

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

5、触发中断

static void vPeriodicTask( void *pvParameters )
{
	for( ;; )
	{
		vTaskDelay( xInterruptFrequency );

		vPrintString( "Periodic task - About to generate an interrupt.\r\n" );
		vPortGenerateSimulatedInterrupt( mainINTERRUPT_NUMBER );
		vPrintString( "Periodic task - Interrupt generated.\r\n\r\n\r\n" );
	}
}

猜你喜欢

转载自blog.csdn.net/liwei16611/article/details/82620736