本文主要是介绍Stk stk = ptos; //将传递过来的堆栈指针值赋值给STKOSTaskStkInit,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
UC/OS-II中OSTaskStkInit()移植详解(基于Cortex-M3)
OSTaskStkInit()在Cortex-M3中主要功能为初始化任务的栈的桔构,使任务的栈看起来就好像刚发生了一个中断一样的结构,这些UC/OS的作者都有说到.现在我们须要了解的是Cortex-M3在发生中断时,它的堆栈结构.在我们之前有提它中断时的压栈过程为xPSR–>PC–>LR–>R12–>R3-R0(详情点这里:Cortex-M3中断时,自动压栈的顺序),推断出中断后的任务堆栈应该为下图: 所以OSTaskStkInit()的作用就是将传递过来的参数(其中包含了堆栈地址与任务入口地址等) 标准的OSTaskStkInit()的原型为: OS_STK *OSTaskStkInit(void (*task)(void *pd),void *pdata,OS_STK *ptos,INT16U opt); ptos是传入是堆栈的初始值,task则是任务PC的起始地址指针.opt则是操作数,一般的任务都没用上. 所以我们最主要的任务就是把ptos,task按中断的方式压入堆栈中,堆栈的地址由ptos给出,然后再把新的堆栈的值传回去.方法: opt=opt; //未使用,防止编译器警告 OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) { OS_STK *stk; //定义一个指针变量,用来对堆栈的操作 stk = ptos; //将传递过来的堆栈指针值赋值给STK *(stk) = (INT32U)0×01000000L; //首先压入的是xPSR *(–stk) = (INT32U)task; //然后自减一后把任务的入口地址压入 *(–stk) = (INT32U)0xFFFFFFFEL; //接下来压入LR,由于CORTEX-M3的LR在中断时是非常特殊值,所以这经的值须要根据实际情况去确定,比如在任务模式下使用PSP那么就得把LR的值设定为FFFFFFFE *(–stk) = (INT32U)0×12121212L; /* R12 */ *(–stk) = (INT32U)0×03030303L; /* R3 */ *(–stk) = (INT32U)0×02020202L; /* R2 */ *(–stk) = (INT32U)0×01010101L; /* R1 */ *(–stk) = (INT32U)parg; /* R0 : ar 输入参数 */ /* Remaining registers saved on*/ /* process stack */ /* 剩下的寄存器保存到堆栈 */ *(–stk) = (INT32U)0×11111111L; /* R11 */ *(–stk) = (INT32U)0×10101010L; /* R10 */ *(–stk) = (INT32U)0×09090909L; /* R9 */ *(–stk) = (INT32U)0×08080808L; /* R8 */ *(–stk) = (INT32U)0×07070707L; /* R7 */ *(–stk) = (INT32U)0×06060606L; /* R6 */ *(–stk) = (INT32U)0×05050505L; /* R5 */ *(–stk) = (INT32U)0×04040404L; /* R4 */ return(stk); //最后,返回新的堆栈的值. } 至此,OSTaskStkInit就算移植完成,当然他具体的目的与作用,还是去看看UC/OS的作者说明是最全面的. |
这篇关于Stk stk = ptos; //将传递过来的堆栈指针值赋值给STKOSTaskStkInit的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!