硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2502|回复: 13
收起左侧

[FPU] STM32H7 Float问题

  [复制链接]

7

主题

7

回帖

28

积分

新手上路

积分
28
发表于 2021-8-25 13:51:55 | 显示全部楼层 |阅读模式
uint8_t UserRxBufferHS[100];
uint32_t Data2;
float_t Data;
Data=*(float_t*)&UserRxBufferHS[0];
Data2=*(uint32_t *)&UserRxBufferHS[4];

这赋值,float_t直接进入硬件错误,uint32_t 正确,而且float在STM32F103系列芯片中这种方式赋值是正确的,请教一下是什么原因呢

回复

使用道具 举报

335

主题

2037

回帖

3047

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3047
发表于 2021-8-25 14:36:29 | 显示全部楼层
本帖最后由 caicaptain2 于 2021-8-25 14:40 编辑

因为uint8不能用指针转换成浮点。 arm里面的浮点数需要地址对齐,而uint8的数据不是地址对齐的。可以用一个联合体来解决这个问题。
typedef union {
    float ffff;
    char cccc[4];
    uint8_t iiii[4];
   int16_t  dataint16[2];
  int32_t  dataint32;
} UserFtoCtoI;    //联合体,方便整形和浮点转换。
UserFtoCtoI   temp; //定义一个联合体变量,它的成员自动符合地址对齐
把你得到的串口字节数据,逐个赋值给temp.iiii[0]~temp.iiii[3];
然后 temp.ffff 就是你需要的浮点数了。


回复

使用道具 举报

7

主题

7

回帖

28

积分

新手上路

积分
28
 楼主| 发表于 2021-8-25 16:38:50 | 显示全部楼层
是STM32H7系列控制器开的数组中每个数地址不是对齐的吗?STM32F103使用这个是可以的
我把u8数组中的四个字节赋给u32的一个变量,然后再用指针转换成float型,这个可以的
回复

使用道具 举报

1

主题

94

回帖

97

积分

初级会员

积分
97
发表于 2021-8-25 20:44:45 | 显示全部楼层
可以用ALIGN_4BYTES 关键字
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2021-8-26 08:01:17 | 显示全部楼层
开启硬件FPU,浮点数据的地址必须4字节对齐。
没有开启的话,随意,因为M内核支持非对齐访问。
回复

使用道具 举报

73

主题

1200

回帖

1419

积分

至尊会员

积分
1419
发表于 2021-8-26 08:42:04 | 显示全部楼层
牛逼了,解答
回复

使用道具 举报

4

主题

9

回帖

21

积分

新手上路

积分
21
发表于 2022-8-18 18:15:03 | 显示全部楼层
eric2013 发表于 2021-8-26 08:01
开启硬件FPU,浮点数据的地址必须4字节对齐。
没有开启的话,随意,因为M内核支持非对齐访问。

硬汉哥,想请问一下,float类型定义后字节默认为4字节,有没有什么方式实现自定义float为2字节或者别的字节?现在有个需求就是想减小内存,想把4字节减小到2字节。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2022-8-19 09:32:14 | 显示全部楼层
mountxing 发表于 2022-8-18 18:15
硬汉哥,想请问一下,float类型定义后字节默认为4字节,有没有什么方式实现自定义float为2字节或者别的字 ...

计算后转换长16bit整形,看看够不够表达范围。
回复

使用道具 举报

0

主题

35

回帖

35

积分

新手上路

积分
35
发表于 4 天前 来自手机 | 显示全部楼层
eric2013 发表于 2021-8-26 08:01
开启硬件FPU,浮点数据的地址必须4字节对齐。
没有开启的话,随意,因为M内核支持非对齐访问。

硬汉哥你好,我是用的是stm32H7,开启硬件fpu,前两张图分别是对其中一个浮点数赋值,但是这个浮点的地址不是四字节对齐的,有一个计算地址偏移是0x0E,这个是对的,另外一个计算的地址偏移是0x10是错的,我使用了pack属性,以前一直没发现问题,但是这里发现了,而且我的代码里面有其他地方也是这么使用的,也没错,让我不解的是为什么一个地方赋值正确,另外一个地方却不对的了,哪里出了问题啊
1715423994470.jpg
1715423998184.jpg
1715424002247.jpg
回复

使用道具 举报

0

主题

35

回帖

35

积分

新手上路

积分
35
发表于 4 天前 | 显示全部楼层
yelu 发表于 2024-5-11 18:46
硬汉哥你好,我是用的是stm32H7,开启硬件fpu,前两张图分别是对其中一个浮点数赋值,但是这个浮点的地址 ...

而且我尝试了一下,我把接口封装一下
void fun(float temp)
{
    DD_debug.eiEnergySet = temp;
}
就像这样,然后在修改该变量的地方就调用这个函数而不是直接修改变量,这样就没问题,这是为什么呢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 3 天前 | 显示全部楼层
yelu 发表于 2024-5-11 21:36
而且我尝试了一下,我把接口封装一下
void fun(float temp)
{

这个帖子对硬件浮点问题做了进一步讨论。有时候可以,有时候不行,所以对齐是最保险的。

关于非对齐内存访问异常的问题
https://www.armbbs.cn/forum.php?mod=viewthread&tid=115867
回复

使用道具 举报

0

主题

35

回帖

35

积分

新手上路

积分
35
发表于 3 天前 | 显示全部楼层
eric2013 发表于 2024-5-12 08:31
这个帖子对硬件浮点问题做了进一步讨论。有时候可以,有时候不行,所以对齐是最保险的。

关于非对齐内 ...

硬汉哥,下图是我的cache配置

cache配置

cache配置

DD_debug这个变量就在这片内存里面,这个变量的定义见下图:

DD_debug结构体

DD_debug结构体

我使用了__attribute__((packed))属性,所以eiEnergySet这个变量的偏移地址应该是0x0E,就像下面这个图的偏移:

偏移量0x0E

偏移量0x0E

但是另外一个地方生成的指令偏移是0x10,使用的VSTR指令(指令描述见下图)见下图:

偏移量0x10

偏移量0x10

VSTR指令描述

VSTR指令描述

是因为使用了VSTR指令所以后面的偏移必须是4的整数倍,然后这个地址就得是错的?而且这个过程中也没有异常发生,这是为啥?

还有就像上面所说的,我在DD_debug定义的文件中将赋值语句封装成函数,然后在对该变量赋值的地方使用封装的函数,这样就好了,因为函数生成的汇编的偏移始终就是0x0E,这我也不知道该怎么理解。

还有我的代码里面使用结构体的并且是非自然对其(使用了packed属性)的变量还有很多,目前我就发现这个有问题,第一次发现;我就在想,对于这种情况,有时候是对的,有时候是错的,而且错的时候也不发生异常,我该怎么避免呢?我感觉是我哪里出错了,但是不知道是哪里,硬汉哥帮帮我!!!

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 前天 09:03 | 显示全部楼层
yelu 发表于 2024-5-12 21:56
硬汉哥,下图是我的cache配置

DD_debug这个变量就在这片内存里面,这个变量的定义见下图:

前面发你的帖子建议你完整的读一下

不对齐的情况下,肯定某些情况是可以触发的,并不能保证不出问题。所以程序里面务必保持对齐才是规范的处理方法。
回复

使用道具 举报

0

主题

35

回帖

35

积分

新手上路

积分
35
发表于 前天 11:05 来自手机 | 显示全部楼层
好的,明白了,还是慎用
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 07:08 , Processed in 0.224337 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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