赞
踩
目录
1.xTaskCreate(创建一个新任务并将其添加到准备运行的任务列表中)
2.xTaskCreateStatic(创建一个新任务并将其添加到准备运行的任务列表中)
3.xTaskCreateRestrictedStatic(创建一个新的内存保护单元(MPU)限制任务,并将其添加到准备运行的任务列表中)
4.vTaskDelete(从RTOS内核管理中删除一个任务)
英文原文:
- BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
- const char * const pcName,
- configSTACK_DEPTH_TYPE usStackDepth,
- void *pvParameters,
- UBaseType_t uxPriority,
- TaskHandle_t *pxCreatedTask );
创建一个新任务并将其添加到准备运行的任务列表中。configSUPPORT_DYNAMIC_ALLOCATION必须在FreeRTOSConfig.h中设置为1,或者未定义(在这种情况下它将默认为1),这样RTOS API函数才可用。
每个任务都需要RAM来保存任务状态,并被任务用作它的堆栈。如果一个任务是使用xTaskCreate()创建的,那么所需的RAM会自动从FreeRTOS堆分配。如果一个任务是使用xTaskCreateStatic()创建的,那么RAM是由应用程序编写器提供的,因此它可以在编译时静态分配。
如果正在使用FreeRTOS-MPU,那么建议使用xTaskCreateRestricted()而不是xTaskCreate()。
参数:
pvTaskCode | 指向任务入口函数的指针(只是实现任务的函数的名称,参见下面的示例)。 任务通常被实现为一个无限循环;实现该任务的函数绝对不能试图返回或退出。但是,任务可以删除自己。 |
pcName | 任务的文本名称。这主要用于方便调试,也可以用来获取任务句柄。 任务名的最大长度由FreeRTOSConfig.h中的configMAX_TASK_NAME_LEN定义。 |
usStackDepth | 分配给任务的堆栈的字数(不是字节!)例如,如果堆栈是16位宽,而usStackDepth是100,那么将分配200字节作为任务的堆栈。另一个例子,如果堆栈是32位宽,而usStackDepth是400,那么将分配1600字节作为任务的堆栈。 usStackDepth 乘以 堆栈宽度 不得超过 size_t 类型变量所能包含的最大值。 查看常见问题:堆栈应该有多大? |
pvParameters | 传递给任务函数的参数。 如果pvParameters被设置为一个变量的地址,那么当创建的任务执行时,这个变量必须仍然存在——所以传递堆栈变量的地址是无效的。 |
uxPriority | 创建的任务执行的优先级。 支持MPU的系统可以通过在uxPriority中设置portPRIVILEGE_BIT位,以特权(系统)模式创建任务。例如,创建优先级为2的特权任务,设置uxPriority为(2 | portPRIVILEGE_BIT)。 优先级被限制小于configMAX_PRIORITIES。如果configASSERT未定义,则优先级被默认地限制为(configMAX_PRIORITIES - 1)。 |
pxCreatedTask | pxCreatedTask用于通过xTaskCreate()函数向创建的任务传递句柄。pxCreatedTask是可选的,可以设置为NULL。 |
返回值:
任务创建成功 | pdPASS |
任务创建失败 | errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY |
使用示例:
-
- /* 需要创建的任务 */
- void vTaskCode( void * pvParameters )
- {
- /* 该参数值预期为1,因为在下面的xTaskCreate()调用中,在pvParameters值中传递了1。*/
- configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
-
- for( ;; )
- {
- /* 任务代码 */
- }
- }
-
- /* 用于创建任务的函数 */
- void vOtherFunction( void )
- {
- BaseType_t xReturned;
- TaskHandle_t xHandle = NULL;
-
- /* 创建任务,存储句柄 */
- xReturned = xTaskCreate(
- vTaskCode, /* 实现该任务的函数. */
- "NAME", /* 任务的文本名称. */
- STACK_SIZE, /* 堆栈大小以字为单位,而不是字节 */
- ( void * ) 1, /* 传入任务的参数 */
- tskIDLE_PRIORITY,/* 任务优先级 */
- &xHandle ); /* 用于传递已创建任务的句柄 */
-
- if( xReturned == pdPASS )
- {
- /* 任务创建完成。使用任务句柄删除任务 */
- vTaskDelete( xHandle );
- }
- }
- TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
- const char * const pcName,
- const uint32_t ulStackDepth,
- void * const pvParameters,
- UBaseType_t uxPriority,
- StackType_t * const puxStackBuffer,
- StaticTask_t * const pxTaskBuffer );
创建一个新任务并将其添加到准备运行的任务列表中。configSUPPORT_STATIC_ALLOCATION必须在FreeRTOSConfig.h中设置为1才能使RTOS API函数可用。
每个任务都需要RAM来保存任务状态,并被任务用作它的堆栈。如果一个任务是使用xTaskCreate()创建的,那么所需的RAM会自动从FreeRTOS堆分配。如果一个任务是使用xTaskCreateStatic()创建的,那么RAM是由应用程序编写器提供的,这将导致更多的参数,但允许在编译时静态分配RAM。
如果使用FreeRTOS-MPU,那么建议使用xTaskCreateRestricted()而不是xTaskCreateStatic()。
参数:
pvTaskCode | 指向任务入口函数的指针(只是实现任务的函数的名称,参见下面的示例)。 任务通常被实现为一个无限循环;实现该任务的函数绝对不能试图返回或退出。但是,任务可以删除自己。 |
pcName | 任务的文本名称。这主要用于方便调试,也可以用来获取任务句柄。 任务名的最大长度由FreeRTOSConfig.h中的configMAX_TASK_NAME_LEN定义。 |
usStackDepth | puxStackBuffer参数用于向xTaskCreateStatic()传递StackType_t变量数组。ulStackDepth必须设置为数组中的索引数。 查看常见问题:堆栈应该有多大? |
pvParameters | 传递给任务函数的参数。 如果pvParameters被设置为一个变量的地址,那么当创建的任务执行时,这个变量必须仍然存在——所以传递堆栈变量的地址是无效的。 |
uxPriority | 创建的任务执行的优先级。 支持MPU的系统可以通过在uxPriority中设置portPRIVILEGE_BIT位,以特权(系统)模式创建任务。例如,创建优先级为2的特权任务,设置uxPriority为(2 | portPRIVILEGE_BIT)。 优先级被限制小于configMAX_PRIORITIES。如果configASSERT未定义,则优先级被默认地限制为(configMAX_PRIORITIES - 1)。 |
puxStackBuffer | 必须指向至少有ulStackDepth索引的StackType_t数组(参见上面的ulStackDepth参数)-该数组将被用作任务的堆栈,因此它必须是持久的(不是在函数的堆栈上声明)。 |
pxTaskBuffer | 必须指向StaticTask_t类型的变量。该变量将用于保存新任务的数据结构(TCB),因此它必须是持久的(没有在函数的堆栈上声明)。 |
返回值:
如果puxStackBuffer和pxTaskBuffer都不为NULL,则创建任务,并返回任务句柄。 |
如果puxStackBuffer或pxTaskBuffer为NULL,则任务不会被创建,返回NULL。 |
使用示例:
- /* 正在创建的任务将用作其堆栈的缓冲区的空间。
- 注意:这是堆栈将保存的单词数,而不是字节数。
- 例如,如果每个堆栈项都是32位,并且设置为100,那么将分配400个字节(100 * 32位)。 */
- #define STACK_SIZE 200
-
- /* 结构,它将保存正在创建的任务的TCB */
- StaticTask_t xTaskBuffer;
-
- /* 正在创建的任务将使用缓冲区作为其堆栈。注意,这是一个StackType_t变量数组。StackType_t的大小与RTOS端口有关。 */
- StackType_t xStack[ STACK_SIZE ];
-
- /* 函数,该函数实现正在创建的任务。 */
- void vTaskCode( void * pvParameters )
- {
- /* 该参数值预期为1,因为1在调用xTaskCreateStatic()的pvParameters值中被传递。 */
- configASSERT( ( uint32_t ) pvParameters == 1UL );
-
- for( ;; )
- {
- /* 任务代码. */
- }
- }
-
- /* 函数,用于创建任务。 */
- void vOtherFunction( void )
- {
- TaskHandle_t xHandle = NULL;
-
- /* 创建任务时不使用任何动态内存分配 */
- xHandle = xTaskCreateStatic(
- vTaskCode, /* 实现该任务的函数 */
- "NAME", /* 任务的文本名称 */
- STACK_SIZE, /* xStack数组中的索引数 */
- ( void * ) 1, /* 传入任务的参数 */
- tskIDLE_PRIORITY,/* 创建任务的优先级 */
- xStack, /* 数组用作任务的堆栈 */
- &xTaskBuffer ); /* 变量来保存任务的数据结构 */
-
- /* puxStackBuffer和pxTaskBuffer不是NULL,所以任务已经创建,xHandle将是任务的句柄。使用句柄暂停任务。 */
- vTaskSuspend( xHandle );
- }
- BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition,
- TaskHandle_t *pxCreatedTask );
创建一个新的内存保护单元(MPU)限制任务,并将其添加到准备运行的任务列表中。configSUPPORT_STATIC_ALLOCATION必须在FreeRTOSConfig.h中设置为1才能使RTOS API函数可用。
在FreeRTOS实现的内部,每个任务需要两个内存块。第一个块用于保存任务的数据结构。第二个块用作任务的堆栈。如果一个任务是使用xTaskCreateRestricted()创建的,那么任务栈的内存由应用程序编写器提供,任务数据结构的内存自动从FreeRTOS堆分配。如果一个任务是使用xTaskCreateRestrictedStatic()创建的,那么应用程序编写器也必须为任务的数据结构提供内存。因此,xTaskCreateRestrictedStatic()允许创建内存保护任务,而无需使用任何动态内存分配。
参数:
pxTaskDefinition | 指向定义任务的TaskParameters_t结构体的指针。该结构将在下文中描述。 |
pxCreatedTask | 用于返回一个句柄,通过该句柄可以引用创建的任务。 |
返回值:
如果任务成功创建并添加到一个就绪列表中,则使用pdPASS,否则将在projdefs.h文件中定义错误代码。
包含MPU支持的任务比不包含MPU支持的任务需要更多的参数来创建。单独地将每个参数传递给xTaskCreateRestrictedStatic()会很麻烦,因此使用结构TaskParameters_t来允许在编译时静态地配置参数。
该结构在task.h中定义为:
- typedef struct xTASK_PARAMETERS
- {
- TaskFunction_t pvTaskCode;
- const signed char * const pcName;
- unsigned short usStackDepth;
- void *pvParameters;
- UBaseType_t uxPriority;
- portSTACK_TYPE *puxStackBuffer;
- MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
- #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
- StaticTask_t * const pxTaskBuffer;
- #endif
- } TaskParameters_t;
其中MemoryRegion_t定义为:
- typedef struct xMEMORY_REGION
- {
- void *pvBaseAddress;
- unsigned long ulLengthInBytes;
- unsigned long ulParameters;
- } MemoryRegion_t;
下面是每个结构成员的描述:
从 pvTaskCode 到 uxPriority
这些成员与发送给xTaskCreate()的同名参数完全相同。
具体来说,uxPriority用于设置任务的优先级和任务执行的模式。例如,创建优先级为2的User模式任务,只需将uxPriority设置为2,创建优先级为2的privilege模式任务,将uxPriority设置为(2 | portPRIVILEGE_BIT)。
puxStackBuffer
每次任务切换时,主控板都会动态地重新配置,定义一个区域,为任务提供对自己栈的读写权限。MPU区域必须满足许多约束条件——特别是,所有这些区域的大小和对齐必须等于相同的2次方值。
标准的FreeRTOS端口使用pvPortMalloc()在每次创建任务时分配一个新的堆栈。提供pvPortMalloc()实现来处理MPU数据对齐需求是可能的,但在RAM使用方面也会变得复杂和低效。为了消除这种复杂性,FreeRTOS-MPU允许在编译时静态声明栈。这允许使用编译器扩展管理对齐,并允许链接器管理RAM使用效率。例如,如果使用GCC,可以使用以下代码声明并正确对齐堆栈:
char cTaskStack[ 1024 ] __attribute__((aligned(1024));
puxStackBuffer通常被设置为静态声明的堆栈的地址。作为替代puxStackBuffer可以设置为NULL 。在这种情况下,pvportmallocalsigned()将被调用来分配任务栈,它是应用程序编写人员的责任来提供pvportmallocalsigned()的实现,以满足MPU的对齐要求。
xRegions
xRegions是MemoryRegion_t结构的数组,每个结构定义了一个用户可定义的内存区域,供正在创建的任务使用。ARM Cortex-M3 FreeRTOS-MPU端口定义portNUM_CONFIGURABLE_REGIONS为3。
pvBaseAddress和ulLengthInBytes成员分别作为内存区域的开始和内存区域的长度是自解释的。
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
pxTaskBuffer
必须指向StaticTask_t类型的变量。变量将用于保存新任务的数据结构,因此它必须是持久的(没有在函数的堆栈上声明)。
使用示例:
- /* 创建一个TaskParameters_t结构,它定义要创建的任务。
- * 只有当configSUPPORT_STATIC_ALLOCATION设置为1时,StaticTask_t变量才包含在结构中。
- PRIVILEGED_DATA宏可用于将变量强制放入RTOS内核的特权数据区域。*/
- static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
- static const TaskParameters_t xCheckTaskParameters =
- {
- vATask, /* pvTaskCode -实现任务的函数 */
- "ATask", /* pcName - 只是用于协助调试的任务的文本名称 */
- 100, /* usStackDepth - 用WORDS定义的堆栈大小 */
- NULL, /* pvParameters - 作为函数参数传入任务函数 */
- ( 1UL | portPRIVILEGE_BIT ),/* uxPriority - 任务优先级,如果任务应该运行在特权状态,设置portPRIVILEGE_BIT */
- cStackBuffer,/* puxStackBuffer - 用作任务栈的缓冲区 */
-
- /* xRegions - 分配最多三个独立的内存区域供任务访问,并具有适当的访问权限。
- 不同的处理器有不同的内存对齐要求-参考FreeRTOS文档获得完整信息。 */
- {
- /* Base address Length Parameters */
- { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
- { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
- { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
- }
-
- &xTaskBuffer; /* 保存任务的数据结构 */
- };
-
- int main( void )
- {
- TaskHandle_t xHandle;
-
- /* 使用上面定义的const结构创建任务。任务句柄被请求(第二个参数不是NULL),
- 但在本例中只是出于演示目的,因为实际上并没有使用它。 */
- xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
-
- /* 开始调度器 */
- vTaskStartScheduler();
-
- /* 只有在没有足够的内存来创建空闲任务 and/or 计时器任务时才会到达这里。 */
- for( ;; );
- }
void vTaskDelete( TaskHandle_t xTask );
INCLUDE_vTaskDelete必须定义为1才能使用该函数。
从RTOS内核管理中删除一个任务。被删除的任务将从所有就绪、阻塞、挂起和事件列表中删除。
注意:空闲任务负责从被删除的任务中释放RTOS内核分配的内存。因此,如果应用程序调用vTaskDelete(),空闲任务不缺乏微控制器处理时间是很重要的。由任务代码分配的内存不会自动释放,应该在删除任务之前释放。
参数:
xTask | 要删除的任务句柄。传递NULL将导致调用任务被删除。 |
使用示例:
- void vOtherFunction( void )
- {
- TaskHandle_t xHandle = NULL;
-
- // Create the task, storing the handle.
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
-
- // Use the handle to delete the task.
- if( xHandle != NULL )
- {
- vTaskDelete( xHandle );
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。