Структурная битовая упаковка и неоднозначность LSB / MSB C ++

0

Мне пришлось написать код c++ для следующего заголовка пакета:

Изображение 174551

Исходная ссылка на изображение, 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-битный процессор.

  • 0
    Я хотел бы хранить данные в структуре как обычные целые числа. И создайте функции pack / unpack для преобразования структуры в поток битов при необходимости.
Теги:
struct
embedded
bit-packing

3 ответа

5

Точно так же, как биты отображаются при использовании битовых полей, специфичны для реализации. Поэтому очень сложно сказать, если вы это сделаете правильно, нам нужно будет знать точный процессор и компилятор (и, конечно же, версию компилятора).

Вкратце; не делайте этого. Бит-поля не очень удобны для таких вещей.

Делайте это вручную вместо этого, объявляя слова по мере необходимости и устанавливая биты внутри них.

  • 0
    Согласились бы. Вы можете использовать встроенные функции-члены, чтобы абстрагироваться от гротескных масок и сдвигов.
  • 0
    А также помните о процессоре endian-ness.
Показать ещё 1 комментарий
2

ИМХО любой, кто пытается построить struct таким образом, находится в состоянии греха.

Стандарт C99, например, гласит:

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

Даже если вы могли бы предсказать, что ваш компилятор будет строить бит-поля в единицах (скажем) uint32_t, а поля были выстроены первым битом LS поля... у вас все еще есть сущность, с которой нужно справиться!

Итак... как расслабляется говорит... делай это вручную!

0

Я согласен, что вы не должны этого делать. Однако STMicroelectronics использует битовые поля для доступа к битам своих регистров микроконтроллера Cortex-M3/M4. Таким образом, любой поставщик компилятора, который хочет, чтобы его пользователи могли использовать библиотеки STMicroelectronics Cortex-M3/M4, должны поддерживать распределение битовых полей, начиная с младшего значащего бита. В моем компиляторе это значение по умолчанию, но оно также необязательно, поэтому я мог бы отменить его, если захочу.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню