Битовые структуры - PullRequest
       84

Битовые структуры

0 голосов
/ 09 мая 2020

Я прочитал некоторые из предыдущих вопросов и связанных с ними ответов относительно битовых структур. Подавляющее большинство состоит в том, что выравнивание и упаковка битов зависят от компилятора.
В настоящее время я адаптирую часть кода Maxim / Mbed для микросхемы ЭКГ MAX30003. Этот чип имеет внутренние 32-битные регистры, доступ к которым осуществляется через SPI. Я адаптирую код к платформе "esp-idf ESP32 Arduino". Разработка ведется с использованием IDE VSCODE (windows10).

Максим использует следующую структуру для доступа к а) 32 битам как uint32_t и б) внутренним битам как отдельным битовым маскам. Подпрограмма max30001_reg_read () считывает все биты из внутреннего регистра в член структуры uint32_t ' .all '. Точно так же процедура max30001_reg_write () передает все биты из « .all » в регистр устройства. Битовые поля устанавливаются / очищаются с использованием членов ' .bit.nnnn '. Я не видел в исходном коде атрибутов __ __ ((упаковано)) или # pragma pack (n) .

Он правильно портирован и устанавливает правильные битовые поля. Таких регистров примерно 20.

Мой вопрос: это просто удачный случай или в этих двух компиляторах есть что-то, что правильно выравнивает битовые поля?

       /**
       * @brief CNFG_GEN (0x10) 
       */
      union max30001_cnfg_gen_reg {
        uint32_t all;
        struct {
          uint32_t rbiasn     : 1;
          uint32_t rbiasp     : 1;
          uint32_t rbiasv     : 2;
          uint32_t en_rbias   : 2;
          uint32_t vth        : 2;
          uint32_t imag       : 3;
          uint32_t ipol       : 1;
          uint32_t en_dcloff  : 2;
          uint32_t en_bloff   : 2;
          uint32_t reserved1  : 1;
          uint32_t en_pace    : 1;
          uint32_t en_bioz    : 1;
          uint32_t en_ecg     : 1;
          uint32_t fmstr      : 2;
          uint32_t en_ulp_lon : 2;
          uint32_t reserved : 8;
        } bit;

      } max30001_cnfg_gen;

int MAX30001::max30001_Rbias_FMSTR_Init(uint8_t En_rbias, uint8_t Rbiasv,
                                        uint8_t Rbiasp, uint8_t Rbiasn,
                                        uint8_t Fmstr) {
  if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) {
    return -1;
  }

  max30001_cnfg_gen.bit.en_rbias = En_rbias;
  max30001_cnfg_gen.bit.rbiasv   = Rbiasv;
  max30001_cnfg_gen.bit.rbiasp   = Rbiasp;
  max30001_cnfg_gen.bit.rbiasn   = Rbiasn;
  max30001_cnfg_gen.bit.fmstr    = Fmstr;

  if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) {
      return -1;
  }
  return 0;
}
...