yanvasilij 0 6 мая, 2016 Опубликовано 6 мая, 2016 · Жалоба Доброго времени суток! Вопрос возможно дурацкий, но все же... Подключаю внешнюю SRAM к STM32 через FMC, компилятор arm-none-eabi. Параметры расположения данных в памяти настраиваю через файлa линковки. Расположить объявленный, например, массив во внешней SRAM труда не составит, но как сделать так, чтобы этот массив можно было инициализировать объявлением? Пусть есть файл someFile.c, переменные внутри которого расположены во внешней SRAM c помощью файл линковки. int data[20] = {1,2,3...20}; Инициализация к массиву data[] осуществляется после инициализации SDRAM в файле main.c extern int *data; int main (void) { SDRAM_init(); /*< Вот тут память инициализаруется */ printf ("data: %d\r", data[5]); while (1) { ... } } Есть ли способ переиницилизировать все массивы данными, которыми они были инициализированы при объявлении, не прибегая к рукопашному присваиванию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 6 мая, 2016 Опубликовано 6 мая, 2016 · Жалоба инициализацию памяти надо вынести в функцию, которая вызывается после старта (до вызова main и функций из стандартной библиотеки, которые занимаются инициализацией). Т.е. смотрите свой стартап Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amiller 2 6 мая, 2016 Опубликовано 6 мая, 2016 · Жалоба По моему сделать так как Вы хотите невозможно. На примере IAR: Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main(). А SDRAM у вас становится доступной в main(), после инициализации. Все остальные способы рукопашные. Я бы после инициализации внешней памяти добавил функцию типа SDRAM_data_init(), в которой и произвёл это действие. Для удобства можно объявить массив констант для инициализации во Flash. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 6 мая, 2016 Опубликовано 6 мая, 2016 · Жалоба инициализацию памяти надо вынести в функцию, которая вызывается после старта (до вызова main и функций из стандартной библиотеки, которые занимаются инициализацией). Т.е. смотрите свой стартап Спасибо за подсказку! Я заглянул в startup и обнаружил там такую штуку: .section .text.Reset_Handler .weak Reset_Handler .type Reset_Handler, %function Reset_Handler: /* Copy the data segment initializers from flash to SRAM */ movs r1, #0 b LoopCopyDataInit CopyDataInit: ldr r3, =_sidata ldr r3, [r3, r1] str r3, [r0, r1] adds r1, r1, #4 LoopCopyDataInit: ldr r0, =_sdata ldr r3, =_edata adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit ldr r2, =_sbss b LoopFillZerobss /* Zero fill the bss segment. */ FillZerobss: movs r3, #0 str r3, [r2], #4 LoopFillZerobss: ldr r3, = _ebss cmp r2, r3 bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit /* Call the application's entry point.*/ bl main bx lr .size Reset_Handler, .-Reset_Handler Если я правильно все понял, то мне нужно позвать после SDRAM_init() LoopCopyDataInit(): extern int *data; int main (void) { SDRAM_init(); /*< Вот тут память инициализаруется */ LoopCopyDataInit(); printf ("data: %d\r", data[5]); while (1) { ... } } В ближайшее время проверю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 6 мая, 2016 Опубликовано 6 мая, 2016 · Жалоба По моему сделать так как Вы хотите невозможно. На примере IAR: Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main(). А SDRAM у вас становится доступной в main(), после инициализации. А в чем проблема инициализировать SDRAM до инициализации переменных в System_init? Если я правильно все понял, то мне нужно позвать после SDRAM_init() LoopCopyDataInit(): extern int *data; int main (void) { SDRAM_init(); /*< Вот тут память инициализаруется */ LoopCopyDataInit(); printf ("data: %d\r", data[5]); while (1) { ... } } В ближайшее время проверю. Это, имхо, может быть чревато. Хотя в чистом Си без наворотов может и прокатит. Более правильно было бы перенести SDRAM_init() в стартап Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amiller 2 6 мая, 2016 Опубликовано 6 мая, 2016 · Жалоба А в чем проблема инициализировать SDRAM до инициализации переменных в System_init? Можно. Просто я такой способ отнёс к "рукопашным" вариантам. Наверное это будет даже проще, чем пытаться перенести инициализацию переменных на момент после инициализации SDRAM. Хотя лично я бы отключил System_init и написал свою функцию копирования переменных, используя адреса, которые формирует линкер. Просто не люблю присутствия стороннего кода, а System_init - как раз такой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 18 мая, 2016 Опубликовано 18 мая, 2016 · Жалоба Это, имхо, может быть чревато. Хотя в чистом Си без наворотов может и прокатит. Более правильно было бы перенести SDRAM_init() в стартап Последовал Вашему совету, и сделал так: Reset_Handler: /* Call the clock system intitialization function.*/ bl SystemInit bl SDRAM_init /*< Инициализация SDRAM в стартапе до main */ /* Copy the data segment initializers from flash to SRAM */ movs r1, #0 b LoopCopyDataInit CopyDataInit: ldr r3, =_sidata ldr r3, [r3, r1] str r3, [r0, r1] adds r1, r1, #4 LoopCopyDataInit: ldr r0, =_sdata ldr r3, =_edata adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit ldr r2, =_sbss b LoopFillZerobss /* Zero fill the bss segment. */ FillZerobss: movs r3, #0 str r3, [r2], #4 LoopFillZerobss: ldr r3, = _ebss cmp r2, r3 bcc FillZerobss /* Call the application's entry point.*/ bl main bx lr .size Reset_Handler, .-Reset_Handler Все прекрасно работает, спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 13 сентября, 2016 Опубликовано 13 сентября, 2016 · Жалоба Спрошу тут, чтобы не плодить веток. Подскажите как разместит в bss опредленного файла в сраме, с помощь линкерскрпита? Напирмер, в моем ликер файле определены секции памяти: MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K SDRAM (xrw) : ORIGIN = 0xD0000000, LENGTH = 31250K MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K } Что нужно дописать в скрипт, чтобы, например, bss файла heap_1.c распологалось в области SDRAM ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 15 сентября, 2016 Опубликовано 15 сентября, 2016 · Жалоба Спрошу тут, чтобы не плодить веток. Подскажите как разместит в bss опредленного файла в сраме, с помощь линкерскрпита? Что нужно дописать в скрипт, чтобы, например, bss файла heap_1.c распологалось в области SDRAM ? Наверное что-то типа .bss.sdram : { heap_1.o(.bss) } >SDRAM Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 15 сентября, 2016 Опубликовано 15 сентября, 2016 · Жалоба Добавил в скрипт эти строчки, при сборке выдает ошибку: arm-none-eabi/bin/ld.exe: cannot find heap_1.o Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 15 сентября, 2016 Опубликовано 15 сентября, 2016 · Жалоба Нужно определить функцию __low_level_init, или файл, плохо помню, подробнее найдёте в доке на яр. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 16 сентября, 2016 Опубликовано 16 сентября, 2016 · Жалоба Добавил в скрипт эти строчки, при сборке выдает ошибку: Не понял, зачем Вы это здесь написали... Вам непонятна суть ошибки? Линкер не нашел указанный в скрипте объектный файл. Такой файл вообще в вашем проекте есть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 16 сентября, 2016 Опубликовано 16 сентября, 2016 · Жалоба Не понял, зачем Вы это здесь написали... Вам непонятна суть ошибки? Линкер не нашел указанный в скрипте объектный файл. Такой файл вообще в вашем проекте есть? Такой файл в проекте есть. Мне не понятно, как это линкеру объяснить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 18 сентября, 2016 Опубликовано 18 сентября, 2016 · Жалоба А в чем проблема инициализировать SDRAM до инициализации переменных в System_init? Это, имхо, может быть чревато. Хотя в чистом Си без наворотов может и прокатит. Более правильно было бы перенести SDRAM_init() в стартап Да чем чревато? Я для 6816 в стартап коде чипселекты для памяти настраивал. Оно ведь еще до копирования переменных сегмента .data должно быть сделано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 19 сентября, 2016 Опубликовано 19 сентября, 2016 · Жалоба Такой файл в проекте есть. Можете показать фрагмент map-файла, где говорится о загрузке этого файла (когда Вы собираете проект без вынесения его .bss в SDRAM)? Мне не понятно, как это линкеру объяснить. В зависимости от того, отдельный ли это файл, или часть библиотели, либо указанием этого файла в командной строке линкера, либо указанием библиотеки через -l... Можете показать команду, которой линкуете проект? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться