问题排查:编译器优化导致读写寄存器操作异常,从而导致core挂死

news/2024/10/7 19:25:32 标签: RISC-V, 嵌入式开发

1、访问寄存器的操作(以32位机器分析)

在这里插入图片描述

  • 嵌入式开发时,经常需要访问寄存器,有时候只需要得到寄存器的部分bit位,会将寄存器的值读出来再进行移位操作,从而解析出特定的bit位
  • 上面的C代码,想要读取出某个寄存器的高16bit,从C代码层面看是没有问题的,但是实际运行时可能会出错,这取决于使用的编译器优化等级。编译器不优化执行不会出错,编译器优化就可能出错

2、编译器优化:使用-Os优化等级

在这里插入图片描述

  • 使用-Os优化等级编译代码,程序运行时会导致core挂死,原因如下:
    • 使用-Os优化等级编译代码,编译器判断本次读寄存器只需要使用16bit,刚好是short变量(2字节),可以优化
    • 原来:从0x80026000地址处读取4B,再右移16bit得到高16bit
    • 优化后:直接从0x80026002地址处读取2B(直接读取寄存器的高2B)
  • lh a1 2(a5):
    • 此时a5的值是0x80026000
    • 本条汇编的作用:从0x80026000开始偏移2字节地址处(0x80026002),读取2B存放到a1
  • 出错原因:
    • 寄存器必须4B整体读写(0x80026000开始读取4B),不支持只访问寄存器的2B(0x80026002开始读取2B),导致读操作返回异常(加载访问异常)或者没有返回
    • 如果0x80026000地址是sram,这样的优化是没有问题的,能节省指令条数,提高性能

3、解决办法

在这里插入图片描述

  • 使用内嵌汇编,将读寄存器的操作强制指定用lw指令,不让编译器优化成lh
  • 将读寄存器的内嵌汇编封装成内联函数RegRead
  • 内嵌汇编可以参考博客:《RISC-V架构学习——C语言内嵌汇编总结》

http://www.niftyadmin.cn/n/5693265.html

相关文章

【计算机网络】面试必问TCP十大机制

1. TCP协议的报文格式 说明: TCP 报文格式主要分为两部分:TCP 报文头部和数据部分。以下是对各字段的详细解释: TCP 报文头部 源/目的端口:各占用16位。表示数据从哪个进程发送,发送到哪个进程去。序号字段&#xff1a…

前端知识汇总(持续更新)

见:GitHub - eHackyd/Front-End: 前端知识汇总 包含:html,css,js,ts等等(语法使用实例)

Linux更改固定IP地址

1.VMware里更改虚拟网络 一: 二: 三:确定就好了 2.修改Linux系统的固定IP 一:进入此文件 效果如下: 执行以下命令: 此时IP已更改 3.远程连接 这个是前提!!! 更改网络编辑器后网络适配器可能会修改,我就是遇着这个,困住我了一会 一:可以以主机IP对应连接 连接成功 二:主机名连…

df命令输出的详细解释

理解 df -h 命令的输出对于有效管理和监控 Ubuntu 系统的磁盘空间至关重要。df(Disk Free)命令用于显示文件系统的磁盘空间使用情况,而 -h 选项使输出以“人类可读”的格式(如 GB、MB)显示,便于理解。 示例…

阿里巴巴_java开发规范手册详解

1、 命名风格 1.1、开始结尾规范 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。 反例: _name, $name, __name 1.2、严禁使用拼音与英文混合及中文的方式 代码中的命名严禁使用拼音与英文混合的方式,更不允许…

水上基础设施检测系统源码分享

水上基础设施检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

HCIE《网络括谱图》

企业园区网 终端>接入>汇聚>核心>出口区(防火墙)>互联网

【java】数据类型与变量以及操作符

各位看官:如果您觉得这篇文章对您有帮助的话 欢迎您分享给更多人哦 感谢大家的点赞收藏评论,感谢您的支持!!! 目录 一.字面变量: 二:数据类型 1.1:int类型:&#xff0…
最新文章