簡體   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