一、目的
一般来说ARM的IDE/调试器不提供UCOSII多任务任务调用函数调用关系的查询,本文旨在提供一种查看UCOSII任务调用堆栈的方法。
二、UCOSII任务切换简介
UCOSII任务切换方式有两种,一种是通过触发软中断来切换,另一种是直接跳转(分中断里跳转和任务执行中跳转)。无论怎样切换,都是把当前执行的任务内容压入当前任务的堆栈中去,然后设置任务SP的值为优先级最高的任务的堆栈,然后出栈恢复寄存器为最高优先级的任务挂起前的值,亦即还原任务状态,让最高优先级的任务跑下去。而保存任务挂起前的寄存器的值的堆栈,就是我们跟踪任务的调用关系的工具。
无论哪种方式的切换,最终都是要切换到要执行的任务,亦即把要执行的任务的堆栈出栈,这样,我们可以获知寄存器在任务堆栈里的位置,我们看切换最后面的一点代码就可以获知。例如,我们可以从下面代码获知,挂起任务堆栈里的顺序是:
CPSR,R0,R1...R12,LR,PC。
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
; Pop new task's context.
LDMFD SP!, {R0-R12, LR}
LDMFD SP!, {PC}^
UCOSII的任务堆栈保存在每个任务控制块里面,如下所示,其成员OSTCBStkPtr就是任务堆栈指针: