?C_XBP解析

前些时候在研究uc/os-II在keil c中移植的时候,对C_XBP指针的使用方式总是不太清楚,只模糊感觉到其是指向当前任务的栈空间顶部的,但引起初始化的时候是指向RAM空间的最顶端加1的位置,这就让我迷糊了。我不知道C_XBP一开始指向那个位置有什么用处,也不清楚何时C_XBP开始指向当前任务的栈空间顶部的。因此花了一些时间去研究其初始化到OS运行的过程中C_XBP的变化。

首先在startup.a51中找到如下语句:
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
从前面的定义知道XBPSTACK定义为1,因此此处将首先对C_XBP进行赋值。因C_XBP定义为两字节的专用指针,因此在汇编中需要对C_XBP+1也赋值(因为在C编程中看来,地址为C_XBP+1的RAM其实是指针C_XBP的一部分,保存此指针的低8位)。从前面定义的XBPSTACKTOP可以知道,此处执行完后,{C_XBP}=0x80,{C_XBP+1}=0x00,即在C编程中看来,此时指针C_XBP是指向存储地址为0x8000的地方。初始化完成后进入main()函数。

然后来跟踪分析main()函数的执行情况。进入main()函数后,真正开始OS的语句是OSInit(),因此进入查看此函数的执行过程。在OSInit()函数中可以看到,前面都部分全部都是对任务控制块TCB等全局变量的初始化,并没有牵涉到指针C_XBP。在此初始化后,OSInit()函数会创建两个任务(一个是空闲任务,一个是统计任务,当然此处假设其使能是打开的),因此需要进去OSTaskCreate()函数中去查找了,在此函数中看到了OSSched(),哦耶,立马就清楚了。因为在以前的学习中知道,正是在OSSched()函数中调用宏定义OS_TASK_SW()(其实就是通过此宏定义来调用OSCtxSw(),此函数是移植中最重点的函数)来进行任务切换的,而对C_XBP的操作也是此初最先开始的。通过分析可知,在第一次进行任务切换时,OS首先将公共堆栈里的内容(从#stack到sp之间的内容)拷贝到C_XBP指针指向的地址下面的RAM空间,即此处相当于将公共堆栈里的内容拷贝到RAM空间的最高地址部分空间内(因为到目前为止C_XBP指针仍然是初始化时候的值,这其实是考虑到此处的RAM空间是最不可能被用到的,因此保存在此处比较安全,当然也是有被破坏的可能的),接着将C_XBP指向刚保存的数据的RAM底端位置。然后调用C_OSCtxSw()函数进入C编程环境中进行操作。

进入C_OSCtxSw()函数后首先执行的就是将C_XBP指针的值赋给OSTCBCur->OSTCBStkPtr。但从初始化过程来看,此处可能会存在问题,因为此时OSTCBCur指针指向的是0地址,即相当于是空指针,同样OSTCBStkPtr指针指向的也是0地址,我不知道此时给空指针赋值是什么用意,但我觉得稳妥的做法是应该在此处判断一下指针是否为空再进行赋值。另外一点疑惑就是,既然将C_XBP指针赋值给空指针,即代表其值将永远丢失,那为什么还要在前面保存相应的数值,那些可是永远也不会用到了啊(当然其实创建任务后确实也不需要再用到了)。

接下来就是将OSTCBCur指针指向最高优先级任务的任务控制块,同时C_XBP指针指向当前任务的堆栈顶端,然后就是调用LoadCtx()切换到当前任务中执行去了。在以后的任务切换过程中,C_XBP指针将始终指向当前任务的堆栈顶端。

至此,C_XBP指针的使用过程全部弄清楚了。这个过程虽然有点枯燥,但当缠在一起的结被解开的瞬间,感觉还是非常HIGH的,呵呵。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值