Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Инициализация данных
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
SanyaKID
Что-то я в последнее время много топиков развел, но все же....

В компиляторе REAL VIEW в KEIL, в соответствии с сишными стандартами, явно неинициализированные переменные по дефолту инициализируются нулями, но, напимер, в моем случае это очень неудобно.
У меня есть дополнение к некоторому массиву данных который храниется во флеше, которое должно быть инициализировано 0xFF-ми, но это дополнение в общем случае переменной длины, которая вычисляется в зависимости от длины массива данных. Тоесть сейчас я компилируюсь с одной длиной дополнения, а завтра эта длина может поменяться. И соответственно очень не хочется каждый раз руками изменять в коде количество 0xFF-ов, к тому же можно просто забыть про это, что вызовет ошибки...
Так вот, я копался в хелпах Кейла, но так и не нашел директивы, меняющей инициализацию по умолчанию... Может быть есть возможность делать инициализацию как-нибуть в автомате? Может макросы такие есть или всетаки директивы?
zltigo
Цитата(SanyaKID @ Aug 23 2007, 10:59) *
Так вот, я копался в хелпах Кейла, но так и не нашел директивы, меняющей инициализацию по умолчанию...

Не майтесь и не создавайте проблем себе - все, что должно-быть инициализировано явно, должно быть явно и инициализировано. Кроме того, как нечно хранящееся во Flash может быть "переменной" и инициализироваться.
Цитата
...в соответствии с сишными стандартами, явно неинициализированные переменные по дефолту инициализируются нулями,

В общем случае - категорически нет.
SanyaKID
Цитата(zltigo @ Aug 23 2007, 12:23) *
Не майтесь и не создавайте проблем себе - все, что должно-быть инициализировано явно, должно быть явно и инициализировано. Кроме того, как нечно хранящееся во Flash может быть "переменной" и инициализироваться.


Ну это константа. Например так:

Код
//sn.h
#define SN_LEN 10;

unsigned char sn[SN_LEN] = {1,2,3,4,5,6,7,8,9,0};

.................

//struct.h
typedef struct
{
    unsigned char   massiv[SN_LEN];
    unsigned char    dummy[16-sizeof(massiv) %16];
} FN_STR;

.................

//struct.c
const FN_STR fn_serial  __at(0x1230) =
{
    sn,
    {0xFF}
};



Пример упрощен, но суть примерно такая. в dummy 0xFF будет только первый байт, а остальные нулями. А хотелось бы чтобы какнибуть в автомате сделать весь dummy 0xFF.

Это все сводится к тому, чтобы выравнивать данные по адресам и по дленне до кратности 16 байтам.
zltigo
Цитата(SanyaKID @ Aug 23 2007, 11:46) *
Ну это константа.

Я понял, о чем шла речь.
Просто счел необходимым отметить, что к неициализированным переменным, которые потому и не инициализированные, что не инициализируются smile.gif этот случай не имеет никакого отношения.
В данном случае Ваша переменная (или константа, если Вы прикажете разместить ее в CONST сегменте)
это вся структура целиком и инициализация хотя-бы одного элемента сразу всю стуктуру целиком делает инициализированной и приводит к ее размещению вне сегмента BSS. Неинициализированные Вами явно поля не могут иметь 'никакого' значения и по это причине действительно инициализируются 0. Но еще раз подчеркивую Вы имеете дело с инициализированной структурой, а отнюдь не с тем, что якобы в 'С' неициализированные данные обнуляются.
В подобных случаях придется явно инициализовать 0xFF при объявлении, а правильнее считать, что неиспользуемые элементы обнулены smile.gif.
Для случая выравнивания все проще - эту проблему обычно решает #pragma data_alignment=
хотя насчет того, что мусор между структурами будет 0xff никаких гарантий быть не может.
Выводы - практически наверняка неудачно постороена система работы с вышеописанной стуктурой - поменяйте smile.gif, дабы независеть от содержимого памяти ПОСЛЕ структуры.
SanyaKID
Спасибо за разъяснения! Насчет структуры я подумаю. А прагмы такой в этом компиляторе RealView нету sad.gif Есть другие, но они позволяют выравнивать только по 8 байт.
zltigo
Цитата(SanyaKID @ Aug 23 2007, 12:46) *
Есть другие, но они позволяют выравнивать только по 8 байт.

Очень странное ограничение. А Вы не ошибаетесь? Не позволяют - это одно, "не работают" - это другое и понятное, поскольку скорее всего сам сегмент в котором Вы данные размещаете выровенен всего на 8 байт - укажите ему выравнивание на 16.
VAI
Кстати, про выравнивание:
в версии 3.1 компилятора RV, что идет в комплекте с МДК3.11, корректно работает #pragma pack() - как в "IAR C/EC++ Compiler", "Borland C++Builder" или "Microsoft Visual C++".
Код
#pragma pack( 1 ) - выравнивание по байтам
#pragma pack( 2 ) - по 2 байта
#pragma pack( 4 ) - по 4 байта и т.д.
#pragma pack()    - выравнивание по умолчанию

В документации пока не отражено, но я потестировал, посмотрел листинги..
По ссылке косвенное подтверждение...
http://www.keil.com/forum/docs/thread9546.asp
SanyaKID
Она все-равно нулями выравнивает, и похоже опять-таки только максимум по 8 байт
amw
Не знаю как в RealView но в GCC, а точнее в LD достаточно записать в скрипте линкера что-то на подобие:
Код
/* Memory Definitions */
MEMORY
{
  FFINIT (r) : ORIGIN = 0x1230, LENGTH = 0x800
}

SECTIONS
{
  .ffdata :
  {
     *(.ffdata)
  }> FFINIT = 0xFF;
}

А C файле указать:
Код
const FN_STR fn_serial  = {Чего-то там равно}
} __attribute__ (( section(".ffdata") )) FN_STR;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.