当前位置:网站首页>FreeRTOS任务基础
FreeRTOS任务基础
2022-08-09 22:39:00 【小梁不偷懒】
任务特性
- 没有数量限制(一个优先级下也可以拥有多个任务)
- 支持抢占(FreeRTOS为抢占式内核高优先级可以抢占低优先级的CPU使用权)
- 支持优先级(决定任务运行的先后)
- 每个任务都拥有堆栈导致了RAM使用量增大
- 抢占需考虑重入问题
任务状态
- 运行态(当前任务正在运行就是运行态)
- 就绪态(任务准备运行,所有就绪态态中优先级最高的任务下一次运行)
- 阻塞态(某个需要事件来引发的任务,事件没有发生时该任务的状态)
- 挂起态(暂停运行,有挂起和解挂两个过程)
这四个状态是可以互相转化的,刚创建好的任务是处于就绪态的,具体的转化过程如下图所示:
任务优先级
任务的优先级决定了任务执行的先后,在FreeRTOS中有32个优先级即0到31,数字越大优先级越高!
任务实现
void vATaskFunction(void *pvParameters)
{
while(1)//for(;;)
{
任务程序
vTaskDelay();
}
vTaskDelay();
}
上方代码为任务实现的基本框架,要注意的是任务中途不能返回或退出,如果一定要退出的话需要调用vTaskDelay(NULL)来删除此任务。
任务控制块(描述任务属性的数据结构)
FreeRTOS 的每个任务都有一些属性需要存储,FreeRTOS 把这些属性集合到一起用一个结
构体来表示,这个结构体叫做任务控制块:TCB_t,在使用函数 xTaskCreate()创建任务的时候就会自动的给每个任务分配一个任务控制块。
typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack; //任务堆栈栈顶
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGSxMPUSettings; //MPU 相关设置
#endif
ListItem_t xStateListItem; //状态列表项
ListItem_t xEventListItem; //事件列表项
UBaseType_t uxPriority; //任务优先级
StackType_t *pxStack; //任务堆栈起始地址
char pcTaskName[ configMAX_TASK_NAME_LEN ];//任务名字
#if ( portSTACK_GROWTH > 0 )
StackType_t *pxEndOfStack; //任务堆栈栈底
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting; //临界区嵌套深度
#endif
#if ( configUSE_TRACE_FACILITY == 1 ) //trace 或到 debug 的时候用到
UBaseType_t uxTCBNumber;
UBaseType_t uxTaskNumber;
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; //任务基础优先级,优先级反转的时候用到
UBaseType_t uxMutexesHeld; //任务获取到的互斥信号量个数
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) //与本地存储有关
void
*pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulRunTimeCounter; //用来记录任务运行总时间
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xNewLib_reent; //定义一个 newlib 结构体变量
#endif
#if( configUSE_TASK_NOTIFICATIONS == 1 )//任务通知相关变量
volatile uint32_t ulNotifiedValue; //任务通知值
volatile uint8_t ucNotifyState; //任务通知状态
#endif
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
//用来标记任务是动态创建的还是静态创建的,如果是静态创建的此变量就为 pdTURE,
//如果是动态创建的就为 pdFALSE
uint8_t ucStaticallyAllocated;
#endif
#if( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
} tskTCB;
//新版本的 FreeRTOS 任务控制块重命名为 TCB_t,但是本质上还是 tskTCB,主要是为了兼容
//旧版本的应用。
typedef tskTCB TCB_t;
上述代码为TCB_t结构体在tasks.c 中的定义。
任务堆栈
FreeRTOS是依靠堆栈来回复一个任务的运行的,任务调度器在切换任务的时候就是使用堆栈来恢复任务原现场的。
创建任务的时候需要给任务指定堆栈,如果使用的函数 xTaskCreate()创建任务(动态方法)
的话那么任务堆栈就会由函数 xTaskCreate()自动创建;如果使用函数 xTaskCreateStatic()创建任务(静态方法)的话就需要程序员自行定义任务堆栈,然。后堆栈首地址作为函数的参数 puxStackBuffer 传递给函数。
堆栈的大小
不管是使用函数 xTaskCreate()还是 xTaskCreateStatic()创建任务都需要指定任务堆栈大小。任务堆栈的数据类型为 StackType_t,StackType_t 本质上是 uint32_t,在 portmacro.h 中有如下定义
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
注意:StackType_t 类型的变量为 4 个字节,那么任务的实际堆栈大小就应该是我们所
定义的 4 倍
边栏推荐
- 【集训DAY3】挖金矿【二分答案】
- tiup cluster start
- Sqlserver restricts the ip under which accounts can access the database
- 什么是平面文件数据库? 如何导入多种格式的文件:DSV、JSON、XML?
- 34. Fabric2.2 证书目录里各文件作用
- 中国SaaS企业排名,龙头企业Top10梳理
- ElasticSearcch集群
- Gartner's global integrated system market data tracking, hyperconverged market growth rate is the first
- Mysql集群 ShardingSphere
- 【哲理】读书的意义
猜你喜欢

Has your phone ever been monitored?

恭喜获奖得主 | 互动有礼获赠 Navicat Premium

Mysql/stonedb - slow SQL - 2022-08-09 Q16 analysis

外包的水有多深?腾讯15k的外包测试岗能去吗?

2020年度SaaS TOP100企业名单

Live Preview | ICML 2022 11 first-author scholars share online neural network, graph learning and other cutting-edge research

SRv6性能测量

用哈希简单封装unordered_map和unordered_set

位图的基本原理以及应用

全面解析FPGA基础知识
随机推荐
Gumbel distribution of discrete choice model
【SSL集训DAY2】有趣的数【数位DP】
【励志】名言警句
leetcode 20. Valid Parentheses 有效的括号(中等)
为什么刀具数据库无法打开?
集群的基础形式
JS基础笔记-关于对象
干货!迈向鲁棒的测试时间适应
【SSL集训DAY2】Sequence【数学】
matplotlib散点图颜色分组图例
Controller层代码这么写,简洁又优雅!
CMake使用记录
Sqlserver restricts the ip under which accounts can access the database
经济衰退即将来临前CIO控制成本的七种方法
你的手机曾经被监控过吗?
Qt 之 QDateEdit 和 QTimeEdit
打包报错 AAPT: error: failed to read PNG signature: file does not start with PNG signature.
68. qt quick-qml multi-level folding drop-down navigation menu supports dynamic add/unload, support qml/widget loading, etc.
全面解析FPGA基础知识
关于服务治理