Перейти к содержанию
    

как разместить массив 32кБ в SRAM

Добрый день, господа!

 

Среда 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
Перенёс

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AT91SAM3U4E содержит всего 52кБ в двух SRAM

Вообще-то в трех.

 

[0x20080000-0x20083fff]: 0x8c0c minimum (size: 0x4000)

Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1.

И проект явно не совсем пустой - 0xc0c байт данных помимо массива.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще-то в трех.

 

Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh.

Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав.

 

Смотрите, что у вас написано в скрипте линкера для SRAM0 - он пытается уложить данные в 16Кб SRAM1.

И проект явно не совсем пустой - 0xc0c байт данных помимо массива.

 

В проекте присутствовали две строки для вывода через DBGU, я их закоментил и все уложилось. Т.е получается, что невозможно создать буфер на 32кБ, целиком, т.к. он сможет поместиться только в SRAM0, но при резервировании даже одной переменной размер данных вылетает за предел памяти.

 

Хорошо, почему тогда не получается создать два массива по 16кБ? Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно Вы имеете в виду 4кБ SRAM от NFC. Да согласен, 52кБ это с учетом SRAM от контроллера NAND flesh.

Если я правильно понимаю SRAM0 содержит 32кб, а SRAM1 16кБ. Поправьте меня если я не прав.

Все правильно.

 

Как явным образом указать компилятору поместить первым массив в конец SRAM0, а вторым полностью занять SRAM1?

Посмотрите мануал на линкер. К сожалению, я не пользуюсь IAR'ом, поэтому подсказать не могу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подумав, пришел к выводу, что должен существовать способ размещения 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");
}

 

Что писать, куда писать, на что смотреть - не понятно.

Извините, если это все очевидно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в скрипте линкера должны быть объявлены регионы 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];

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в .с

Код

#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 };

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какая связь между этими строками?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Bulya, спасибо все работает как Вы писали. После перемещения кучи и переменных в RAM1, RAM0 можно использовать под свои задачи, но в моем проекте не получается разместить кучу и стат. переменные в RAM1 т.к все это занимает больше чем 16кБ. Для проверки того, что не мои действия привели к такому требуемому объему, я загрузил пример mass storage device от ATMEL, в моем проекте это должно присутствовать, и попробовал сделать так как предлагалось выше. Результат один. Куча и т.д не помещаются в RAM1. Вывод напрашивается сам собой в этом случае инициализация массива такого объема невозможна, но остались вопросы:

 

1. Почему отъедается столько памяти?

2. Я не использую контроллер NAND flash, как можно добавить 4 кБ озу в общее пользование и как это посмотреть в файле линкера.

3. Кроме файла .map можно где-нибудь посмотреть оставшиеся ресурсы?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 и нужно смотреть на что расходуется память.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...