本帖最后由 victor3l 于 2013-8-11 10:06 编辑
运行原子的UCOSII移植教程,在主函数中创建完任务后调用OSStart()来启动。
void OSStart (void)
{
if (OSRunning == OS_FALSE) {
OS_SchedNew(); /* Find highest priority's task priority number */
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy(); /* Execute target specific code to start task */
}
}
该函数的最后一句是调用了一段汇编代码:
OSStartHighRdy
LDR R4, =NVIC_SYSPRI2 ; set the PendSV exception priority
LDR R5, =NVIC_PENDSV_PRI
STR R5, [R4]
MOV R4, #0 ; set the PSP to 0 for initial context switch call
MSR PSP, R4
LDR R4, =OSRunning ; OSRunning = TRUE
MOV R5, #1
STRB R5, [R4]
;切换到最高优先级的任务
LDR R4, =NVIC_INT_CTRL ;rigger the PendSV exception (causes context switch)
LDR R5, =NVIC_PENDSVSET
STR R5, [R4]
CPSIE I ;enable interrupts at processor level
OSStartHang
B OSStartHang ;should never get here
单步调试时,总是停在
OSStartHang
B OSStartHang ;should never get here
请问:如果停在这里了,哪些已经创建的任务怎么才能执行,代码就没有走到那些函数内?
当我看野火的教程时,这段汇编是没有最后这2句。这最后2句就是让程序停在这里的,为什么会有这两句了?
但是下载到板子上有没有问题。当我注释掉上面2句后,编译出现警告,
..\UCOSII\PORT\os_cpu_a.asm(204): warning: A1581W: Added 2 bytes of padding at address 0x8e
错误指向:
PendSV_Handler_Nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook(); 这里是调用该钩子函数
BLX R0
POP {R14} ;恢复r14
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; 实际就是设置当前优先级位最高优先级就绪任务的优先级。
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0] ;这里把R2中的内容放到R0中
LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy; 设置当前任务控制块指针
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr; 为什么说R0为新的SP。
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20
MSR PSP, R0 ; Load PSP with new process SP;PSP为进程堆栈指针。
ORR LR, LR, #0x04 ; Ensure exception return uses process stack ;确保LR的第2位为1,
CPSIE I ;开中断
BX LR ; Exception return will restore remaining context 返回
end
该段的最后。再进行单步调试,程序会在
__asm void WFI_SET(void)
{
WFI;
}
//关闭所有中断
__asm void INTX_DISABLE(void)
{
CPSID I;
}
//开启所有中断
__asm void INTX_ENABLE(void)
{
CPSIE I;
}
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
以上4个函数间来回走动。
请问这是为什么?谢谢
|