GD32的FPU读取结构体内的float的读取与写入错误问题

记录一下这个bug,让后人避免这个bug。

这个bug复现很简单

首先需要一个开了o1优化的keil

然后需要一个绝对对不齐的结构体,并使用pack(1)

如果对齐了就无法触发了

然后你需要一个直接读取到fpu中的指令

你就需要一个形如这样的代码

    float *fVoltage_line = &(sAdSample_GetL2BusVolt()->stAdcData.fRealValue);
	float voltage= *fVoltage_line;

 然后这段代码就会生成一段

0x080168C4 ED900A00  VLDR          s0,[r0,#0x00]

就类似于这样

到这里,恭喜你,发现了一个稳定触发fpu的hardfault的方式

当然需要注意以下几点:

如果你么欸有代码优化或者先读到了r1里,那么就不会触发这个bug

或者你手动对齐了位置,比如添加了一个uint8_t 类似于这样:

那么就不会触发这个bug

添加最简短的稳定触发代码··············································

#include "gd32f30x.h"                   // Device header
#pragma pack(1)
typedef struct
{
		uint8_t u8LostZero;  // ?????
//		uint8_t u8LostZerogroup[1];  // ?????
    uint32_t Cnt; // ???
	  uint16_t u16RealVal; // ?????

	
	  float fRms;          // ???
    float fFreq;  // ????????

    float fRealValue;    // ?????

    float fSquareSum;    // ???

} ADCCALC_AC;
#pragma pack()
ADCCALC_AC tRtADC[4];
float *p;
float ftest;
int main(void){
	p=&(tRtADC[1].fRealValue);
	float voltage =*p;
	ftest=voltage*12;
	while(1);
//	return 0;
}

至于解决方案,,还是得等厂商修复。

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值