|
как разместить массив 32кБ в SRAM, AT91SAM3U4E {IAR} |
|
|
|
Mar 21 2011, 07:43
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Добрый день, господа! Среда 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, тогда прошу уважаемых модераторов перекинуть топик туда. Спасибо!
Сообщение отредактировал IgorKossak - Mar 21 2011, 08:47
Причина редактирования: Перенёс
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Mar 22 2011, 15:34
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(*rust* @ Mar 21 2011, 10:43)  AT91SAM3U4E содержит всего 52кБ в двух SRAM Вообще-то в трех. Цитата(*rust* @ Mar 21 2011, 10:43)  [0x20080000-0x20083fff]: 0x8c0c minimum (size: 0x4000) Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1. И проект явно не совсем пустой - 0xc0c байт данных помимо массива.
|
|
|
|
|
Mar 22 2011, 19:47
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Цитата Вообще-то в трех. Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh. Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав. Цитата Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1. И проект явно не совсем пустой - 0xc0c байт данных помимо массива. В проекте присутствовали две строки для вывода через DBGU, я их закоментил и все уложилось. Т.е получается, что невозможно создать буфер на 32кБ, целиком, т.к. он сможет поместиться только в SRAM0, но при резервировании даже одной переменной размер данных вылетает за предел памяти. Хорошо, почему тогда не получается создать два массива по 16кБ? Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1?
|
|
|
|
|
Mar 22 2011, 20:44
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(*rust* @ Mar 22 2011, 22:47)  Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh. Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав. Все правильно. Цитата(*rust* @ Mar 22 2011, 22:47)  Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1? Посмотрите мануал на линкер. К сожалению, я не пользуюсь IAR'ом, поэтому подсказать не могу.
|
|
|
|
|
Mar 23 2011, 07:42
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Подумав, пришел к выводу, что должен существовать способ размещения 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"); } Что писать, куда писать, на что смотреть - не понятно. Извините, если это все очевидно.
|
|
|
|
|
Mar 23 2011, 11:56
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 11-10-08
Из: Харьков
Пользователь №: 40 874

|
в скрипте линкера должны быть объявлены регионы 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];
|
|
|
|
|
Mar 24 2011, 07:59
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Цитата в .с Код #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 };
|
|
|
|
|
Mar 24 2011, 09:55
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 11-10-08
Из: Харьков
Пользователь №: 40 874

|
Цитата Какая связь между этими строками? 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 };
Сообщение отредактировал Bulya - Mar 24 2011, 09:58
|
|
|
|
|
Mar 25 2011, 05:43
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Bulya, спасибо все работает как Вы писали. После перемещения кучи и переменных в RAM1, RAM0 можно использовать под свои задачи, но в моем проекте не получается разместить кучу и стат. переменные в RAM1 т.к все это занимает больше чем 16кБ. Для проверки того, что не мои действия привели к такому требуемому объему, я загрузил пример mass storage device от ATMEL, в моем проекте это должно присутствовать, и попробовал сделать так как предлагалось выше. Результат один. Куча и т.д не помещаются в RAM1. Вывод напрашивается сам собой в этом случае инициализация массива такого объема невозможна, но остались вопросы:
1. Почему отъедается столько памяти? 2. Я не использую контроллер NAND flash, как можно добавить 4 кБ озу в общее пользование и как это посмотреть в файле линкера. 3. Кроме файла .map можно где-нибудь посмотреть оставшиеся ресурсы?
|
|
|
|
|
Mar 25 2011, 11:25
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 11-10-08
Из: Харьков
Пользователь №: 40 874

|
Цитата 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 и нужно смотреть на что расходуется память.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|