硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3206|回复: 3
收起左侧

[FreeRTOS] arm cortex硬件出栈PC,会将出栈的PC值自动加1?

[复制链接]

41

主题

215

回帖

338

积分

高级会员

积分
338
发表于 2021-1-4 14:39:10 | 显示全部楼层 |阅读模式

1.1 问题来源
发现freertos第一次代码模拟压栈,放入PC的函数指针,最低位必须是0.   
1.2 问题
资料说: 手动写pc,必须把最低位设1,告诉mcu此时是thumb状态。
但freertos的代码把最低位强行变0了。 这不是矛盾吗?
1.3 我的猜测
资料说读PC,值最低位总是0,所以代码里面模拟硬件压栈,PC的bit[0]要求为0,因为PC肯定是硬件读出来放到栈里面,只要读PC的bit[0]必须为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;
}




回复

使用道具 举报

8

主题

104

回帖

138

积分

初级会员

积分
138
发表于 2021-1-4 16:55:20 | 显示全部楼层
我找了半天也不知道“资料说: 手动写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指令集,半字节对齐)。不知道这样解释对不对。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2021-1-4 17:51:32 | 显示全部楼层
这个在使用分支或者内存读取指令来更新PC的时候才需要强制PC的BIT0 = 1,否则会触发硬件异常,其它不用。 QQ截图20210104175144.png

另外对于T标志,CM内核永远是1
666.png

回复

使用道具 举报

41

主题

215

回帖

338

积分

高级会员

积分
338
 楼主| 发表于 2021-1-5 11:42:57 | 显示全部楼层
本帖最后由 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的记录才行。 屏幕截图 2021-01-05 111927.png






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-1 16:55 , Processed in 0.161987 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表