在线时间21 小时
UID2036529
注册时间2013-8-26
NXP金币0
该用户从未签到
中级会员
 
- 积分
- 217
- 最后登录
- 1970-1-1
|

楼主 |
发表于 2013-9-3 20:43:32
|
显示全部楼层
RE:【飞思卡尔“新”礼三重奏】 jasonwangse的方案
3.任务调度时现场的保存
由于我们的设计将OS的任务运行在Thread mode,异常和中断运行在Handler mode,Thread mode使用PSP作为栈指针,Handler mode使用MSP作为栈指针,所以在uC/OS II中OS_TCB的OSTCBStkPtr应为任务切换时PSP的值。
需要注意的一点就是M0+在进入异常时,现场保护的工作是由硬件来完成的,手册中也给出了PushStack的伪代码,同样异常返回时的现场恢复工作也是由硬件来完成的
PushStack()
if CONTROL.SPSEL == '1' && CurrentMode == Mode_Thread then
frameptralign = SP_process;
SP_process = (SP_process - 0x20) AND
NOT(ZeroExtend('100',32));
frameptr = SP_process;
else
frameptralign = SP_main;
SP_main = (SP_main - 0x20) AND NOT(ZeroExtend('100',32));
frameptr = SP_main;
MemA[frameptr,4] = R[0];
MemA[frameptr+0x4,4] = R[1];
MemA[frameptr+0x8,4] = R[2];
MemA[frameptr+0xC,4] = R[3];
MemA[frameptr+0x10,4] = R[12];
MemA[frameptr+0x14,4] = LR;
MemA[frameptr+0x18,4] = ReturnAddress();
MemA[frameptr+0x1C,4] = (xPSR:frameptralign:xPSR);
所以我们在做任务切换时,除了需要将其余寄存器的值恢复到要切换的那个任务的现场外,还需要将任务切换前硬件保存的现场做相应的修改。即PSP堆栈中R0~R3,R12,LR都需要恢复成要切换的那个任务的现场,也就是说要在PendSV异常退出前,将Thread mode堆栈中存储的这些寄存器的值都替换为要切换的那个任务。
不过有一点还没考虑好,就是中断中的任务切换是直接调用切换程序去处理呢,还是也和任务中一样,通过触发PendSV异常来处理呢?我再分析分析。。。 |
|