OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4445|回复: 15

RTOS r14 LR寄存器是否压栈

[复制链接]

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
发表于 2020-5-8 15:43:22 | 显示全部楼层 |阅读模式
就是想请问一下,为什么FreeRtos的汇编代码中有对 r14寄存器的 压栈出栈。
但是RT-thread的汇编代码中,没有对r14 寄存器的压栈出栈。这样不会出BUG吗?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
743
金钱
743
注册时间
2018-9-1
在线时间
177 小时
发表于 2020-5-8 17:43:55 | 显示全部楼层
本帖最后由 ultraelec 于 2020-5-8 18:10 编辑

先回答你的问题:
1、栈帧(其中包含了r14即lr)会由硬件自动入栈/出栈。
但不同于普通函数,对于异常来说,异常不使用lr返回,
并且进入异常r14就会自动被覆盖新的值,用于处理异常返回机制。

2、你提的FreeRTOS会出栈r14:本质上是在出异常前将任务栈中的一个值覆盖掉寄存器中的r14,也就是修改r14的值
然后执行bx 14,由命令手动触发返回机制而非自动异常返回机制,效果就是出异常后使用进程栈。

3、刚才看了一眼rtt的port部分代码,它也同样是修改了r14,手段并不是用“出栈覆盖”,而是直接修改r14的值:将lr的bit2 置1
ORR     lr, lr, #0x04
BX      lr
效果同FreeRTOS  。
uevip#126.com
回复 支持 1 反对 0

使用道具 举报

4

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
743
金钱
743
注册时间
2018-9-1
在线时间
177 小时
发表于 2020-5-8 21:40:46 | 显示全部楼层
ky475477428 发表于 2020-5-8 20:07
懂了,威武~ 还有就是 我看到了 LR居然有时候跳转时 FFFFFFED的数值。。 按理说 最高28bit应该全F才是, ...

两个数,高28位都为1,没问题,你算错了吧
ED 和 FD你看手册,区别在于是否使用了FPU
不论FreeRTOS和RTT,都是正常的,你自己不要改内核。
uevip#126.com
回复 支持 反对

使用道具 举报

0

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2016-1-5
在线时间
1 小时
发表于 2020-5-8 15:43:22 | 显示全部楼层
帮顶,原子哥,来溜一下。。。
回复 支持 反对

使用道具 举报

0

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2018-12-27
在线时间
0 小时
发表于 2020-5-8 16:02:39 | 显示全部楼层
原子哥,有人提问了,快来,快来。。。
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-8 16:05:53 | 显示全部楼层
.....什么情况。。  其实就是我调试的时候,发现r14不压栈的话,最高栈顶地址那     会反向有内存溢出或者踩内存现象。。不正常  加了r14以后就OK了
回复 支持 反对

使用道具 举报

11

主题

1041

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3696
金钱
3696
注册时间
2011-5-23
在线时间
2008 小时
发表于 2020-5-8 16:05:56 | 显示全部楼层
LR是子函数执行完毕后的返回地址,肯定是要保存的哈。
不过 cortex-M 在进入中断时,LR有被自动压入栈中,所以不必再写代码再压了。
不知道楼主具体是看的哪段代码产生的疑问?
RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-8 16:15:04 | 显示全部楼层
aozima 发表于 2020-5-8 16:05
LR是子函数执行完毕后的返回地址,肯定是要保存的哈。
不过 cortex-M 在进入中断时,LR有被自动压入栈中, ...

mrs r0, psp;读取进程栈指针,保存在R0里
        isb;指令同步屏障
        /* 获取当前的任务控制块. */
        ldr        r3, =g_CurThreadPtr;获取pCurrentTCB指针的存储地址,这个指针永远指向正在运行的任务。
        ldr        r2, [r3];取R3所保存的地址处的值赋值给R2,即获取到了当前任务的存储地址

        /* 判断任务是否使用了FPU,如果使用了FPU的话,进行任务切换的时候就需要将FPU的S16-31寄存器保存在任务堆栈中,S0-15自动保存的 */
        tst r14, #0x10
        it eq
        vstmdbeq r0!, {s16-s31}

        /* 保存核心寄存器. */
        stmdb r0!, {r4-r11,r14}

        str r0, [r2] ;寄存器R0的值写入到寄存器R2所保存的地址中去,即将新的栈顶保存在任务控制块的第一个字段中。
        /* Cortex中断默认情况下有一个数值为0的优先级。大多数情况下0代表最高级优先级。绝对不可以在优先级为0的中断服务例程中调用RTOS API函数*/
        stmdb sp!, {r0, r3};寄存器R3的值临时压栈,寄存器R3中保存了当前任务的控制块,接下来要操作任务上下文切换,为了防止R3被改写,所以临时先压栈
        mov r0, #0x20;
        msr basepri, r0;关中断
        dsb;数据同步屏障
        isb;指令同步屏障
        bl OEOS_SwitchContext;该函数来获取下一个要运行的任务
        mov r0, #0
        msr basepri, r0;开中断
        ldmia sp!, {r0, r3};r3出栈,恢复寄存器R3的值。note:此时r3所保存的地址处数据改变,已经变成了下一个要运行任务的任务控制块

        ldr r1, [r3]
        ldr r0, [r1];获取新的要运行任务的任务堆栈栈顶,并将栈顶保存在寄存器R0中。

        /* Pop the core registers. r0-r3等其它的寄存器,内核会自动pop*/
        ldmia r0!, {r4-r11,r14};运行的任务的现场

        /* 是否支持FPU,支持就手动恢复S16-31 */
        tst r14, #0x10
        it eq
        vldmiaeq r0!, {s16-s31}

        msr psp, r0;更新进程栈指针PSP的值
        isb;指令同步屏障

        bx r14;函数返回,bx为间接跳转指令,即跳转到存放在r14中的地址处,R14寄存器也叫链接寄存(LR)。
   
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-8 16:16:06 | 显示全部楼层
如上代码,都对r14做了压栈处理。但是再stackinit里,确实写了一个INITIAL_EXC_RETURN的值(0xfffffffd)给R14。
回复 支持 反对

使用道具 举报

11

主题

1041

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3696
金钱
3696
注册时间
2011-5-23
在线时间
2008 小时
发表于 2020-5-8 17:12:07 | 显示全部楼层
进入中断前,硬件有自动压LR。
TIM截图20200508171121.png

RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-8 17:12:59 | 显示全部楼层
发现了更奇怪的问题: LR寄存器在pendsv中断中 居然有 FFFF FFED的数值。。没有手册说过这个问题。Exc_return值 手册上说过  高28bit是全1啊。。太奇葩了。
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-8 17:20:09 | 显示全部楼层
aozima 发表于 2020-5-8 17:12
进入中断前,硬件有自动压LR。

我知道会压呢,但是很奇怪的是,压入了FFFFFFED这个数值。。不知道为什么
回复 支持 反对

使用道具 举报

4

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
743
金钱
743
注册时间
2018-9-1
在线时间
177 小时
发表于 2020-5-8 17:51:08 | 显示全部楼层
本帖最后由 ultraelec 于 2020-5-8 18:01 编辑
ultraelec 发表于 2020-5-8 17:43
先回答你的问题:
1、栈帧(其中包含了r14即lr)会由硬件自动入栈/出栈。
但不同于普通函数,对于异常来 ...

补充一下:
“因为异常不使用lr返回” 我这针对的是返回地址:异常不用lr保存返回地址,在异常中使用它触发异常返回机制。
uevip#126.com
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-8 20:07:50 | 显示全部楼层
ultraelec 发表于 2020-5-8 17:43
先回答你的问题:
1、栈帧(其中包含了r14即lr)会由硬件自动入栈/出栈。
但不同于普通函数,对于异常来 ...

懂了,威武~ 还有就是 我看到了 LR居然有时候跳转时 FFFFFFED的数值。。 按理说 最高28bit应该全F才是,所以没整明白内核那套机制。。有时候ED结尾,有时候FD结尾。而且某些时候ED结尾还会导致异常(比如内存泄漏)。。
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-9 08:50:05 | 显示全部楼层
问题解决,大佬们解释得很对。还有就是CortexM3 M4因为有FPU差异,所以 cortex M4    LR寄存器得第5bit会有位域定义哦。  我前面只看了M3的内核指南,所以没搞定这个原因。本问题OVER,谢谢各位。~~~
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2015-11-26
在线时间
31 小时
 楼主| 发表于 2020-5-9 08:51:33 | 显示全部楼层
忘记改成悬赏贴了,@ultraelec  感谢大佬。我这边问题解决了。多谢回答~。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 22:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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