繁体   English   中英

在 Arm Cortex-M3 上转换为双指针

[英]Casting to double pointer on Arm Cortex-M3

我正在使用 Arm Cortex-M3 处理器。 我在unsigned char数组中接收二进制数据,必须将其转换为合适的变量以用于进一步计算:

unsigned char gps[24] = { 0xFA, 0x05, 0x08, 0x00, 0x10, 0x00,0xA4, 0x15, 0x02, 0x42, 0x4D, 0xDF, 0xEB, 0x3F, 0xF6, 0x1A, 0x36, 0xBE, 0xBF, 0x2D, 0xA4, 0x41,
                          0xAF, 0x1A };
int i = 6;
float f = (float) *(double*)&gps[i];

此代码在计算机上工作以获得正确的“f”值,但在 Cortex-M3 上失败。 我知道处理器上没有算术单元,因此不支持 64 位操作; 但是是否有如上所示的变通方法。

请注意,下面的代码适用于处理器; 只有上面显示的铸造失败:

double d = 9.7;

另请注意,32 位转换可以工作,如下所示; 只有doubleuint64_t失败。

uint16_t k = *(uint16_t*)&gps[i];

有替代解决方案吗?

unsigned char的地址转换为指向double的指针——然后使用它——违反了严格的别名规则 更重要的是(在您的情况下,如下所述),它还打破了访问多字节(即double )数据单元所需的对齐规则

许多编译器会对此发出警告; clang-cl 为(double*)&gps[i]表达式提供以下内容:

警告:从 'unsigned char *' 转换为 'double *' 将所需对齐从 1 增加到 8 [-Wcast-align]

现在,一些架构对数据类型的对齐并不太挑剔,并且代码可能(似乎)适用于其中的许多。 但是,Cortex-M3 对多字节数据类型(例如double )的对齐要求非常挑剔

要删除未定义的行为,您应该使用memcpy函数将gps数组的组件字节转换为真正的double变量,然后将其转换为float

    unsigned char gps[24] = {0xFA, 0x05, 0x08, 0x00, 0x10, 0x00,0xA4, 0x15, 0x02, 0x42, 0x4D,
        0xDF, 0xEB, 0x3F, 0xF6, 0x1A, 0x36, 0xBE, 0xBF, 0x2D, 0xA4, 0x41, 0xAF, 0x1A };
    int i = 6;
    double d; // This will be correctly aligned by the compiler
    memcpy(&d, &gps[i], sizeof(double)); // This doesn't need source alignment
    float f = (float)d; // ... so now, this is a 'safe' cast down to single precision

memcpy调用将使用(或生成)可以安全访问未对齐数据的代码——即使这意味着访问速度显着减慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM