FreeRTOS静态和动态创建任务
时间:2022-07-24
本文章向大家介绍FreeRTOS静态和动态创建任务,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
静态创建任务 源代码 xTaskCreateStatic 静态的方式创建任务,需要用户先申请任务控制模块和任务栈需要的内存(一般使用静态内存),然后把内存地址传递给函数,函数负责其他初始化。 函数按顺序完成: * 根据用户传递内存,初始化任务 TCB * 初始化任务堆栈 * 将新建任务加入到就绪链表中 * 如果调度器运行,新任务优先级更高,触发系统切换
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 )
{
TCB_t *pxNewTCB;
TaskHandle_t xReturn;
configASSERT( puxStackBuffer != NULL );
configASSERT( pxTaskBuffer != NULL );
if ((pxTaskBuffer != NULL) && (puxStackBuffer != NULL))
{
// 设置用户传递进来的任务控制块和栈的内存地址到对应指针变量
pxNewTCB = (TCB_t *)pxTaskBuffer;
pxNewTCB->pxStack = (StackType_t *)puxStackBuffer;
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
{
// 标识这个任务控制块和栈内存时静态的
// 删除任务的时候, 系统不会做内存回收处理
pxNewTCB->ucStaticallyAllocated =
tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
}
#endif
// 初始化任务控制块 下文介绍
prvInitialiseNewTask( pxTaskCode, pcName,
ulStackDepth, pvParameters, uxPriority,
&xReturn, pxNewTCB, NULL );
// 把新任务插入就绪链表 下文介绍
prvAddNewTaskToReadyList( pxNewTCB );
}
else
{
xReturn = NULL;
}
return xReturn;
}
动态创建任务 源代码 xTaskCreate 动态创建任务, 调用函数内部向系统申请创建新任务所需的内存,包括任务控制块和栈。 所以调用这个函数,在内存堆空间不足或者碎片话的情况下,可能创建新任务失败,需要判断函数执行后是否成功返回。 其源码解析如下所示。
BaseType_t xTaskCreate(
TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
{
TCB_t *pxNewTCB;
BaseType_t xReturn;
// 如果是向下增长的栈, 先申请栈内存再申请任务控制块内存
// 可以避免栈溢出覆盖了自己任务控制块
// 对应向上增长的则相反
// 在旧版本 V8.0.0 中没有这么处理,统一先 TCB 后 Stack
// 项目上碰到平台栈向下增长, 栈溢出错时候覆盖了自己的 TCB
// 导致调试的时候无法获取出错任务信息(比如任务名)
#if( portSTACK_GROWTH > 0 )
{
// 申请任务控制块内存
pxNewTCB = (TCB_t *)pvPortMalloc(sizeof(TCB_t));
if( pxNewTCB != NULL )
{
// 申请栈内存, 返回地址设置任务中的栈指针
pxNewTCB->pxStack = (StackType_t *)pvPortMalloc(
(((size_t)usStackDepth) * sizeof(StackType_t)));
if( pxNewTCB->pxStack == NULL )
{
// 栈内存申请失败, 释放前面申请的任务控制块内存
vPortFree( pxNewTCB );
pxNewTCB = NULL;
}
}
}
#else /*栈向下增长*/
{
StackType_t *pxStack;
pxStack = (StackType_t *)pvPortMalloc(
(((size_t)usStackDepth) * sizeof(StackType_t)));
if( pxStack != NULL )
{
pxNewTCB = (TCB_t *)pvPortMalloc(sizeof(TCB_t));
if( pxNewTCB != NULL )
{
pxNewTCB->pxStack = pxStack;
}
else
{
vPortFree( pxStack );
}
}
else
{
pxNewTCB = NULL;
}
}
#endif
if( pxNewTCB != NULL )
{
// 成功申请所需内存 执行任务初始化操作
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
{
// 标志任务控制块和栈是动态申请
// 删除任务系统会自动回收内存
pxNewTCB->ucStaticallyAllocated =
tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
// 初始任务控制块
prvInitialiseNewTask(pxTaskCode, pcName,
(uint32_t)usStackDepth, pvParameters,
uxPriority, pxCreatedTask, pxNewTCB, NULL );
// 将新任务插入到就绪链表
prvAddNewTaskToReadyList( pxNewTCB );
xReturn = pdPASS;
}
else
{
// 创建任务失败,返回错误码
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn;
}
- Pegasus间谍套件内部原理及流程剖析
- 用node.js实现ORM的一种思路
- iOS“远程越狱”间谍软件Pegasus技术分析
- 学习HTML5之表单
- 基于jQuery的ajax对WebApi和OData的封装我们还是先来看看要求在看看目标:思路封装方式
- js的动态加载、缓存、更新以及复用(四)
- ajax的再次封装!(改进版) —— new与不 new 有啥区别?
- ajax的再次封装!
- 【自然框架】js版的QuickPager分页控件 V2.0
- 你的SQL语句放在了哪里?
- oclhashcat:离线hash密码破解工具官方文档(中文版)
- 如何动态加载js?
- 【自然框架】数据访问之精雕细琢(一)存储过程的参数
- 100w条记录分页,可以有多快?—— DataReader分页与SQL语句分页的对比测试(在线演示)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法