Поиск
Показаны результаты для тегов 'scatter'.
-
MDR32F1QI. Программа использует калибровочную таблицу переменной длины, под которую отводится страница памяти во Flash-области. В выделенной под таблицу секции памяти необходимо проинициализировать нулевыми значениями переменную — текущую длину таблицы, а так же сами данные. Соответствующий участок C-кода выглядит так: // Максимальное количество записей в таблице #define MAX_TABLE_SIZE 500 // Структура записи в таблице typedef struct { uint32_t value; uint32_t corr; } record_t; // Текущее количество записей в таблице const volatile size_t table_sz __attribute__((section(".table"))) = 0; // Массив стуктур const volatile record_t table[MAX_TABLE_SIZE] __attribute__((section(".table"))) = { {0, 0} }; Далее привожу соответствующий scatter-файл: LR_IROM1 0x00000000 0x00012000 { ; load region size_region ER_IROM1 0x00000000 0x00010000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00008000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x20100000 0x00004000 { mdr32f9qx_eeprom.o eeprom.o (+RO) .ANY (+RW +ZI) } } } LR_IROM2 0x00013000 0x00001000 { ; load region size_region ER_IROM2 0x00013000 0x00001000 { ; * (.table) } } Компилирую и собираю (ARMCC 5.06), после чего с помощью objdump смотрю выходной файл. И здесь начинается волшебство: Содержимое раздела ER_IROM2: 13000 01ff01ff 01ff01ff 01ff01ff 01ff01ff ................ 13010 01ff01ff 01ff01ff 01ff01ff 01ff01b3 ................ Далее, пытаюсь уменьшить длину массива в объявлении (MAX_TABLE_SIZE = 20). И, о чудо! Содержимое раздела ER_IROM2: 13000 00000000 00000000 00000000 00000000 ................ 13010 00000000 00000000 00000000 00000000 ................ 13020 00000000 00000000 00000000 00000000 ................ 13030 00000000 00000000 00000000 00000000 ................ 13040 00000000 00000000 00000000 00000000 ................ 13050 00000000 00000000 00000000 00000000 ................ 13060 00000000 00000000 00000000 00000000 ................ 13070 00000000 00000000 00000000 00000000 ................ 13080 00000000 00000000 00000000 00000000 ................ 13090 00000000 00000000 00000000 00000000 ................ 130a0 00000000 .... Опытным путем обнаружил, что максимальное работающее значение MAX_TABLE_SIZE равно 36. Тогда и переменная, отвечающая за текущую длину массива, и сам массив аккуратно в зануленном виде появляются в соответствующей секции. Иначе — мусор, подобный тому, что выше. Например, при MAX_TABLE_SIZE = 37 соответствующая секция выглядит так (вообще одно значение): Содержимое раздела ER_IROM2: 13000 01ff012d ...- Помогите разобраться с этим "волшебством". Сразу скажу, что при использовании GCC и ld никаких проблем не возникает. Массив и переменная в аккурат инициализируются в том количестве, какое задано. А вот с Keil у меня засада. Но необходимо делать код рабочим под оба компилятора. Есть, конечно, еще workaround: массив ведь можно заменить указателем относительно адреса переменной —- текущей его длины (что и было сделано в самом первоначальной версии), причем инициализация нулями его элементов необязательна — нулевая начальная длина (в соответствующей переменной) вполне достаточна для правильной работы программы. Но последующие считывание и запись в массив будут происходить тоже через смещения указателя относительно базового адреса переменной. Это, как мне кажется, не совсем удобно. Тем более, когда в GCC и ld все прекрасно работает. Посему в силу моего небольшого опыта прошу помочь разобраться с этой странной проблемой в Keil. Заранее спасибо за помощь.