AlphaLaiman 0 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Реализовал выполнение кода из ОЗУ на STM32, отредактировав .icf файл. Вопрос в следующем: у меня в коде присутствует большой константный массив данных (картинка). Как мне сказать компилятору, чтобы он не копировал её в оперативку и не забивал память почем зря? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Реализовал выполнение кода из ОЗУ на STM32, отредактировав .icf файл. Вопрос в следующем: у меня в коде присутствует большой константный массив данных (картинка). Как мне сказать компилятору, чтобы он не копировал её в оперативку и не забивал память почем зря? Перенести этот массив во FLASH-регион описанный в .icf. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlphaLaiman 0 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Перенести этот массив во FLASH-регион описанный в .icf. Вот я и пытаюсь понять, как это сделать, чтобы не копировалось. Пробовал, например, #pragma location = ".rodata", не помогает .icf файл.: /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x00000000; define symbol __ICFEDIT_region_RAM_end__ = 0x0002FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x2000; define symbol __ICFEDIT_size_heap__ = 0x2000; /**** End of ICF editor section. ###ICF###*/ /* intvec location in RAM after remapping in SystemInit */ define symbol RAM_intvec_start = 0x00000000; define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readonly, readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:RAM_intvec_start { section .intvec_RAM }; /*place at address mem:RAM_intvec_start { readonly section .intvec };*/ place in ROM_region { readonly }; place in RAM_region { readwrite }; place in CCMRAM_region { section .ccmram, block CSTACK, block HEAP }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Вот я и пытаюсь понять, как это сделать, чтобы не копировалось. Пробовал, например, #pragma location = ".rodata", не помогает .cpp: static char const t[] @ ".httpContent" = {...}; .icf: define region FLASHC_regionC = mem:[from 0x08020000 to 0x081FFFFF]; //PMU/FLASH (cached) ... place in FLASHC_regionC {section .httpContent}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlphaLaiman 0 18 апреля, 2018 Опубликовано 18 апреля, 2018 (изменено) · Жалоба Попробовал, результат следующий: в отладчике массив лежит во Flash, как и хотелось, но теперь другой косяк - вместо значений из .cpp файла в нем одни нули UPD: а иногда одни 0xFF Изменено 18 апреля, 2018 пользователем AlphaLaiman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Предлагаю заглянуть в .map файл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Попробовал, результат следующий: в отладчике массив лежит во Flash, как и хотелось, но теперь другой косяк - вместо значений из .cpp файла в нем одни нули UPD: а иногда одни 0xFF Так ищите где у Вас косяк. Я Вам выдержки из рабочего проекта привёл, где всё ок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlphaLaiman 0 18 апреля, 2018 Опубликовано 18 апреля, 2018 (изменено) · Жалоба Так ищите где у Вас косяк При замене Вашего кода .cpp: static char const t[] @ ".httpContent" = {...}; например на .cpp: static char const t[] @ ".ccmram" = {...}; все работает. Но ccmram тоже не хочется забивать этим массивом Предлагаю заглянуть в .map файл. Если воспользоваться советом jcxz, то в map файле следующее: "P1": 0x207c P1 s0 0x08000190 0x207c <Init block> .httpContent inited 0x08000190 0x207c graphics.o [1] - 0x0800220c 0x207c вроде тут все норм Изменено 18 апреля, 2018 пользователем AlphaLaiman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба .httpContent inited 0x08000190 0x207c graphics.o [1] вроде тут все норм Где же норм? Вы бы хоть поинтересовались в этом же .map как у Вас const-элементы выглядят! Вот это норм: .httpContent const 0x08020000 0x1444 content.cpio [1] А inited - это runtime-инициализируемая переменная: .data inited 0x20022468 0x4 dflash.o [2] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlphaLaiman 0 18 апреля, 2018 Опубликовано 18 апреля, 2018 (изменено) · Жалоба Но я ведь вроде все также сделал, как у Вас. Может, Вы не все показали? Инициализация массива: static BYTE const font[] @ ".httpContent" = { #include "table_char_5x7.h" }; icf файл: /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x00000000; define symbol __ICFEDIT_region_RAM_end__ = 0x0002FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x2000; define symbol __ICFEDIT_size_heap__ = 0x2000; /**** End of ICF editor section. ###ICF###*/ /* intvec location in RAM after remapping in SystemInit */ define symbol RAM_intvec_start = 0x00000000; define memory mem with size = 4G; define region FLASHC_regionC = mem:[from 0x08080000 to __ICFEDIT_region_ROM_end__]; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to 0x0807FFFF]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readonly, readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:RAM_intvec_start { section .intvec_RAM }; /*place at address mem:RAM_intvec_start { readonly section .intvec };*/ place in FLASHC_regionC { section .httpContent}; place in ROM_region { readonly }; place in RAM_region { readwrite }; place in CCMRAM_region { section .ccmram, block CSTACK, block HEAP }; Изменено 18 апреля, 2018 пользователем AlphaLaiman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба initialize by copy { readonly, readwrite }; Ничем не смущает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlphaLaiman 0 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба initialize by copy { readonly, readwrite }; Ничем не смущает? Ну так я же в начале темы написал, что хочу, чтобы код выполнялся из RAM. Для этого копирую туда код Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Для этого копирую туда код В readonly секции?? :01: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 18 апреля, 2018 Опубликовано 18 апреля, 2018 (изменено) · Жалоба initialize by copy { readonly, readwrite } except{ section .httpContent}; Cекцию .httpContent в исключения попробуй. В readonly секции?? :01: Вообще, мануал именно это и советует. If you want to copy the entire application from ROM to RAM at program startup, use the initilize by copy directive, for example: initialize by copy { readonly, readwrite }; The readwrite pattern will match all statically initialized variables and arrange for them to be initialized at startup. The readonly pattern will do the same for all read-only code and data, except for code and data needed for the initialization. Нелогично... Наверное, except{ section .httpContent} поможет. PS: А зачем для секции .httpContent свой регион заводить? Можно же просто в ROM_region её разместить. Даже больше, что-то мне подсказывает, что с атрибутом static const массив и так в readonly должен попасть. PPS: Я рассуждаю так. Регионы описывают физические области памяти, если они отличаются друг от друга свойствами или разнесены в адресном пространстве. Секции же описывают области программы. Если какие-то части программы (секции) требуют особенного размещения, то их размещают в нужном регионе, а если требуется то и по фиксированному адресу. Создавать пересекающиеся регионы - только осложнять жизнь линкеру. Изменено 18 апреля, 2018 пользователем VladislavS Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 апреля, 2018 Опубликовано 18 апреля, 2018 · Жалоба Нелогично... Наверное, except{ section .httpContent} поможет. initialize by copy { readonly, readwrite } Тогда уж лучше указать конкретные секции в initialize by copy {}. А readonly, readwrite в указанной конструкции указывают на все секции имеющие соответствующие атрибуты. PS: А зачем для секции .httpContent свой регион заводить? Можно же просто в ROM_region её разместить. Даже больше, что-то мне подсказывает, что с атрибутом static const массив и так в readonly должен попасть. Его секция будет иметь атрибут readoinly. Ну и попадёт в тот регион, который для readonly. Я скопировал этот пример из .icf-файла для отладки в ОЗУ. Там все остальные секции идут в ОЗУ. Только .httpContent - во FLASH так как большой и не меняется - нет смысла грузить при каждой отладке. Создавать пересекающиеся регионы - только осложнять жизнь линкеру. У меня и нет пересекающихся регионов. define region FLASHC_regionA = mem:[from 0x08000000 to 0x08001FFF]; //PMU/FLASH (cached) define region FLASHC_regionB = mem:[from 0x08002000 to 0x08003FFF]; //PMU/FLASH (cached) define region FLASHC_regionC = mem:[from 0x08020000 to 0x081FFFFF]; //PMU/FLASH (cached) define region FLASHU_regionA = mem:[from 0x0C000000 to 0x0C1FFFFF]; //PMU/FLASH (uncached) define region RAM_regionA = mem:[from 0x1FFE8000 size 0x18000]; //PSRAM (code) define region RAM_regionB = mem:[from 0x20000100 size 0x1FF00]; //DSRAM1 (RW-data) define region RAM_regionC = mem:[from 0x20020000 size 0x20000]; //DSRAM2 (RO-data) PS: А "ROM" я называю именно ROM - Read Only Memory. FLASH != ROM :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться