02常用任务函数

1.任务创建和删除

任务创建和删除调用的API函数。

函数 描述
xTaskCreate() 使用动态的方法创建一个任务
xTaskCreateStatic() 使用静态的方法创建一个任务
vTaskDelete() 删除一个任务

(1)任务创建和删除(动态方法)

  • 使用动态任务创建函数 xTaskCreate() 来创建一个任务,任务需要 RAM 来保存与任务有关的状态信息,也需要一定的 RAM 来作为任务堆栈。所需的 RAM 就会自动的从 FreeRTOS 的堆中分配,因此必须提供内存管理文件,默认使用
    heap_4.c 这个内存管理文件,而且宏 configSUPPORT_DYNAMIC_ALLOCATION 必须为 1,支持动态内存申请。新创建的任务默认就是就绪态的,如果当前没有比它更高优先级的任务运行那么此任务就会立即进入运行态开始运行,不管在任务调度器启动前还是启动后,都可以创建任务。
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,   //任务入口函数
                        const char * const pcName,  //任务名字
                        const uint16_t usStackDepth,//任务栈大小
                        void * const pvParameters,  //任务入口函数参数
                        UBaseType_t uxPriority,    //任务的优先级,0-31
                        TaskHandle_t * const pxCreatedTask ) //任务句柄
  • 动态创建及内部实现:
    ① 申请堆栈内存(返回首地址)
    ②申请任务控制块内存(返回首地址)
    ③把申请的堆栈地址赋值给控制块的堆栈成员
    ④调用 prvInitialiseNewTask 初始化任务控制块中的成员

    • 初始化堆栈为0xa5(可选);
    • 记录栈顶,保存在 pxTopOfStack;
    • 保存任务名字到 pxNewTCB->pcTaskName[x]中;
    • 保存任务优先级到 pxNewTCB->uxPriority;
    • 设置状态列表项的所属控制块,设置事件列表项的值;
    • 列表项的插入是从小到大插入,将越高优先级的任务事件列表项值设置越小就可以排到前面;
    • 调用 pxPortInitialiseStack 初始化任务栈,用于保存当前任务上下文寄存器信息,以备后续任务切换使用;
    • 将任务句柄等于任务控制块。

    ⑤调用 prvAddNewTaskToReadyList 添加新创建任务到就绪列表中

    • 记录任务数量 uxCurrentNumberOfTasks++;
    • 判断新创建的任务是否为第一个任务
      • 是第一个任务,初始化任务列表 prvInitialiseTaskLists;
      • 不是第一个任务,并且调度器还未启动,比较新任务与正在执行的任务优先级大小,新任务优先级大的话,将当前控制块指向新的控制块。
    • 将新的任务控制块添加到就绪列表中,使用函数 prvAddNewTaskToReadyList
    • 如果调度器已经开始运行,并且新任务的优先级更大的话,进行一次任务切换。

(2)任务创建和删除(静态方法)

  • ① 使用函数 xTaskCreateStatic()创建,这些 RAM 就需要用户来提供,configSUPPORT_STATIC_ALLOCATION 定义为 1。

  • ② 定义空闲任务和定时器任务的任务堆栈、PCB及实现两个接口函数

空闲任务使用vApplicationGetIdleTaskMemory()函数

参数:

  • ppxIdleTaskTCBBuffer:任务控制块内存
  • ppxIdleTaskStackBuffer:任务堆栈内存
  • pulIdleTaskStackSize:任务堆栈大小

void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
								   StackType_t **ppxIdleTaskStackBuffer, 
								   uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&IdleTaskTCB;      //任务控制块内存
	*ppxIdleTaskStackBuffer=IdleTaskStack;   //任务堆栈内存 
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE; //任务堆栈大小
}
  • 定时器任务使用vApplicationGetTimerTaskMemory()函数
    参数:
  • ppxTimerTaskTCBBuffer:任务控制块内存
  • ppxTimerTaskStackBuffer:任务堆栈内存
  • pulTimerTaskStackSize:任务堆栈大小
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 
									StackType_t **ppxTimerTaskStackBuffer, 
									uint32_t *pulTimerTaskStackSize)
{
	*ppxTimerTaskTCBBuffer=&TimerTaskTCB;     //任务控制块内存
	*ppxTimerTaskStackBuffer=TimerTaskStack;  //任务堆栈内存
	*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH; //任务堆栈大小
}

③定义函数入口参数

④编写任务函数

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 )//任务控制块

posted @ 2023-09-05 20:50  xioahuhu  阅读(18)  评论(0编辑  收藏  举报