*rust* 0 Posted March 21, 2011 (edited) · Report post Добрый день, господа! Среда IAR, проц. AT91SAM3U4E. Пытаюсь создать массив 32кБ (unsigned char). Пишет, что места нет, хотя проект пустой. AT91SAM3U4E содержит всего 52кБ в двух SRAM. Пытался создать два массива по 16кБ, подумав что компилятор не может разместить целый массив 32кБ сразу в двух SRAM, но все повторилось, пишет нет места. Error[Lp011]: section placement failed: unable to allocate space for sections/blocks with a total estimated minimum size of 0x8c0c bytes in <[0x20080000-0x20083fff]> (total uncommitted space 0x4000). Needed: [0x20080000-0x20083fff]: 0x8c0c minimum (size: 0x4000) Как решить этот вопрос? Может вопрос не совсем по адресу и мне нужно на ветку с IAR, тогда прошу уважаемых модераторов перекинуть топик туда. Спасибо! Edited March 21, 2011 by IgorKossak Перенёс Quote Ответить с цитированием Share this post Link to post Share on other sites
aaarrr 0 Posted March 22, 2011 · Report post AT91SAM3U4E содержит всего 52кБ в двух SRAM Вообще-то в трех. [0x20080000-0x20083fff]: 0x8c0c minimum (size: 0x4000) Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1. И проект явно не совсем пустой - 0xc0c байт данных помимо массива. Quote Ответить с цитированием Share this post Link to post Share on other sites
*rust* 0 Posted March 22, 2011 · Report post Вообще-то в трех. Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh. Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав. Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1. И проект явно не совсем пустой - 0xc0c байт данных помимо массива. В проекте присутствовали две строки для вывода через DBGU, я их закоментил и все уложилось. Т.е получается, что невозможно создать буфер на 32кБ, целиком, т.к. он сможет поместиться только в SRAM0, но при резервировании даже одной переменной размер данных вылетает за предел памяти. Хорошо, почему тогда не получается создать два массива по 16кБ? Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1? Quote Ответить с цитированием Share this post Link to post Share on other sites
aaarrr 0 Posted March 22, 2011 · Report post Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh. Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав. Все правильно. Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1? Посмотрите мануал на линкер. К сожалению, я не пользуюсь IAR'ом, поэтому подсказать не могу. Quote Ответить с цитированием Share this post Link to post Share on other sites
*rust* 0 Posted March 23, 2011 · Report post Подумав, пришел к выводу, что должен существовать способ размещения 32кБ в SRAM. 1. разместить 32кБ полностью в SRAM0, 2. разместить по 16кБ в SRAM0 и SRAM1. По первому пункту компилятор должен резервировать всю память SRAM0 для массива, а все остальные используемые переменные размещать в SRAM1 и SRAM(NFC). По второму каким-то образом разместить массивы по 16кБ в SRAM0 и SRAM1. Не один из вариантов у меня пока не получается. В документации на линкер иара я нашел как разместить по опред. адресу данные, но из-за недостаточных знаний компилятора не могу прикрутить этот код. .//In the linker configuration file, it can look like this: define block TempStorage with size = 0x1000, alignment = 4 { }; place in RAM { block TempStorage }; //To retrieve the start of the allocated memory from the application, the source code could //look like this: /* Declares a section */ #pragma section = "TempStorage" char *TempStorage() { /* Return start address of section TempStorage. */ return __section_begin("TempStorage"); } Что писать, куда писать, на что смотреть - не понятно. Извините, если это все очевидно. Quote Ответить с цитированием Share this post Link to post Share on other sites
Bulya 0 Posted March 23, 2011 · Report post в скрипте линкера должны быть объявлены регионы SRAM define region SRAM0 = Mem:[from 0x20000000 size 32K]; define region SRAM1 = Mem:[from 0x20080000 size 16K]; 1. разместить 32кБ полностью в SRAM0, в .icf place in SRAM0 { section TempStorage }; place in SRAM1 { readwrite, block CSTACK, ... }; в .с #pragma location = "TempStorage" unsigned char Buf[0x8000]; 2. разместить по 16кБ в SRAM0 и SRAM1. в .icf place in SRAM0 { readwrite, block CSTACK, ... }; place in SRAM1 { section SRAM1_data }; в .с unsigned char Buf0[0x4000]; #pragma location = "SRAM1_data" unsigned char Buf1[0x4000]; Quote Ответить с цитированием Share this post Link to post Share on other sites
*rust* 0 Posted March 23, 2011 · Report post Спасибо, попробую разобраться. Думаю вопросы еще возникнут. :rolleyes: Quote Ответить с цитированием Share this post Link to post Share on other sites
*rust* 0 Posted March 24, 2011 · Report post в .с Код #pragma location = "TempStorage" unsigned char Buf[0x8000]; Какая связь между этими строками? Делаю так по первому варианту когда 32кБ полностью пытаюсь инициализировать. в скрипте линкера дописываю place in RAM0_region { section TempStorage }; в .с #pragma section = "TempStorage" unsigned char Buf[0x8000]; компилируются нормально, но если начинаешь работать с Buf[] к примеру Buf[100]=0xAA; то все, лезут ошибки: Error[Lp011]: section placement failed: unable to allocate space for sections/blocks with a total estimated minimum size of 0xa38f bytes in <[0x20000000-0x20007fff]> (total uncommitted space 0x8000). Needed: [0x20000000-0x20007fff]: 0xa38c minimum (size: 0x8000) Вот мой скрипт линкера: /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ /*-Vector table start*/ define symbol __ICFEDIT_vector_start__ = 0x00080000; /*Add for CMSIS*/ /*-Memory Regions-*/ define symbol __ICFEDIT_region_RAM0_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM0_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM1_start__ = 0x20080000; define symbol __ICFEDIT_region_RAM1_end__ = 0x20083FFF; define symbol __ICFEDIT_region_ROM0_start__ = 0x00080000; define symbol __ICFEDIT_region_ROM0_end__ = 0x0009FFFF; define symbol __ICFEDIT_region_ROM1_start__ = 0x00100000; define symbol __ICFEDIT_region_ROM1_end__ = 0x0011FFFF; /*-Sizes-*/ /*define symbol __ICFEDIT_size_cstack__ = 0x1000;*//*for nandflash*/ define symbol __ICFEDIT_size_cstack__ = 0x2000; define symbol __ICFEDIT_size_heap__ = 0x200; /*-Specials-*/ /*define symbol __ICFEDIT_region_RAM_VECT_start__ = __ICFEDIT_region_RAM0_start__;*/ /*Referenced for CMSIS*/ /*define symbol __ICFEDIT_size_vectors__ = 0x100;*/ /*Referenced for CMSIS*/ /*-Exports-*/ /*export symbol __ICFEDIT_region_RAM_VECT_start__;*/ export symbol __ICFEDIT_vector_start__; /*Add for CMSIS*/ /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; /*define region RAM_VECT_region = mem:[from __ICFEDIT_region_RAM_VECT_start__ size __ICFEDIT_size_vectors__];*/ /*Referenced for CMSIS*/ /*define region RAM0_region = mem:[from __ICFEDIT_region_RAM0_start__+__ICFEDIT_size_vectors__ to __ICFEDIT_region_RAM0_end__];*/ /*Referenced for CMSIS*/ define region RAM0_region = mem:[from __ICFEDIT_region_RAM0_start__ to __ICFEDIT_region_RAM0_end__]; define region RAM1_region = mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__]; /*define region RAM_region = mem:[from __ICFEDIT_region_RAM0_start__+__ICFEDIT_size_vectors__ to __ICFEDIT_region_RAM0_end__] | mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__];*/ /*Referenced for CMSIS*/ define region ROM0_region = mem:[from __ICFEDIT_region_ROM0_start__ to __ICFEDIT_region_ROM0_end__]; define region ROM1_region = mem:[from __ICFEDIT_region_ROM1_start__ to __ICFEDIT_region_ROM1_end__]; /*define block RamVect with alignment = 8, size = __ICFEDIT_size_vectors__ { };*/ define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; /*place at start of ROM0_region { readonly section .vectors };*/ /*Referenced for CMSIS*/ place at address mem:__ICFEDIT_vector_start__ { readonly section .vectors }; /*Add for CMSIS*/ place in ROM0_region { readonly }; place in RAM0_region { readwrite, block HEAP }; place in RAM1_region { block CSTACK }; /* for nandflash*/ /*place in RAM_VECT_region { block RamVect };*/ /*Referenced for CMSIS*/ //Эту строку я дописываю place in RAM0_region { section TempStorage }; Quote Ответить с цитированием Share this post Link to post Share on other sites
Bulya 0 Posted March 24, 2011 (edited) · Report post Какая связь между этими строками? pragma всегда относится к следующему за ним определению. #pragma location задает секцию, в которую должен быть помещен определяемый объектю Вы кроме TempStorage помещаете в RAM0_region все статические переменные и кучу place in RAM0_region { readwrite, block HEAP }; надо place in RAM0_region { section TempStorage }; place in RAM1_region { readwrite, block HEAP, block CSTACK }; Edited March 24, 2011 by Bulya Quote Ответить с цитированием Share this post Link to post Share on other sites
*rust* 0 Posted March 25, 2011 · Report post Bulya, спасибо все работает как Вы писали. После перемещения кучи и переменных в RAM1, RAM0 можно использовать под свои задачи, но в моем проекте не получается разместить кучу и стат. переменные в RAM1 т.к все это занимает больше чем 16кБ. Для проверки того, что не мои действия привели к такому требуемому объему, я загрузил пример mass storage device от ATMEL, в моем проекте это должно присутствовать, и попробовал сделать так как предлагалось выше. Результат один. Куча и т.д не помещаются в RAM1. Вывод напрашивается сам собой в этом случае инициализация массива такого объема невозможна, но остались вопросы: 1. Почему отъедается столько памяти? 2. Я не использую контроллер NAND flash, как можно добавить 4 кБ озу в общее пользование и как это посмотреть в файле линкера. 3. Кроме файла .map можно где-нибудь посмотреть оставшиеся ресурсы? Quote Ответить с цитированием Share this post Link to post Share on other sites
Bulya 0 Posted March 25, 2011 · Report post 1. Почему отъедается столько памяти? размеры стека и кучи определены в define symbol __ICFEDIT_size_cstack__ = 0x2000; define symbol __ICFEDIT_size_heap__ = 0x200; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; все остальное - статические переменные, созданные в программе 2. Я не использую контроллер NAND flash, как можно добавить 4 кБ озу в общее пользование и как это посмотреть в файле линкера. define symbol __region_NAND_RAM_start__ = 0x20100000; define symbol __region_NAND_RAM_end__ = 0x2010107F; define region NAND_RAM_region = mem:[from __region_NAND_RAM_start__ to __region_NAND_RAM_end__]; Но определять какие секции должны лечь в этот регион надо в .icf самому. Можно, например, перенести туда из RAM1_region стек и кучу: place in NAND_RAM_region { block HEAP, block CSTACK }; или какие-то крупные объекты, которые легко выделить в отдельную секцию через #pragma location = "NAND_RAM_section" place in NAND_RAM_region { section NAND_RAM_section }; Именно в .map и нужно смотреть на что расходуется память. Quote Ответить с цитированием Share this post Link to post Share on other sites
*rust* 0 Posted March 25, 2011 · Report post Bulya, огромное спасибо за Вашу помощь. Надеюсь, эта информация будет полезна всем. Quote Ответить с цитированием Share this post Link to post Share on other sites