*rust* 0 21 марта, 2011 Опубликовано 21 марта, 2011 (изменено) · Жалоба Добрый день, господа! Среда 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, тогда прошу уважаемых модераторов перекинуть топик туда. Спасибо! Изменено 21 марта, 2011 пользователем IgorKossak Перенёс Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 56 22 марта, 2011 Опубликовано 22 марта, 2011 · Жалоба AT91SAM3U4E содержит всего 52кБ в двух SRAM Вообще-то в трех. [0x20080000-0x20083fff]: 0x8c0c minimum (size: 0x4000) Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1. И проект явно не совсем пустой - 0xc0c байт данных помимо массива. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*rust* 0 22 марта, 2011 Опубликовано 22 марта, 2011 · Жалоба Вообще-то в трех. Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh. Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав. Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1. И проект явно не совсем пустой - 0xc0c байт данных помимо массива. В проекте присутствовали две строки для вывода через DBGU, я их закоментил и все уложилось. Т.е получается, что невозможно создать буфер на 32кБ, целиком, т.к. он сможет поместиться только в SRAM0, но при резервировании даже одной переменной размер данных вылетает за предел памяти. Хорошо, почему тогда не получается создать два массива по 16кБ? Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 56 22 марта, 2011 Опубликовано 22 марта, 2011 · Жалоба Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh. Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав. Все правильно. Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1? Посмотрите мануал на линкер. К сожалению, я не пользуюсь IAR'ом, поэтому подсказать не могу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*rust* 0 23 марта, 2011 Опубликовано 23 марта, 2011 · Жалоба Подумав, пришел к выводу, что должен существовать способ размещения 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"); } Что писать, куда писать, на что смотреть - не понятно. Извините, если это все очевидно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bulya 0 23 марта, 2011 Опубликовано 23 марта, 2011 · Жалоба в скрипте линкера должны быть объявлены регионы 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]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*rust* 0 23 марта, 2011 Опубликовано 23 марта, 2011 · Жалоба Спасибо, попробую разобраться. Думаю вопросы еще возникнут. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*rust* 0 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба в .с Код #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 }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bulya 0 24 марта, 2011 Опубликовано 24 марта, 2011 (изменено) · Жалоба Какая связь между этими строками? 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 }; Изменено 24 марта, 2011 пользователем Bulya Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*rust* 0 25 марта, 2011 Опубликовано 25 марта, 2011 · Жалоба Bulya, спасибо все работает как Вы писали. После перемещения кучи и переменных в RAM1, RAM0 можно использовать под свои задачи, но в моем проекте не получается разместить кучу и стат. переменные в RAM1 т.к все это занимает больше чем 16кБ. Для проверки того, что не мои действия привели к такому требуемому объему, я загрузил пример mass storage device от ATMEL, в моем проекте это должно присутствовать, и попробовал сделать так как предлагалось выше. Результат один. Куча и т.д не помещаются в RAM1. Вывод напрашивается сам собой в этом случае инициализация массива такого объема невозможна, но остались вопросы: 1. Почему отъедается столько памяти? 2. Я не использую контроллер NAND flash, как можно добавить 4 кБ озу в общее пользование и как это посмотреть в файле линкера. 3. Кроме файла .map можно где-нибудь посмотреть оставшиеся ресурсы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bulya 0 25 марта, 2011 Опубликовано 25 марта, 2011 · Жалоба 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 и нужно смотреть на что расходуется память. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*rust* 0 25 марта, 2011 Опубликовано 25 марта, 2011 · Жалоба Bulya, огромное спасибо за Вашу помощь. Надеюсь, эта информация будет полезна всем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться