arm cortex硬件出栈PC,会将出栈的PC值自动加1?
1.1 问题来源发现freertos第一次代码模拟压栈,放入PC的函数指针,最低位必须是0. 1.2 问题资料说: 手动写pc,必须把最低位设1,告诉mcu此时是thumb状态。 但freertos的代码把最低位强行变0了。 这不是矛盾吗?1.3 我的猜测资料说读PC,值最低位总是0,所以代码里面模拟硬件压栈,PC的bit要求为0,因为PC肯定是硬件读出来放到栈里面,只要读PC的bit必须为0.硬件自动出栈给pc的时候,自动给出栈给pc的值加1?1.4 freerots源码StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ){ /* Simulate the stack frame as it would be created by a context switch interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & 0xfffffffeUL; /* PC */ 不理解此处为什么要把bit0变为0 pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack;}
我找了半天也不知道“资料说: 手动写pc,必须把最低位设1,告诉mcu此时是thumb状态。”这个资料的来源,能否出示资料来源? 我记得切换ARM Thumb状态的是cpsr(xPSR portINITIAL_XPSR bit24 为1)寄存器T位决定的。 *pxTopOfStack = ( ( StackType_t ) pxCode ) & 0xfffffffeUL; 此处这么操作不能单一理解未想要把bit0变为0,如果是thumb状态,则是16位,如果是arm32 状态则为32位,所以这里bit0是想要半字对齐或字对齐(如果使用的是cortex-m,则只有thumb-2指令集,半字节对齐)。不知道这样解释对不对。 这个在使用分支或者内存读取指令来更新PC的时候才需要强制PC的BIT0 = 1,否则会触发硬件异常,其它不用。
另外对于T标志,CM内核永远是1
本帖最后由 snakeemail 于 2021-1-5 12:09 编辑
@李益达 我用的是cortex,所以直接写PC,最低位一定要是1。 资料是看的 ARM cortex-M3 权威指南。见下图。
@eric2013 太对了。最后我的看法就是,只要是代码写PC(不论是pop, ldr),一定要求LSB一定为1,表示branch后为thumb状态。 而当MCU硬件自动出栈,把栈里面的值给PC,那就不属于代码写的,这个时候又需要强制最低位为0. 但这个地方真的是很拧巴。
我看ucos这一块没有干任何事情,直接把函数指针放到栈里面。以前的freertos代码也是这样,到了9.0加上的,估计要看看github的记录才行。
页:
[1]