2011-12-15 5 views
5

У меня есть структура конфигурации, которую я бы хотел сохранить на внутренней вспышке ARM-коры M3. В соответствии со спецификациями сохранение данных во внутренней вспышке должно быть выровнено до 32 бит. Поскольку у меня есть много логических и символов в моей структуре, я не хочу использовать 32 бита для хранения 8 бит ... Я решил упаковать структуру, используя прагму препроцессора __packed, Затем, когда я сохраняю ее как целую структуру , Я просто должен убедиться, что размер структуры делится на 4 (4 байта = 32 бит), я делаю это, добавляя байты заполнения, если это необходимо. В настоящее время во время разработки я много изменяю структуру, и чтобы она выровнялась с 32 битами, мне нужно постоянно менять байты заполнения. В настоящее время структура выглядит slike этогоВыравнивание структуры C во внутренней FLASH-памяти

typedef __packed struct 
{ 
uint8_t status; 
uint16_t delay; 
uint32_t blabla; 
uint8_t foo[5]; 
uint8_t padding[...] // this has to be changed every time I alter the structure. 
} CONFIG; 

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

Редактировать: Обратите внимание. Данные сохраняются в конце внутренней вспышки, так опуская отступы не будет работать ...

+1

Я считаю, что ваше понимание неверно. Возможно, инструкции во флэш-памяти должны быть выровнены, и это будет гарантировано компилятором. Но данные, хранящиеся в флэш-памяти даже без выровненности, могут управляться ядрами cortex m3. Какой MCU компании вы используете? –

ответ

4

Возможно, это идея:

typedef __packed struct { 
    uint8_t status; 
    uint16_t delay; 
    uint32_t blabla; 
    uint8_t foo[5]; 
} CONFIG; 

typedef __packed struct { 
    CONFIG cfg; 
    uint8_t padding[4 - (sizeof(CONFIG) % 4)] 
} CONFIGWRAPPER; 
+0

На самом деле, когда я думаю об этом. Если он уже выровнен, мы добавим 4 байта для ничего – stdcall

4

Решение 1: Вы можете поместить его в союз содержащий структуру и массив символов:

union 
{ 
    CONFIG config; 
    uint8_t total_size[32]; 
} my_union; 
+0

Это интересно, скажем, что sizeof (CONFIG) меньше размера total_size. и я устанавливаю конфигурацию в объединении. что будет sizeof (my_union)? – stdcall

+0

Если 'CONFIG' меньше, чем' total_size', то 'sizeof (my_union)' будет размером 'total_size', конкретно 32. – Lindydancer

1

решение 2: Вы можете использовать IAR-специфическую особенность #pragma location размещать конфигурационные данные в определенном месте, как 32 с конца вспышки. Таким образом, вы не должны были бы колодки структуры в любом случае:

/* Fictitious end of flash location. */ 
#pragma location=0x1234FFE0 
struct [... your struct goes here ...] 
3

Во-первых, упаковано выравнивание обычно следует избегать, если вы в конечном итоге с данными не выровнены с их естественными границами, некоторые процессоры будут просто выдавать когда вы пытаетесь получить к ним доступ.

Сначала сохраните элементы в заказе, чтобы компилятор не добавлял промежутки для выравнивания (или, если это так, добавляет его в конце). Если вы можете, у 1-го члена есть требование выравнивания, которое вы желаете, поскольку это заставляет компилятор хотя бы дать структуре, которая сильно выравнивается.

Это требует некоторых знаний о том, как требования к выравниванию вашей платформы и компилятора, например. избавиться от массива отступа, а также изменить

typedef struct 
{ 
uint8_t status; 
uint16_t delay; 
uint32_t blabla; 
uint8_t foo[5]; 
uint8_t padding[...]; 
} CONFIG; 

в

typedef struct 
{ 
uint32_t blabla; 
uint16_t delay; 
uint8_t status; 
uint8_t foo[5]; 
} CONFIG; 

Тогда скажите компилятору, что эта структура нуждается в 4 байт ALIGMENT (в данном случае, скорее всего, уже будет как первый член имеет 4 байта или больше требований к выравниванию). например с использованием gcc attribute((__aligned__(4))

Затем напишите небольшую тестовую программу, которая проверяет ваши требования к выравниванию (которая представляет собой небольшую программу, которая использует sizeof() и alignof() для вашей структуры), это даже скажет вам, если вы необходимо добавить инструкцию для выравниваемой структуры. Запустите эту программу как часть сборки/упаковки.

+0

Отличный ответ и хорошо сказано. Пробная тестовая программа имеет решающее значение для вашего успеха или неудачи, вы НЕ МОЖЕТЕ пропустить этот шаг, если хотите сделать то, что вы пытаетесь сделать с помощью структур в компилируемых доменах (считайте аппаратное обеспечение компилятором). –