Как передать битовое поле (по ссылке) в функцию? - PullRequest
1 голос
/ 15 апреля 2011

У меня вопрос, как передать экземпляр битового поля по ссылке на функцию. Я выполнил это, как показано ниже, но когда я вводил функцию DAC_set_gain_code, процессор выдает ошибку прерывания. Что я делаю правильно, когда проходит битовое поле?

Я создал битовое поле (см. Ниже), которое представляет 24-битный регистр на микросхеме ЦАП, в который я хочу записать, и хранится в файле .h.

typedef struct {
    uint8_t rdwr_u8:        1;
    uint8_t not_used_u8:    3;
    uint8_t address_u8:     4;
    uint8_t reserved_u8:    8;
    uint8_t data_u8:        8;
}GAIN_REG_st;

У меня есть функция, которая инициализирует битовое поле следующим образом:

void init(void)
{
    GAIN_REG_st GAIN_x;  //Create instance of bitfield

    //other code here...

    DAC_set_gain_code(channel_u8, gain_code_i8, &GAIN_x);   //Pass address of bitfield

    return;
 }

Функция, которая фактически заполняет битовое поле, показана ниже:

void DAC_set_gain_code(uint8_t channel_u8, int8_t gain_code_i8, GAIN_REG_st *GAIN)
{
    /* Populate ZERO_REG_st bitfield */
    GAIN->rdwr_u8       = 0;
    GAIN->not_used_u8 = 0;

    if(channel_u8==0){
        GAIN->address_u8 = GAIN_REGISTER_0;
    }
    else if(channel_u8==1){
        GAIN->address_u8 = GAIN_REGISTER_1;
    }
    else if(channel_u8==2){
        GAIN->address_u8 = GAIN_REGISTER_2;
    }
    else if(channel_u8==3){
        GAIN->address_u8 = GAIN_REGISTER_3;
    }

    GAIN->data_u8 = gain_code_i8;

    return;
}

Прототип функции для hal_DAC_set_gain_code_uni:

void DAC_set_gain_code(uint8_t channel_u8, int8_t gain_code_i8, GAIN_REG_st *GAIN);

Любой совет приветствуется.

Спасибо.

Ответы [ 2 ]

3 голосов
/ 25 апреля 2011

Так как real использует этот код для записи в аппаратный регистр, такие вопросы, как заполнение и выравнивание / упорядочение полей DOES имеют значение.

Я подозреваю, что компилятор использует 32-битные числа, и эта структура дополняется до 32-битных, но в отлаживаемом коде GAIN_X не является локальной переменной, вы передаете 0xNNNNNNN (или эквивалентный) - и адрес не находится на «правильной» границе (вполне возможно, поскольку это 24-битный регистр). Компилятор будет предполагать, что вы передаете указатель на реальный GAIN_REG_st, а не на адрес с пробой типа, и поэтому, возможно, сделали предположения о выравнивании.

Чтобы получить доступ к оборудованию напрямую из C / C ++, вам нужно знать , как компилятор обрабатывает подобные вещи, и быть уверенным, что вы лгите компилятору осторожно.

0 голосов
/ 15 апреля 2011

Может ли быть какая-то проблема с выравниванием?

Может быть, вы можете поиграть с параметрами выравнивания вашего компилятора?Или попробуйте набить свою конструкцию фиктивной uint8 в конце?

...