Мне пришлось написать код C ++ для следующего заголовка пакета:
Исходная ссылка на изображение, PNG-версия вышеупомянутого JPEG.
Вот структурный код, который я написал для вышеуказанного формата пакета. Я хочу знать, правильны ли битовые поля uint8_t или uint16_t
struct TelemetryTransferFramePrimaryHeader
{
//-- 6 Ocets Long --//
//-- Master Channel ID (2 octets)--//
uint16_t TransferFrameVersionNumber : 2;
uint16_t SpacecraftID : 10;
uint16_t VirtualChannelID : 3;
uint16_t OCFFlag : 1;
//-----------------//
uint8_t MasterChannelFrameCount;
uint8_t VirtualChannelFrameCount;
//-- Transfer Frame Data Field Status (2 octets) --//
uint16_t TransferFrameSecondaryHeaderFlag : 1;
uint16_t SyncFlag : 1;
uint16_t PacketOrderFlag : 1;
uint16_t SegmentLengthID : 2;
uint16_t FirstHeaderPointer : 11;
//-----------------//
};
Как я могу гарантировать, что LSB -> MSB сохранен в структуре?
Я все время путаюсь и пытаюсь читать, но в конечном итоге это еще больше сбивает меня с толку.
PS: я использую 32-битный процессор.
Как именно отображаются биты при использовании битовых полей, зависит от реализации. Так что очень трудно сказать наверняка, если вы все сделали правильно, нам нужно знать точный процессор и компилятор (и версию компилятора, конечно).
Короче; не делай этого Битовые поля не очень пригодны для подобных вещей.
Вместо этого сделайте это вручную, объявив слова по мере необходимости и установив биты внутри них.
ИМХО любой пытается построить struct
таким образом, находится в состоянии греха.
Например, стандарт C99 гласит:
Реализация может выделить любой адресуемый блок памяти, достаточно большой для хранения битового поля. Если остается достаточно места, битовое поле, которое непосредственно следует за другим битовым полем в структуре, должно быть упаковано в смежные биты той же единицы. Если остается недостаточно места, определяется ли битовое поле, которое не умещается, в следующем блоке или перекрывает смежные блоки, определяется реализацией. Порядок распределения битовых полей внутри блока (от старшего к младшему или от младшего к старшему) определяется реализацией. Выравнивание адресуемой единицы хранения не указано.
Даже если бы вы могли предсказать, что ваш компилятор будет создавать битовые поля в единицах (скажем) uint32_t, а поля были упорядочены в битах LS первого поля … у вас все еще есть порядок байтов!
Так что … как говорит раскрутка … делай это вручную!
Я согласен, что вы не должны этого делать. Однако STMicroelectronics использует битовые поля для доступа к битам своих регистров микроконтроллера Cortex-M3 / M4. Поэтому любой поставщик компиляторов, который хочет, чтобы его пользователи могли использовать библиотеки STMicroelectronics Cortex-M3 / M4, должен поддерживать выделение битовых полей, начиная с младшего бита. В моем компиляторе это значение по умолчанию, но оно также необязательно, поэтому я могу отменить его, если захочу.