ucos堆栈和任务控制块初始化

当操作系统要建立一个进程时操作系统首先要对栈空间和进程控制块进行初始化,这里的栈是为任务在内存里开辟的一块的模拟的堆栈区域,主要用来保存CPU的所有寄存器和任务的入口首地址,在任务切换时,保存CPU寄存器和程序入口,注意这里由于这是人造的堆栈所以你必须提供入口,这个入口就是取得函数的入口地址,这是栈,那么进程控制块主要是保存一些与任务密切相关的数据,比如本任务的堆栈在哪里,本任务的状态,本任务在就绪表中的坐标等参数,加速任务切换等,
那么堆栈是怎样初始化的呢或者说初始化之后的结果是多少呢?结构是什么样的?
其实堆栈就是一个数组,这个数组创建的时候内部数据全部清0,那么运行对战初始化后堆栈变成了什么样子?就那空闲任务来做例子吧
空闲任务他什么也不做,只是傻傻对一个32位的变量进行++,操作,他的优先级最低,也就是任何一个任务就绪了就可以抢占他,他只是在
操作系统没有就绪的任务时运行,但他确实是一个任务,因此他拥有所有任务的特性。又因为他简单所以比较好分析。
首先创建一个堆栈:
static  OS_STK DT_XDATA OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE]; 
这就是创建的那个空闲任务的堆栈,创建空闲任务时调用OSTaskStkInit来初始化这堆栈代码如下:
OS_STK DT_XDATA *stk;
    ppdata = ppdata;       
    opt    = opt;                               


     stk    = (OS_STK DT_XDATA *)ptos;          
    *stk++ = (0xFF + 1);                 
     *stk++ = 2 + 13;       
    *stk++ = (INT16U)task & 0xFF;         

    *stk++ = (INT16U)task >> 8;               
    *stk++ = 0x0A;                              
    *stk++ = 0x0B;                             
    *stk++ = 0xD1;                             
    *stk++ = 0xD0;                             
    *stk++ = 0x00;                              
    *stk++ = 0x00;                              
    *stk++ = 0x01;                           
    *stk++ = 0x02;                            
    *stk++ = 0x03;                              
    *stk++ = 0x04;                              
    *stk++ = 0x05;                              
    *stk++ = 0x06;                             
    *stk++ = 0x07;                             
                                                
    return ((void DT_XDATA *)ptos);    


STK是一个指向堆栈首地址的指针,用它修改堆栈的值,最后执行完堆栈的值如下
OSTaskIdleStk【0】=0
OSTaskIdleStk【1】=15
OSTaskIdleStk【2】=任务入口函数地址高八位
OSTaskIdleStk【3】=任务入口函数地址低八位
OSTaskIdleStk【4】=ACC=10
OSTaskIdleStk【5】=B=11
OSTaskIdleStk【6】=DPH=0XD1
OSTaskIdleStk【7】=DPL=0XD0
OSTaskIdleStk【8】=PSW=0
OSTaskIdleStk【9】=R0=0
OSTaskIdleStk【10】=R1=1
OSTaskIdleStk【11】=R2=2
OSTaskIdleStk【12】=R3=3
OSTaskIdleStk【13】=R4=4
OSTaskIdleStk【14】=R5=5
OSTaskIdleStk【15】=R6=6
OSTaskIdleStk【16】=R7=7
表示每个字节代表的存入的寄存器名字,他的堆栈是由下向上生长的!
然后函数返回一个堆栈的首地址,至此堆栈的初始化就完成了
接下来是任务控制块(TCB)
任务控制块到底在哪里呢?在这里看下面的定义
static  OS_TCB DT_XDATA OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS];
这就是书上所谓的TCB池,书总是爱故弄玄虚,你妈逼的不就是个数组吗?瞎比比什么!记住所有的一切的操作的核心就是对这个数组的操作
他就是TCB,而且作者把他开辟为一块静态的内存区,不被扰动的,因为他很重要,
什么是空TCB呢?他在程序中的样子是这样的
OS_EXT  OS_TCB DT_XDATA * DT_XDATA OSTCBFreeList;
不难看出,他就是个结构指针,但是一个指针怎么和空表联系起来?原来他里面的值存着尚未用的OSTCBTbl【】,也就是说,当有任务要求占一个TCB时,首先要通过这个空表指针得到,还要看看这个表示不是用完了,获得了这个空闲的表的地址后,还要更新OSTCBFreeList,让他指向下一个没有使用的空的TCB表,这也就是他的作用了
还有一个优先级和TCB对应的指针数组,为什么要做这个数组呢?这个数组存着什么?先看定义
OS_EXT  OS_TCB DT_XDATA * DT_XDATA OSTCBPrioTbl[OS_LOWEST_PRIO + 1];
这就是那个指针数组,为什么要这个数组现在我还不知道,但是有一点可以看出来,他可以快速的通过任务对应香型的TCB,也就是说
知道了任务的优先级我就知道这任务的TCB在哪里,和目录一样,它里面存的全部是任务的TCB首地址,
还有一个指针这个指针叫做
OS_EXT  OS_TCB DT_XDATA * DT_XDATA OSTCBList; 
他是做什么的呢?他用来存一个地址,这个地址如果是第一次分配这个TCB表,那么他的值是0,第二次就是第一次的地址,依次向下,他的值
给了链表指针里的下一个表的指针,可见它是用来更新链表的!我感觉他只是个中间量而已,角色并不是很重要。
哈哈,定义不高明白,是看不进去的,因为他老是跳来跳去,而且有数组,有指针,还有指针数组,
搞明白定义家简单了,初始化大致分为如下几部:
取得空表,
占用空表
空表指针下移
TCB初始化,
优先级和TCB目录写入
加载链表的下个和上个TCB块
结束
主要还是对这四个的定义的理解,其他的都是小事,水到渠则成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值