Выровненные и упакованные атрибуты - PullRequest
3 голосов
/ 11 августа 2011

Я работаю над прошивкой для 16-битного PIC и пишу на C (компилятор Microchip C30).Мое устройство получает длинный список байтов от внешнего устройства, а затем я пытаюсь скопировать эти байты в структуру.Структура определяется следующим образом:

typedef struct __attribute__((__packed__)) {
    char    F1Nickname[17];
    char    F2Nickname[17];
    DWORD   F1CurrentPos;
    DWORD   F2CurrentPos;
    WORD    F1CurrentTemp;
    WORD    F2CurrentTemp;
    DWORD   F1MaxPos;
    DWORD   F2MaxPos;
    BYTE    F1TempCompOn;
    BYTE    F2TempCompOn;
    BYTE    CheckSum;
} deviceStatus;

У меня была странная проблема: всякий раз, когда общее количество байтов в структуре было нечетным числом, моя программа зависала и попадала в подпрограмму службы AddressError.Я могу решить эту проблему, просто добавив дополнительный байт в структуру, но это похоже на исправление бинтов.

Я поместил упакованный атрибут в структуру, потому что хотел убедиться, что компилятор не вставиллюбые байты-заполнители между моими переменными.Если бы это произошло, значения в моей структуре были бы неверными при копировании из полученного массива символов.

Я знаю, что есть также атрибут с именем выровненный.Выравнивает ли выравнивание начала структуры по четному байту или выравнивает каждый элемент в структуре по четному байту?Как вы думаете, выровненный атрибут требуется здесь?Если я добавлю выравниваемый атрибут в эту структуру, я также должен добавить его в структуру на устройстве, которое отправляет данные, верно?На данный момент они оба определены точно так же, как показано выше.

Если я добавлю выравниваемый атрибут, я должен удалить упакованный атрибут?Разве они в основном не делают наоборот?

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Определенная микропроцессорная архитектура может выполнять выборку данных только по адресу, который выровнен по границам слова, и выдает исключение, если они не выровнены по словам. Часто компилятор помогает и генерирует код, который выполняет необходимую акробатику, чтобы гарантировать, что выборки выровнены по словам, но это не похоже на случай с вашим компилятором, и именно поэтому вы видите исключения.

В вашем случае вы используете struct для сериализации данных, и поэтому они должны быть упакованы. В этом случае вы должны либо переставить struct, чтобы гарантировать отсутствие чтения за границы слов, либо вам придется использовать распакованную структуру и вручную сериализовать данные.

2 голосов
/ 11 августа 2011

__attribute__ и __packed__ не являются частью стандарта C и являются расширениями, предоставляемыми вашим компилятором. Единственный способ узнать наверняка, что они имеют в виду, - найти это в документации компилятора.

...