2017-02-21 50 views
0

Представьте себе! Я получаю 8 байтов как uint8_t data[8] от интерфейса ввода-вывода, который обрабатывает некоторую автоматизацию дома. Эти восемь байт должны быть интерпретированы как залежи:Как получить доступ к битам в отображаемой памяти?

Memory interpretion

Как получить доступ правильных бит? Я думал, сейчас около двух решений:

Решение 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; 
} 

Далее я мог бы просто сделать слепок и получить доступ к членам структур согласно этому примеру:

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, чтобы улучшить переносимость решения 1? Могу ли я использовать решение 1, если код построен только для одной цели с помощью кросс-компилятора?

Так что мой вопрос: Как получить доступ к правильным битам?

+0

Битвы являются переносными и частью стандарта C. Это вопрос читаемости кода и привычек: в моем случае я предпочитаю битмаски, но многие люди предпочитают битфилды. – LPs

+0

MISRA используется для запрета использования битполей, я не знаю, все ли это делает. – Toby

+0

Вы можете сделать решение 2 более просто читаемым, используя макросы #define. В конечном итоге вы получите уродливые нечитаемые материалы в одном месте, что добавит преимущества сокращения объема работы, необходимой для внесения изменений в будущем. –

ответ

3

Степень, в которой битподы являются зависимыми от компилятора, несколько преувеличена. Они в основном становятся странными, когда вы используете их странным образом.

В вашем примере все поля являются неподписанными и имеют один и тот же тип хранилища, ни один из них не пересекает границу хранилища, а неиспользуемых битов нет. Существует проблема упорядочивания битов (как вы видели), но в последние годы все поселились в одном заказе. Насколько я знаю, никакой текущий компилятор не производит ничего, что несовместимо с данными IO, которые вы получаете.