介绍多值信号量的使用。

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 );

// 定义多值信号量
SemaphoreHandle_t xCountingSemaphore;

2、启动任务

任务 vPeriodicRask 用于启动模拟中断:

int main( void )
{
    // 创建多值信号量,最小值 0,最大值 10
	xCountingSemaphore = xSemaphoreCreateCounting( 10, 0 );

	if( xCountingSemaphore != NULL )
	{
		xTaskCreate( vHandlerTask, "Handler", 1000, NULL, 3, NULL );

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

		vPortSetInterruptHandler( mainINTERRUPT_NUMBER, ulExampleInterruptHandler );

		vTaskStartScheduler();
	}

	for( ;; );
	return 0;
}

3、定义任务

static void vHandlerTask( void *pvParameters )
{
	for( ;; )
	{
		xSemaphoreTake( xCountingSemaphore, portMAX_DELAY );

		vPrintString( "Handler task - Processing event.\r\n" );
	}
}

static void vPeriodicTask( void *pvParameters )
{
	const TickType_t xDelay500ms = pdMS_TO_TICKS( 500UL );

	for( ;; )
	{
		vTaskDelay( xDelay500ms );

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

static uint32_t ulExampleInterruptHandler( void )
{
	BaseType_t xHigherPriorityTaskWoken;

	xHigherPriorityTaskWoken = pdFALSE;

	xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );
	xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );
	xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}