• 编译器使用优化后出现的busfault


    遇到的问题:
    未开优化是正常执行,打开优化,无法运行,定位到异常语句

    //ADC_REG 是ADC结果寄存器地址
    uint32 adc = *(uint32 *)ADC_REG;
    uint32 temp = adc&0xffff;
    
    • 1
    • 2
    • 3

    未优化汇编代码

    //uint32 adc = *(uint32*)ADC_REG;
    MOVW	 	R8 ,	#0X0824					//加载高16位地址
    MOVT		R8 ,	#4090					//加载低16位地址
    LDR.W		R0,		[R8]					//读取32位数据
    //uint32 temp = adc&0xffff;
    UBFX 		R2 , 	R0,		#0,		#16		进行与运算
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    优化汇编代码

    //uint32 adc = *(uint32 *)ADC_REG;
    //uint32 temp = adc&0xffff;
    MOVW	 	R8 ,	#0X0824					//加载高16位地址
    MOVT		R8 ,	#4090					//加载低16位地址
    LDRH		R0,		[R8]					//半字节数据读取数据到R0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题就在 LDRH指令;由于通用寄存器读取外设寄存器需要按照32位读取,并且需要使用的数据刚好就是半字,编译器优化后就使用LDRH指令进行半字读取,从功能上是等效的,但是由于内核寄存器对外设寄寄存器需要使用32位读取即LDR.W指令,编译器优化使用16位读取即LDRH,故此出现 busfault 。解决办法,即在读取时添加volatile,不使用用编译器优化。

    volatile优化汇编代码

    //uint32 adc = *(volatile uint32*)ADC_REG;
    MOVW	 	R8 ,	#0X0824					//加载高16位地址
    MOVT		R8 ,	#4090					//加载低16位地址
    LDR.W		R0,		[R8]					//读取32位数据
    UBFX 		R0, 	R0,		#0,		#16		//进行与运算
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    性能测试过程
    会议OA项目(待开会议&历史会议&所有会议)
    界面重建——Marching cubes算法
    LLM实现RPA
    【Docker】Docker-compose及Consul多容器编排工具
    docker在虚拟机中的应用
    记一次生产慢sql索引优化及思考
    群晖 NAS 外网访问设置 - 腾讯 DNSPod
    十三、队列的特性
    HTTP与HTTPS
  • 原文地址:https://blog.csdn.net/lyq308152569/article/details/134288024