任务池库 - FreeRTOS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

任务池库

概览

FreeRTOS 支持通过 FreeRTOS 任务池库的任务管理。任务池库让您可以计划后台任务,并允许安全的异步任务计划和取消。使用任务池 API,您可以配置应用程序任务以优化在性能与内存占用之间的权衡。

任务池库构建在两个主数据结构之上:任务池和任务池作业。

任务池 (IotTaskPool_t)

任务池包含分派队列,管理要执行的作业队列,并管理执行作业的工作线程。

任务池作业 (IotTaskPoolJob_t)

任务池作业可以作为后台作业或者定时后台作业执行。后台作业按照先入先出的顺序启动,没有时间约束。定时作业根据计时器计划在后台的执行。

注意

任务池只能保证定时作业在经过超时时间之后执行,不能保证在特定的时段内执行。

依赖项和要求

任务池库具有以下依赖项:

  • 线性容器(列表/队列)库,用于维护所计划和进行中任务池操作的数据结构。

  • 日志记录库(如果 IOT_LOG_LEVEL_TASKPOOL 配置位置不是 IOT_LOG_NONE)。

  • 一个平台层,提供与操作系统的接口,用于线程管理、计时器、时钟功能等。

功能

使用任务池库 API,您可以执行以下操作:

  • 使用库的非阻塞 API 函数计划立即执行的作业和延迟作业。

  • 创建静态和动态分配的作业。

  • 配置库设置,使之根据您的系统资源来扩展性能和占用。

  • 动态创建作业时,自定义缓存以实现低内存开销。

故障排除

任务池库函数以 IotTaskPoolError_t 枚举值格式返回错误代码。有关各个错误代码的更多信息,请参阅任务池 C 开发工具包 API 参考IotTaskPoolError_t 枚举数据类型的参考文档。

使用限制

任务池库不能从中断服务例程 (ISR) 使用。

我们强烈反对执行阻塞操作的任务池用户回调,特别是无限期阻塞操作。长时间的阻塞操作会很快地占据任务线程池,并可能造成死锁或不足。

初始化

应用程序需要在使用任务池之前调用 IotTaskPool_CreateSystemTaskPool 以初始化系统任务池的实例。应用程序需要确保在引导顺序中,系统级别的任务池在足够早的时间进行了初始化,要早于使用任务池的任何库,并早于向任务池发布作业的任何应用程序代码。在引导之后不久,系统为所有库初始化一个系统级别的任务池以共享。初始化之后,可以检索任务池句柄来与 IOT_SYSTEM_TASKPOOL API 配合使用。

注意

调用 IotTaskPool_CreateSystemTaskPool 不会分配内存以保存任务池数据结构和状态,但它可能会分配内存以保存依赖项实体和数据结构,例如任务池的线程。

API 参考

有关完整 API 参考,请参阅任务池 C 开发工具包 API 参考

示例用法

假设您需要计划定期收集 AWS IoT Device Defender 指标,并且您决定使用计时器,计划通过对 MQTT 连接、订阅和发布 API 的调用来计划收集。以下代码定义了一个回调函数,用于通过 MQTT 接受 AWS IoT Device Defender 指标,并有一个断开连接回调以从 MQTT 连接中断开。

/* An example of a user context to pass to a callback through a task pool thread. */ typedef struct JobUserContext { uint32_t counter; } JobUserContext_t; /* An example of a user callback to invoke through a task pool thread. */ static void ExecutionCb( IotTaskPool_t * pTaskPool, IotTaskPoolJob_t * pJob, void * context ) { ( void )pTaskPool; ( void )pJob; JobUserContext_t * pUserContext = ( JobUserContext_t * )context; pUserContext->counter++; } void TaskPoolExample( ) { JobUserContext_t userContext = { 0 }; IotTaskPoolJob_t job; IotTaskPool_t * pTaskPool; IotTaskPoolError_t errorSchedule; /* Configure the task pool to hold at least two threads and three at the maximum. */ /* Provide proper stack size and priority per the application needs. */ const IotTaskPoolInfo_t tpInfo = { .minThreads = 2, .maxThreads = 3, .stackSize = 512, .priority = 0 }; /* Create a task pool. */ IotTaskPool_Create( &tpInfo, &pTaskPool ); /* Statically allocate one job, then schedule it. */ IotTaskPool_CreateJob( &ExecutionCb, &userContext, &job ); errorSchedule = IotTaskPool_Schedule( pTaskPool, &job, 0 ); switch ( errorSchedule ) { case IOT_TASKPOOL_SUCCESS: break; case IOT_TASKPOOL_BAD_PARAMETER: // Invalid parameters, such as a NULL handle, can trigger this error. case IOT_TASKPOOL_ILLEGAL_OPERATION: // Scheduling a job that was previously scheduled or destroyed could trigger this error. case IOT_TASKPOOL_NO_MEMORY: // Scheduling a with flag #IOT_TASKPOOL_JOB_HIGH_PRIORITY could trigger this error. case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS: // Scheduling a job after trying to destroy the task pool could trigger this error. // ASSERT break; default: // ASSERT*/ } /* ................................. */ /* ... Perform other operations ... */ /* ................................. */ IotTaskPool_Destroy( pTaskPool ); }