UC/OS基础知识之任务堆栈
1.任务堆栈
所谓堆栈就是在存储器中按数据“后进先出(LIFO)”的原则组织的连续存储空间,为了满足任务切换和响应中断时保存CPU寄存器中的内容及任务调用其他函数时的需要,每个任务都应该配有自己的堆栈。每个任务控制块都有一个指向该任务堆栈的指针。
PO:堆栈是一种简单的数据结构,是一种只允许在其一端进行插入或删除的线性表。允许插入或删除操作的一端称为栈顶,另一端称为栈底,对堆栈的插入和删除操作被称为入栈和出栈。有一组CPU指令可以实现对进程的内存实现堆栈访问。其中,POP指令实现出栈操作,PUSH指令实现入栈操作。
注意:
堆栈的增长方向随系统所使用的处理器不同而不同,在使用OSTaskCreate()来创建任务时,一定要注意堆栈的增长方向。
在OS_CFG.H文件中的常数OS_STK_GROWTH 作为选择开关,默认为向上增长。
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on 80x86 */
2.任务堆栈的创建
在OS_CPU.H中专门定义了一个数据类型OS_STK
typedef unsigned short OS_STK; // Each stack entry is 16-bit wide
在定义任务堆栈的时候,只要定义一个OS_STK类型的数组即可
#define TASK_STK_SIZE 512//定义堆栈的长度为1024个字节
OS_STK TaskStk[TASK_STK_SIZE];//定义一个数组作为任务堆栈
在调用函数OSTaskCreate()来创建一个任务时,把数组的指针传递给OSTaskCreate()中的堆栈栈顶参数ptos,就可以把该数组与任务关联起来而成为该任务的任务堆栈。OSTaskCreate()的原型:
INT8U OSTaskCreate (
void (*task)(void *p_arg),//指向任务的指针
void *p_arg,//传递给任务的参数
OS_STK *ptos,//指向任务堆栈栈顶指针
INT8U prio)//任务的优先级别
3.任务堆栈的初始化
当CPU在启动运行一个任务时,CPU各寄存器总是需要预置一些初始数据,例如任务的指针,程序状态字PSW等,由于他们都是任务的私有数据,所以应将他们存放在任务堆栈中。把任务初始数及存放到任务堆栈的工作就叫做任务堆栈的初始化,UC/OS在OS_CPU_C.C中提供了堆栈初始化函数OSTaskStkInit(),函数原型如下:
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
OS_EMU_STK *stk;
stk=(OS_EMU_STK *)((char*)ptos-sizeof(OS_EMU_STK)); /* Load stack pointer*/
stk->pData = pdata;
stk->Opt = opt;
stk->Task = task;
stk->Handle = NULL;
stk->Id = 0;
stk->Exit = 0;
return ((void *)stk);
}