当前位置:   article > 正文

FreeRTOS库函数 API Reference(一)任务创建_xtaskcreaterestricted

xtaskcreaterestricted

目录

任务创建(Task Creation)

1.xTaskCreate(创建一个新任务并将其添加到准备运行的任务列表中)

2.xTaskCreateStatic(创建一个新任务并将其添加到准备运行的任务列表中)

3.xTaskCreateRestrictedStatic(创建一个新的内存保护单元(MPU)限制任务,并将其添加到准备运行的任务列表中)

4.vTaskDelete(从RTOS内核管理中删除一个任务)


英文原文:

FreeRTOS - A FREE Open Source RTOS. The Free RTOS API functions for creating RTOS tasks and deleting RTOS tasks - xTaskCreate() and vTaskDelete.https://www.freertos.org/a00019.html

任务创建(Task Creation)

1.xTaskCreate(创建一个新任务并将其添加到准备运行的任务列表中)

  1. BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
  2. const char * const pcName,
  3. configSTACK_DEPTH_TYPE usStackDepth,
  4. void *pvParameters,
  5. UBaseType_t uxPriority,
  6. 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 类型变量所能包含的最大值。

 查看常见问题:堆栈应该有多大?

FreeRTOS创建任务的堆栈应该有多大?_QxNL的博客-CSDN博客

pvParameters

传递给任务函数的参数。

如果pvParameters被设置为一个变量的地址,那么当创建的任务执行时,这个变量必须仍然存在——所以传递堆栈变量的地址是无效的。

uxPriority

创建的任务执行的优先级。

支持MPU的系统可以通过在uxPriority中设置portPRIVILEGE_BIT位,以特权(系统)模式创建任务。例如,创建优先级为2的特权任务,设置uxPriority为(2 | portPRIVILEGE_BIT)。

优先级被限制小于configMAX_PRIORITIES。如果configASSERT未定义,则优先级被默认地限制为(configMAX_PRIORITIES - 1)。

pxCreatedTaskpxCreatedTask用于通过xTaskCreate()函数向创建的任务传递句柄。pxCreatedTask是可选的,可以设置为NULL。

返回值:

任务创建成功pdPASS
任务创建失败errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY

使用示例:

  1. /* 需要创建的任务 */
  2. void vTaskCode( void * pvParameters )
  3. {
  4. /* 该参数值预期为1,因为在下面的xTaskCreate()调用中,在pvParameters值中传递了1。*/
  5. configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
  6. for( ;; )
  7. {
  8. /* 任务代码 */
  9. }
  10. }
  11. /* 用于创建任务的函数 */
  12. void vOtherFunction( void )
  13. {
  14. BaseType_t xReturned;
  15. TaskHandle_t xHandle = NULL;
  16. /* 创建任务,存储句柄 */
  17. xReturned = xTaskCreate(
  18. vTaskCode, /* 实现该任务的函数. */
  19. "NAME", /* 任务的文本名称. */
  20. STACK_SIZE, /* 堆栈大小以字为单位,而不是字节 */
  21. ( void * ) 1, /* 传入任务的参数 */
  22. tskIDLE_PRIORITY,/* 任务优先级 */
  23. &xHandle ); /* 用于传递已创建任务的句柄 */
  24. if( xReturned == pdPASS )
  25. {
  26. /* 任务创建完成。使用任务句柄删除任务 */
  27. vTaskDelete( xHandle );
  28. }
  29. }

2.xTaskCreateStatic(创建一个新任务并将其添加到准备运行的任务列表中)

  1. TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
  2. const char * const pcName,
  3. const uint32_t ulStackDepth,
  4. void * const pvParameters,
  5. UBaseType_t uxPriority,
  6. StackType_t * const puxStackBuffer,
  7. 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必须设置为数组中的索引数。

 查看常见问题:堆栈应该有多大?

FreeRTOS创建任务的堆栈应该有多大?_QxNL的博客-CSDN博客

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。

使用示例:

  1. /* 正在创建的任务将用作其堆栈的缓冲区的空间。
  2. 注意:这是堆栈将保存的单词数,而不是字节数。
  3. 例如,如果每个堆栈项都是32位,并且设置为100,那么将分配400个字节(100 * 32位)。 */
  4. #define STACK_SIZE 200
  5. /* 结构,它将保存正在创建的任务的TCB */
  6. StaticTask_t xTaskBuffer;
  7. /* 正在创建的任务将使用缓冲区作为其堆栈。注意,这是一个StackType_t变量数组。StackType_t的大小与RTOS端口有关。 */
  8. StackType_t xStack[ STACK_SIZE ];
  9. /* 函数,该函数实现正在创建的任务。 */
  10. void vTaskCode( void * pvParameters )
  11. {
  12. /* 该参数值预期为1,因为1在调用xTaskCreateStatic()的pvParameters值中被传递。 */
  13. configASSERT( ( uint32_t ) pvParameters == 1UL );
  14. for( ;; )
  15. {
  16. /* 任务代码. */
  17. }
  18. }
  19. /* 函数,用于创建任务。 */
  20. void vOtherFunction( void )
  21. {
  22. TaskHandle_t xHandle = NULL;
  23. /* 创建任务时不使用任何动态内存分配 */
  24. xHandle = xTaskCreateStatic(
  25. vTaskCode, /* 实现该任务的函数 */
  26. "NAME", /* 任务的文本名称 */
  27. STACK_SIZE, /* xStack数组中的索引数 */
  28. ( void * ) 1, /* 传入任务的参数 */
  29. tskIDLE_PRIORITY,/* 创建任务的优先级 */
  30. xStack, /* 数组用作任务的堆栈 */
  31. &xTaskBuffer ); /* 变量来保存任务的数据结构 */
  32. /* puxStackBuffer和pxTaskBuffer不是NULL,所以任务已经创建,xHandle将是任务的句柄。使用句柄暂停任务。 */
  33. vTaskSuspend( xHandle );
  34. }

3.xTaskCreateRestrictedStatic(创建一个新的内存保护单元(MPU)限制任务,并将其添加到准备运行的任务列表中)

  1. BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition,
  2. 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中定义为:

  1. typedef struct xTASK_PARAMETERS
  2. {
  3. TaskFunction_t pvTaskCode;
  4. const signed char * const pcName;
  5. unsigned short usStackDepth;
  6. void *pvParameters;
  7. UBaseType_t uxPriority;
  8. portSTACK_TYPE *puxStackBuffer;
  9. MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
  10. #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
  11. StaticTask_t * const pxTaskBuffer;
  12. #endif
  13. } TaskParameters_t;

其中MemoryRegion_t定义为:

  1. typedef struct xMEMORY_REGION
  2. {
  3. void *pvBaseAddress;
  4. unsigned long ulLengthInBytes;
  5. unsigned long ulParameters;
  6. } 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。

pvBaseAddressulLengthInBytes成员分别作为内存区域的开始和内存区域的长度是自解释的。

ulParameters定义了任务如何被允许访问内存区域,可以取以下值的位或:

  1. portMPU_REGION_READ_WRITE
  2. portMPU_REGION_PRIVILEGED_READ_ONLY
  3. portMPU_REGION_READ_ONLY
  4. portMPU_REGION_PRIVILEGED_READ_WRITE
  5. portMPU_REGION_CACHEABLE_BUFFERABLE
  6. portMPU_REGION_EXECUTE_NEVER

pxTaskBuffer

必须指向StaticTask_t类型的变量。变量将用于保存新任务的数据结构,因此它必须是持久的(没有在函数的堆栈上声明)。

使用示例:

  1. /* 创建一个TaskParameters_t结构,它定义要创建的任务。
  2. * 只有当configSUPPORT_STATIC_ALLOCATION设置为1时,StaticTask_t变量才包含在结构中。
  3. PRIVILEGED_DATA宏可用于将变量强制放入RTOS内核的特权数据区域。*/
  4. static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
  5. static const TaskParameters_t xCheckTaskParameters =
  6. {
  7. vATask, /* pvTaskCode -实现任务的函数 */
  8. "ATask", /* pcName - 只是用于协助调试的任务的文本名称 */
  9. 100, /* usStackDepth - 用WORDS定义的堆栈大小 */
  10. NULL, /* pvParameters - 作为函数参数传入任务函数 */
  11. ( 1UL | portPRIVILEGE_BIT ),/* uxPriority - 任务优先级,如果任务应该运行在特权状态,设置portPRIVILEGE_BIT */
  12. cStackBuffer,/* puxStackBuffer - 用作任务栈的缓冲区 */
  13. /* xRegions - 分配最多三个独立的内存区域供任务访问,并具有适当的访问权限。
  14. 不同的处理器有不同的内存对齐要求-参考FreeRTOS文档获得完整信息。 */
  15. {
  16. /* Base address Length Parameters */
  17. { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
  18. { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
  19. { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
  20. }
  21. &xTaskBuffer; /* 保存任务的数据结构 */
  22. };
  23. int main( void )
  24. {
  25. TaskHandle_t xHandle;
  26. /* 使用上面定义的const结构创建任务。任务句柄被请求(第二个参数不是NULL),
  27. 但在本例中只是出于演示目的,因为实际上并没有使用它。 */
  28. xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
  29. /* 开始调度器 */
  30. vTaskStartScheduler();
  31. /* 只有在没有足够的内存来创建空闲任务 and/or 计时器任务时才会到达这里。 */
  32. for( ;; );
  33. }

4.vTaskDelete(从RTOS内核管理中删除一个任务)

void vTaskDelete( TaskHandle_t xTask );

INCLUDE_vTaskDelete必须定义为1才能使用该函数。

从RTOS内核管理中删除一个任务。被删除的任务将从所有就绪、阻塞、挂起和事件列表中删除。

注意:空闲任务负责从被删除的任务中释放RTOS内核分配的内存。因此,如果应用程序调用vTaskDelete(),空闲任务不缺乏微控制器处理时间是很重要的。由任务代码分配的内存不会自动释放,应该在删除任务之前释放。

参数:

xTask 要删除的任务句柄。传递NULL将导致调用任务被删除。

使用示例:

  1. void vOtherFunction( void )
  2. {
  3. TaskHandle_t xHandle = NULL;
  4. // Create the task, storing the handle.
  5. xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
  6. // Use the handle to delete the task.
  7. if( xHandle != NULL )
  8. {
  9. vTaskDelete( xHandle );
  10. }
  11. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/398057
推荐阅读
相关标签
  

闽ICP备14008679号