Free RTOS学习Task and Scheduler API

参考自FreeRTOS_Reference_Manual_V10.0.0

1、portSWITCH_TO_USER_MODE()

#include “FreeRTOS.h”
#include “task.h”
void portSWITCH_TO_USER_MODE( void );
简介

这个函数仅适用于高级用户,并且仅与FreeRTOS MPU端口(使用内存保护单元的FreeRTOS端口)相关。
使用MPU进行限制的任务是使用xTaskCreateRestricted()创建的。提供给xTaskCreateRestricted()的参数指定创建的任务应该是用户(非特权)模式任务,还是主管(特权)模式任务。管理模式任务可以调用portSWITCH_TO_USER_MODE()将自己从管理模式任务转换为用户模式任务。

注意

没有与portSWITCH_TO_USER_MODE()对等的方法,该方法可以将任务从用户模式转换为管理模式任务。

2、vTaskAllocateMPURegions()

#include “FreeRTOS.h”
#include “task.h”
void vTaskAllocateMPURegions( 
	TaskHandle_t xTaskToModify,
	const MemoryRegion_t * const xRegions
	 );
简介

定义一组内存保护单元(MPU)区域,供使用MPU进行限制的任务使用。
这个函数仅适用于高级用户,并且仅与FreeRTOS MPU端口(使用内存保护单元的FreeRTOS端口)相关。
当使用xTaskCreateRestricted()函数创建任务时,可以将MPU控制的内存区域分配给使用MPU进行限制的任务。然后可以在运行时使用vTaskAllocateMPURegions()函数重新定义(或重新分配)它们。

参数
xTaskToModify

需要被修改的受限制任务的句柄(被赋予访问由xRegions参数定义的内存区域的任务)

xRegions

MemoryRegion_t结构的数组。数组中的位置数由端口特定的portNUM_CONFIGURABLE_REGIONS常量定义。
在Cortex-M3上,portNUM_CONFIGURABLE_REGIONS定义为三个区域。
数组中的每个MemoryRegion_t结构定义一个MPU内存区域,供xTaskToModify参数引用的任务使用。

注意

MPU内存区域使用的MemoryRegion_t结构定义:

typedef struct xMEMORY_REGION
{
	void *pvBaseAddress;
	unsigned long ulLengthInBytes;
	unsigned long ulParameters;
} MemoryRegion_t;

pvBaseAddress和ulLengthInBytes成员分别作为内存区域的开始和内存区域的长度自解释。这些必须符合MPU施加的尺寸和对齐限制。特别是,每个区域的大小和对齐方式都必须等于两个值的相同幂。
ulParameters定义了如何允许任务访问正在定义的内存区域,并可以按位或取以下值:

  • portMPU_REGION_READ_WRITE
  • portMPU_REGION_PRIVILEGED_READ_ONLY
  • portMPU_REGION_READ_ONLY
  • portMPU_REGION_PRIVILEGED_READ_WRITE
  • portMPU_REGION_CACHEABLE_BUFFERABLE
  • portMPU_REGION_EXECUTE_NEVER
官方示例:
/* 定义一个数组,任务将从该数组读取和写入该数组。确保
大小和对齐适合于MPU区域(注意这使用GCC语法) __attribute__ 是编译器指令,
告诉编译器声明的特性,或者让编译器进行更多的错误检查和高级优化*/
static unsigned char ucOneKByte[ 1024 ] __attribute__((align( 1024 ))); 
/* 定义一个 MemoryRegion_t 结构数组,它可以配置一个MPU区域
从ucOneKByte数组开始的1024字节的读/写访问。
最大三个可定义区域中的另外两个未使用,因此将其设置为零。*/
static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
{
/* 基址长度参数 */
	{ ucOneKByte, 1024, portMPU_REGION_READ_WRITE },
	{ 0, 0, 0 },
	{ 0, 0, 0 }
};
void vATask( void *pvParameters )
{
/*  这个任务是使用xTaskCreateRestricted()创建的,可以访问最多有三个MPU控制的内存区域
在某种时候,需要用上面定义的 xAltRegions const 结构中定义的区域替换这些MPU区域。
NULL用作任务句柄,指示将更改应用于调用任务。. */
vTaskAllocateMPURegions( NULL, xAltRegions );
/* 现在任务可以继续它的函数,但是从现在开始只能访问它的堆栈和
ucOneKByte数组(除非在其他地方声明了其他静态定义或共享的区域)。 */
}

3、xTaskAbortDelay()

#include “FreeRTOS.h”
#include “task.h”
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
简介

调用包含超时参数的API函数会导致调用任务进入阻塞状态。处于阻塞状态的任务要么等待超时时间过去,要么等待事件超时,在超时之后任务将自动离开阻塞状态并进入就绪状态。这种行为有很多例子,其中两个是:

  • 如果任务调用vTaskDelay(),它将进入阻塞状态,直到函数参数指定的超时结束,此时任务将自动离开阻塞状态并进入就绪状态。
  • 如果一个任务调用ulTaskNotifyTake()时通知值为零将进入阻塞状态,直到它收到一个通知或一个函数的参数所指定的超时运行,在这段时间的任务将自动离开阻塞状态,进入就绪状态。

xTaskAbortDelay()将任务从阻塞状态移动到就绪状态,即使任务正在等待的事件没有发生,并且任务进入阻塞状态时指定的超时没有经过。
当任务已经处于阻塞状态时,调度器无法使用它,并且不会消耗任何处理时间。

参数
xTask

将被移出阻塞状态的任务的句柄。
要获取任务的句柄,请使用xTaskCreate()创建任务并使用pxCreatedTask参数,或者使用xTaskCreateStatic()创建任务并存储返回值,或者在调用xTaskGetHandle()时使用任务的名称。

返回值

如果xTask引用的任务从阻塞状态中删除,则返回pdPASS。如果xTask引用的任务没有从阻塞状态中删除,因为它没有处于阻塞状态,则返回pdFAIL。

注意

要使xTaskAbortDelay()可用,必须将FreeRTOSConfig.h中的INCLUDE_xTaskAbortDelay设置为1。

官方示例:
void vAFunction( TaskHandle_t xTask )
{
	/* The task referenced by xTask is blocked to wait for something that the task calling
	this function has determined will never happen. Force the task referenced by xTask
	out of the Blocked state. */
	if( xTaskAbortDelay( xTask ) == pdFAIL )
	{
		
		/*xTask引用的任务没有处于阻塞状态*/
	}
	else
	{
		
		/*xTask引用将要处于阻塞状态的任务*/
	}
}

4、xTaskCallApplicationTaskHook()

简介
参数
返回值
注意
官方示例:

5、

简介
参数
返回值
注意
官方示例:

6、xTaskCreate()

#include “FreeRTOS.h”
#include “task.h”
BaseType_t xTaskCreate( 
	TaskFunction_t pvTaskCode,
	const char * const pcName,
	unsigned short usStackDepth,
	void *pvParameters,
	UBaseType_t uxPriority,
	TaskHandle_t *pxCreatedTask 
);

使用方法:xTaskCreate(新建任务函数名,字符串别名,堆栈深度,新建任务参数,优先级,传递句柄)
示例:

if(xTaskCreate(init_fun, ((const char*)"init"), 2048, NULL, 3, NULL) != pdPASS)  
	printf("\n\r%s xTaskCreate(init_fun) failed", __FUNCTION__);
简介

创建一个新的任务实例。
每一个任务都需要用于保存任务状态的RAM(任务控制块,或者TCB),并被任务用作其堆栈。如果使用xTaskCreate()创建任务,则从FreeRTOS堆自动分配所需的RAM。如果使用xTaskCreateStatic()创建任务,则由应用程序编写器提供RAM,这将导致两个额外的函数参数,但允许在编译时静态分配RAM。
新创建的任务最初处于就绪状态,但如果没有更高优先级的任务可以运行,则会立即成为正在运行的状态任务。
可以在启动调度程序之前和之后创建任务。

参数
pvTaskCode

pvTaskCode参数只是一个指针,指向实现任务的函数(实际上,只是函数名)。注意:任务函数必须是从不退出的C函数,因此通常被实现为一个无限循环。

pcName

任务函数的别名。这主要用于方便调试,但也可以通过调用xTaskGetHandle()来获取任务句柄。
应用程序定义的常量configMAX_TASK_NAME_LEN以字符为单位来定义名称的最大长度——包括NULL终止符。如果提供的字符串长度超过此最大值,将导致字符串被静默截断。

usStackDepth

任务的堆栈深度
每个任务都有自己独特的堆栈,内核在创建任务时将其分配给任务。usStackDepth值告诉内核堆栈的大小。
该值指定堆栈可以容纳的数量,而不是字节数。例如,在具有4字节堆栈宽度的体系结构上,如果将usStackDepth作为100传入,那么将分配400字节的堆栈空间(100 * 4字节)。堆栈深度乘以堆栈宽度不能超过size_t类型变量中可以包含的最大值。
configMINIMAL_STACK_SIZE定义空闲任务使用的堆栈大小。

pvParameters

分配给pvParameters的值将是传递给任务函数的值。即创建任务时,参数的指针。

uxPriority

定义任务执行时的优先级。优先级可以从0(最低优先级)分配到(configMAX_PRIORITIES - 1)(最高优先级)。
configMAX_PRIORITIES是一个用户定义的常量。如果configUSE_PORT_OPTIMISED_TASK_SELECTION设置为0,那么优先的数量没有上限,可以使用的限制(除了数据类型和可用的RAM单片机使用),但建议使用所需的最低数量的优先级,以避免浪费内存。
传递上面的uxPriority值(configMAX_PRIORITIES - 1)将导致分配给任务的优先级被静默地限制为最大合法值。

pxCreatedTask

可以使用pxCreatedTask向正在创建的任务传递句柄。以便创建的任务可以被关联。例如,更改任务优先级或删除任务。
如果应用程序不使用任务句柄,则可以将pxCreatedTask设置为NULL。

返回值

pdPASS
指示任务已成功创建。
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
指示无法创建任务,因为FreeRTOS没有足够的堆内存来分配任务数据结构和堆栈。
如果heap_1。项目中包含c、heap_2.c或heap_4.c,然后FreeRTOSConfig中的configTOTAL_HEAP_SIZE定义可用堆的总量。使用vApplicationMallocFailedHook()回调函数(或“hook”)可以捕获分配内存失败,使用xPortGetFreeHeapSize() API函数可以查询剩余的空闲堆内存数量。

注意

在FreeRTOSConfig.h中,configSUPPORT_DYNAMIC_ALLOCATION必须设置为1。或者简单地未定义,使这个函数可用。

官方示例:
/*定义一个名为xStruct的结构和一个类型为xStruct的变量。这些只是用来演示传递给任务函数的参数。*/
typedef struct A_STRUCT
{
	char cStructMember1;
	char cStructMember2;
} xStruct;
/*定义一个类型为xStruct的变量作为任务参数传递。*/
xStruct xParameter = { 1, 2 };
/* Define the task that will be created. Note the name of the function that implements the task is used as the first parameter in the call to xTaskCreate() below. */
/*定义将要创建的任务。注意,实现该任务的函数的名称用作下面调用xTaskCreate()的第一个参数。*/
void vTaskCode( void * pvParameters )
{
	xStruct *pxParameters;
	/* Cast the void * parameter back to the required type. */
	/*将void *参数强制转换回所需类型。*/
	pxParameters = ( xStruct * ) pvParameters;
	if( pxParameters->cStructMember1 != 1 )
	{
	/* 等等及其他*/
	}

	for( ;; )
	{
	/* 任务代码在这里 */
	}
}

/*定义一个创建任务的函数。可以在启动调度程序之前或之后调用。*/
void vAnotherFunction( void )
{
	TaskHandle_t xHandle;
	/* 创建任务. */
	if( xTaskCreate(
		vTaskCode, /* 任务函数指针 */
		"Demo task", /* 字符串别名. */
		STACK_SIZE, /* 堆栈深度注意不是字节*/
		(void*) &xParameter,/* xParameter指针传递给创建的任务参数.
		转化为void* 防止编译器警告 */
		TASK_PRIORITY, /* 给新建任务分配优先级. */
		&xHandle /* 创建任务的句柄将放在xHandle中 */
		) != pdPASS )
	{
		printf("\n\r%s xTaskCreate(vTaskCode) failed", __FUNCTION__);
		/*
		由于剩余堆内存不足,无法创建该任务。如果多个heap.c文件都包含在这个项目中,
		这种情况可以使用vApplicationMallocFailedHook()回调函数(或“hook”)捕获,
		并且可以使用xPortGetFreeHeapSize() API函数查询FreeRTOS堆内存中未分配的数量。
		*/
	}
	else
	{
		/*任务创建成功。句柄现在可以用于其他API函数,例如更改任务的优先级。*/
		vTaskPrioritySet( xHandle, 2 );
	}
}

9、vTaskDelay()

#include “FreeRTOS.h”
#include “task.h”
void vTaskDelay( TickType_t xTicksToDelay );
简介

将调用vTaskDelay()的任务设置为阻塞状态,执行固定次数
中断。
方法将不会导致调用任务被放置到阻塞状态,但将导致调用任务让位给任何共享其状态的就绪任务优先级。调用vTaskDelay(0)等同于调用taskYIELD()。

参数
xTicksToDelay

调用任务将保持在被阻塞状态的滴答中断数
在被转换回就绪状态之前的状态。例如,如果a
任务称为vTaskDelay(100),当滴答计数为10,000时,它会
立即进入阻塞状态并保持阻塞状态,直到
tick数量达到10100。
从调用vTaskDelay()到下一次滴答之间的任何时间
中断发生,计数为一个完整的滴答周期。因此,
指定延迟周期时可以达到的最高时间分辨率
在最坏的情况下,等于一个完整的滴答中断周期。
可以使用宏pdMS_TO_TICKS()将毫秒转换为刻度。

返回值

注意

对于vTaskDelay() API, INCLUDE_vTaskDelay必须在FreeRTOSConfig.h中设置为1
功能可用。

官方示例:
void vAnotherTask( void * pvParameters )
{
	for( ;; )
	{
		/*处理程序*/

		/*输入20个tick中断的阻塞状态——阻塞状态下实际花费的时间取决于tick频率*/
		vTaskDelay( 20 );
		/*输入阻塞状态20毫秒。使用pdMS_TO_TICKS()宏意味着tick频率可以改变,而不会影响在阻塞状态中花费的时间(*/
		vTaskDelay( pdMS_TO_TICKS( 20 ) );
	}
}

10、vTaskDelayUntil()

#include “FreeRTOS.h”
#include “task.h”
void vTaskDelayUntil( 
		TickType_t *pxPreviousWakeTime, 
		TickType_t xTimeIncrement
 );
简介

将调用vTaskDelayUntil()的任务置于阻塞状态,直到出现绝对时间
达成。
周期性任务可以使用vTaskDelayUntil()实现恒定的执行频率。
vTaskDelay()和vTaskDelayUntil()的区别
vTaskDelay()导致调用任务进入阻塞状态,然后保持阻塞状态
从调用vTaskDelay()开始的指定节拍数的阻塞状态。
调用vTaskDelay()的任务退出阻塞状态的时间相对于调用vTaskDelay()的时间。
vTaskDelayUntil()导致调用任务进入阻塞状态,然后保持阻塞状态,直到到达一个绝对时间。这个任务vTaskDelayUntil()在指定的时间退出阻塞状态,而不是在指定的时间退出相对于调用vTaskDelayUntil()的时间。

参数
pxPreviousWakeTime

:vTaskDelayUntil()用于实现定期执行且频率固定的任务。pxPreviousWakeTime保存任务最后一次离开阻塞状态的时间(被“唤醒”)。此时间用作一个参考点,用于计算任务下一次离开阻塞状态的时间。pxPreviousWakeTime指向的变量在vTaskDelayUntil()函数中自动更新;它通常不会被应用程序代码修改,除非在变量第一次初始化的时候。

xTimeIncrement

vTaskDelayUntil()用于实现一个任务,该任务定期执行,并且具有固定的频率——频率由xTimeIncrement值设置.xTimeIncrement在’ ticks '中指定。可以使用pdMS_TO_TICKS()宏将毫秒转换为刻度

返回值

注意

对于vTaskDelay() API, INCLUDE_vTaskDelayUntil必须在FreeRTOSConfig.h中设置为1可用功能

官方示例:
/* 定义每50毫秒执行一个动作的任务. */
void vCyclicTaskFunction( void * pvParameters )
{
	TickType_t xLastWakeTime;
	const TickType_t xPeriod = pdMS_TO_TICKS( 50 );
	/*需要使用当前滴答计数初始化xLastWakeTime变量。注意,这是惟一一次显式地写入变量。在这个任务之后,xLastWakeTime在vTaskDelayUntil()内部自动更新. */
	xLastWakeTime = xTaskGetTickCount();/* 输入定义任务行为的循环。 */
	for( ;; )
	{
		/*这个任务应该每50毫秒执行一次。时间是用滴答声来计算的。pdMS_TO_TICKS宏用于将毫秒转换为刻度。xLastWakeTime在vTaskDelayUntil()中自动更新,因此任务不会显式更新。*/
		vTaskDelayUntil( &xLastWakeTime, xPeriod );
		/*在这里执行周期性动作。 */
	}
}

11、 vTaskDelete()

#include “FreeRTOS.h”
#include “task.h”
void vTaskDelete( TaskHandle_t pxTask );
简介

删除先前使用对xTaskCreate() orxTaskCreateStatic()的调用创建的任务实例。
已删除的任务不再存在,因此无法进入运行状态。
不要试图使用任务句柄引用已删除的任务。
当一个任务被删除时,空闲任务负责释放用来保存被删除任务的堆栈和数据结构(任务控制块)的内存。因此,如果应用程序使用了vTaskDelete() API函数,那么应用程序还必须确保空闲任务不会占用处理时间(必须在运行状态下分配空闲任务的时间)。
只有内核本身分配给任务的内存在删除任务时才会自动释放。应用程序(而不是内核)分配给任务的内存或任何其他资源必须在删除任务时由应用程序显式释放。

参数
pxTask

要删除的任务的句柄(主题任务)。
要获取任务句柄,请使用xTaskCreate()创建任务并使用pxCreatedTask参数,或使用xTaskCreateStatic()创建任务并存储返回值,或在对xTaskGetHandle()的调用中使用任务的名称
任务可以通过传递NULL来代替有效的任务句柄来删除自身

返回值

官方示例:
void vAnotherFunction( void )
{
	TaskHandle_t xHandle;
	/* 创建一个任务,在xHandle中存储创建任务的句柄. */
	if(
		xTaskCreate(
			vTaskCode,
			"Demo task",
			STACK_SIZE,
			NULL,
			PRIORITY,
			&xHandle /* xHandle的地址作为最后一个参数传递给xTaskCreate(),以获得正在创建的任务的句柄. */
			)
		!= pdPASS )
	{
	/* 无法创建任务,因为没有足够的FreeRTOS堆内存可用来分配任务数据结构和堆栈. */
	}
	else
	{
		/*删除刚刚创建的任务。使用从xTaskCreate()传递出去的句柄来引用主题任务. */
		vTaskDelete( xHandle );
	}
	/* 通过传递NULL作为vTaskDelete()参数来删除调用该函数的任务。同样的任务(此任务)也可以通过向自身传递一个有效句柄来删除。 */
	vTaskDelete( NULL );
}

12、

简介
参数
返回值
注意
官方示例:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值