Jump to content

    

расположить массив в памяти (Си)

есть большой массив- миллион значений uint32_t

при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?

Где про это почитать? Как правильно объявлять такие большие массивы?

 

миллион- может и много, но даже 10000 не хочет объявляться.

Share this post


Link to post
Share on other sites

Такие объёмы памяти на стеке не выделяются. Если это константы - добавьте ключевое слово const, если нет - выделяйте при помощи malloc/calloc.

Share this post


Link to post
Share on other sites
есть большой массив- миллион значений uint32_t

при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?

Где про это почитать? Как правильно объявлять такие большие массивы?

 

миллион- может и много, но даже 10000 не хочет объявляться.

Сами данные будут линейно в памяти располагаться?

Если да, то линкером выделяете эту область, чтобы ее компилятор не использовал, а в программе делаете указатель на нее

Если будет нужен конкретный элемент, то обращение типа

uint32_t *dp;

dp = (uint32_t*)0xYYYYYYYY;

*(dp+x) = 0xZZZZZZZZ;

 

если нужно - добавить volatile

Share this post


Link to post
Share on other sites
Сами данные будут линейно в памяти располагаться?

Если да, то линкером выделяете эту область, чтобы ее компилятор не использовал, а в программе делаете указатель на нее

ЗАчем все это ? Либо кучу сделать достаточного размера и привет malloc, либо сегмент .bss и просто объявить этот массив статически.

 

 

есть большой массив- миллион значений uint32_t

при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?

Где про это почитать? Как правильно объявлять такие большие массивы?

 

миллион- может и много, но даже 10000 не хочет объявляться.

Кто и какаую ошибку дает ? Какой компилятор-линкер использованы ? Сколько реально памяти в системе и как она разбита на секции ?

Share this post


Link to post
Share on other sites

немного не уточнил. Проект под STM32F4 IAR.

компилится нормально. Но, вывод по USB через VCP отваливается, как только массив больше 100. Просто ком порт не появляется в списке и все. Хотя, компиляция проходит. Причем без разницы- массив локальный или глобальный.

Share this post


Link to post
Share on other sites

То есть никаких ошибок линкера, на плате реально более 4 мегабайт памяти стоит ???? В ИАРе вроде используется .icf файлы (project-ooptions-linker-linker configuration file) - что в нем ? А если в General options на вкладке Stack-Heap поставите Heap такого большого размера и выделите память через malloc - что увидите ?

 

Насчет выделения.

void Foo()

{

char ar[10000]; // это на стеке

}

///////////////

 

char ar[10000]; // это глобально (или локально для файла с кваоификатором static) в сегмент .bss пойдет (в разных линкерах может называться иначе)

//code

///////////////

char *pAr = (char*) malloc (10000); // это в HEAP ляжет, по окончании использования делаем free (pAr);

Ну локальный массив на стеке в 40000 байт однозначно все отвалит и ляжем в hard fault, компилятор такое не проверяет. А вот глобальный массив он должен проверить на допустимость размера и линкер должен дать ошибку - мало памяти. Правда отвалится все если на стеке только если эта функция уже вызывалась... Мутно Вы как-то проблему описываете. Мне для начала интересно как к Ф4 столько памяти прицепить реальной..

Share this post


Link to post
Share on other sites

про 4 гига я уже потом подумал ;) Но оно и в 1000 значений не работает. И да, скомпилилось как ни в чем ни бывало. Вот странно.

Буду пробовать советы.

 

Еще раз описание- задействован вывод printf в USB.

массив на 1000 int32_t компилится нормально, и на 10 000 тоже нормально. Но путем поиска выяснил, что работает только при значении массива не более 100.

Как не работает- в диспетчере устройств- порты СОМ- он просто там не появляется. Напомню, у меня VCP драйвер ои ST стоит.

 

ВРоде все описал.

 

DASM, за примеры спасибо, запомню где что.

toweroff, Ваш пример- как раз то, как библиотека STM32 регистры назначения обрабатывает- нашел сходство )

Share this post


Link to post
Share on other sites

Массив с изменяемыми данными, или с константами? Насколько сильно отбирает ОЗУ остальная программа? Если добавить-убрать глобальных переменных, расположенных в ОЗУ, размер массива, с которого появляется ошибка, будет изменяться?

Share this post


Link to post
Share on other sites

массив заполняется результатом измерений- т.е. не константа.

Остальная программа- это работа с USB. Точно не знаю сколько. Тоже что-то ест.

 

Share this post


Link to post
Share on other sites

А в прошивке используется выделение памяти на куче (операторы new, new[]), или всё статически на этапе компиляции задаётся?

Share this post


Link to post
Share on other sites

опять наступаю на подобные грабли.

принимаю данные в массив от визнета.

как только размер массива задаю >50, сразу что-то не так в исполнении программы. Хотя, компилится без проблем.

uint8_t recv_IP[500];

объявлен как глобальный.

Получается, что он в ОЗУ объявляется? Массив меньше 1 Кб. ОЗУ же 192 с чем-то Кб.

Почему так? Должно же нормально объявляться? ОЗУ ему достаточно ведь для размещения массива?

Share this post


Link to post
Share on other sites

А какой размер CSTACK в настройках стоит?

Share this post


Link to post
Share on other sites

Ну есть предположение что размера CSTACK не хватает, а т.к. его переполнение при работе не проверяется, то оно может портить память (было такое пару раз в IAR AVR).

Ну память явно чем-то портится, но вот чем? Можно для теста увеличить CSTACK раз в несколько и посмотреть что будет (хотя 0x2000 должно хватать, но мало ли). Если не оно, то значит портится в каком-то другом месте.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this