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

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

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

未优化汇编代码

//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		进行与运算

优化汇编代码

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

问题就在 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		//进行与运算

你可能感兴趣的:(MCU,arm开发,stm32)