目录
UCOSIII任务堆栈
任务堆栈的创建目的
- 任务堆栈是任务的重要部分
- 堆栈式在RAM中按照“先进先出(FIFO)”的原则组织的一块连续的存储空间
- 为满足任务切换和响应中断时保存CPU寄存器中的内容及任务调用其他函数时的需要
- 每个任务都有自己的堆栈
任务堆栈的创建方法
#define START_STK_SIZE 512 //堆栈大小
CPU_STK START_TASK_STK[START_STK_SIZE]; //定义一个数组来作为任务堆栈
任务堆栈大小的计算
CPU_STK为unsigned int类型为 4字节
堆栈START_TASK_STK的大小就为:512 X 4=2048字节
任务堆栈的初始化的目的
- 在创建一个新任务时,把系统启动这个任务时所需的CPU各个寄存器初始值事先存放在任务堆栈中。
- 当任务获得CPU使用权时,就把任务堆栈的内容复制到CPU的各个寄存器,从而可以任务顺利地启动并运行。
- 总结:堆栈和CPU寄存器的相互转换
任务堆栈初始化的方法
- 把任务初始数据存放到任务堆栈的工作就叫做任务堆栈的初始化
- UCOSIII提供了完成堆栈初始化的函数:OSTaskStkInit()
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
- 一般不会直接操作堆栈初始化函数
- 任务堆栈初始化函数由任务创建函数OSTaskCreate()调用
UCOSIII任务控制块
任务控制块的作用
- 用来记录与任务相关的信息的数据结构,每个任务都要有自己的任务控制块。
- 任务控制块由用户自行创建,如下代码为创建一个任务控制块:
OS_TCB StartTaskTCB; //创建一个任务控制块
注:OS_TCB为一个结构体
任务控制块初始化
- OSTaskCreate()创建任务时,对任务控制块进行初始化。
- OS_TaskInitTCB()初始化任务控制块,不需要自行初始化任务控制块。
UCOSIII任务就绪表
优先级
- UCOSIII中任务优先级数由宏OS_CFG_PRIO_MAX来配置
- UCOSIII中数值越小,优先级越高,最低可用优先级就是OS_CFG_PRIO_MAX-1
就绪表
- 优先级位映射表OSPrioTbl[]:用来记录哪个优先级下有任务就绪。
- 就绪任务列表OSRdyList[]:用来记录每一个优先级下所有就绪的任务。
就绪最高优先级寻找
- 函数OS_PrioGetHighest()用于找到就绪了的最高优先级的任务
- UCOSIII支持时间片轮转调度,需要在确定优先级下的哪个任务就绪了
UCOSIII任务调度
任务调度概念
- 任务调度就是中止当前正在运行的任务转而去执行其他的任务。
可剥夺型任务调度
- 任务级调度器函数:OSSched()
- 中断级调度器函数:OSIntExit()
任务调度点
- 使用延时函数OSTimeDly()或者OSTimeDlyHMSM()
- 创建任务
- 删除任务
- 任务通过调用OSTaskSuspend()将自身挂起
- 任务解挂某个挂起的任务
- 用户调用OSSched()
- 通过OSSchedUnlock()给调度器解锁
- 时间片轮转调度(给每个任务指定执行时间,时间到达执行下一个任务)
UCOSIII任务切换
任务切换概念
- 当UCOSIII需要切换到另外一个任务时,它将保存当前任务的现场到当前任务的堆栈中,主要是CPU寄存器值,然后恢复新的现场并且执行新的任务,这个过程叫任务切换
任务切换函数
- 任务级切换函数为:OSCtxSw()
- 中断级切换函数为:OSIntCtxSw()
UCOSIII系统初始化和启动
int main(void)
{
OS_ERR err;
……
//其他函数,一般为外设初始化函数
……
OSInit(&err);//UCOSIII初始化必须先于其他UCOSIII调度函数
……
//其他函数,一般为创建任务函数
……
OSStart(&err);
}