簡體   English   中英

如何訪問映射內存中的位?

[英]How to access bits in mapped memory?

想像! 我從IO接口接收8個字節的uint8_t data[8] ,該接口處理一些房屋自動化。 這八個字節需要解釋為休假:

記憶解釋

如何訪問正確的位? 我現在考慮了兩種解決方案:

解決方案1:用一些位域定義一個結構:

struct data_s {
  uint8_t LightSwitch0:1;
  uint8_t LightSwitch1:1;
  uint8_t LightSwitch2:1;
  uint8_t LightSwitch3:1;
  uint8_t Brightness:4;
  uint8_t Dimmer0;
  uint8_t Dimmer1;
  uint8_t Dimmer2;
  uint8_t Dimmer3;
  uint8_t Dimmer4;
  uint8_t DoorSwitch:1;
  uint8_t Spare:7;
}

接下來,根據該示例,我可以簡單地進行強制轉換並訪問structs成員:

data_s *foo = data;
foo->LightSwtich1 = FALSE;
foo->Brightness = 7;
//...

解決方案2:使用位掩碼:

data[0] |= 0x02;
data[0] = (data[0] & 0x0F) | (( 7 << 4 ) & 0xF0)
//...

我知道位域是編譯器所依賴的,並且不那么可移植。 這就是為什么通常首選解決方案2的原因。 然而,解決方案2看起來要復雜得多,而且更難閱讀。 此外,如果映射的內存具有八個以上的字節,則將需要大量工作。

我真的需要解決方案2嗎? 或者我可以#pragma reverse_bitfields on指令#pragma reverse_bitfields on使用#pragma reverse_bitfields on來提高解決方案1的可移植性? 如果僅使用交叉編譯器為一個目標構建代碼,是否可以使用解決方案1?

所以我的問題是: 我應該如何訪問正確的位?

位域依賴於編譯器的程度已被誇大了。 當您以怪異的方式使用它們時,它們通常會變得怪異。

在您的示例中,所有字段都是無符號的,並且具有相同的存儲類型,它們都沒有跨越存儲邊界,並且沒有未使用的位。 有排序的問題(如您所見),但是近年來,每個人都對相同的排序感到滿意。 據我所知,沒有任何當前的編譯器會產生任何與您獲取的IO數據不兼容的東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM