?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指针将始终指向当前任务的堆栈顶端。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章