Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: расположить массив в памяти (Си)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Метценгерштейн
есть большой массив- миллион значений uint32_t
при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?
Где про это почитать? Как правильно объявлять такие большие массивы?

миллион- может и много, но даже 10000 не хочет объявляться.
msalov
Такие объёмы памяти на стеке не выделяются. Если это константы - добавьте ключевое слово const, если нет - выделяйте при помощи malloc/calloc.
toweroff
Цитата(Метценгерштейн @ Aug 20 2014, 15:10) *
есть большой массив- миллион значений uint32_t
при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?
Где про это почитать? Как правильно объявлять такие большие массивы?

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

Сами данные будут линейно в памяти располагаться?
Если да, то линкером выделяете эту область, чтобы ее компилятор не использовал, а в программе делаете указатель на нее
Если будет нужен конкретный элемент, то обращение типа
Код
uint32_t *dp;

dp = (uint32_t*)0xYYYYYYYY;

*(dp+x) = 0xZZZZZZZZ;


если нужно - добавить volatile
DASM
Цитата(toweroff @ Aug 20 2014, 17:11) *
Сами данные будут линейно в памяти располагаться?
Если да, то линкером выделяете эту область, чтобы ее компилятор не использовал, а в программе делаете указатель на нее

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


Цитата(Метценгерштейн @ Aug 20 2014, 15:10) *
есть большой массив- миллион значений uint32_t
при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?
Где про это почитать? Как правильно объявлять такие большие массивы?

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

Кто и какаую ошибку дает ? Какой компилятор-линкер использованы ? Сколько реально памяти в системе и как она разбита на секции ?
Метценгерштейн
немного не уточнил. Проект под STM32F4 IAR.
компилится нормально. Но, вывод по USB через VCP отваливается, как только массив больше 100. Просто ком порт не появляется в списке и все. Хотя, компиляция проходит. Причем без разницы- массив локальный или глобальный.
DASM
То есть никаких ошибок линкера, на плате реально более 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 столько памяти прицепить реальной..
Метценгерштейн
про 4 гига я уже потом подумал wink.gif Но оно и в 1000 значений не работает. И да, скомпилилось как ни в чем ни бывало. Вот странно.
Буду пробовать советы.

Еще раз описание- задействован вывод printf в USB.
массив на 1000 int32_t компилится нормально, и на 10 000 тоже нормально. Но путем поиска выяснил, что работает только при значении массива не более 100.
Как не работает- в диспетчере устройств- порты СОМ- он просто там не появляется. Напомню, у меня VCP драйвер ои ST стоит.

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

DASM, за примеры спасибо, запомню где что.
toweroff, Ваш пример- как раз то, как библиотека STM32 регистры назначения обрабатывает- нашел сходство )
fatlortroll
Массив с изменяемыми данными, или с константами? Насколько сильно отбирает ОЗУ остальная программа? Если добавить-убрать глобальных переменных, расположенных в ОЗУ, размер массива, с которого появляется ошибка, будет изменяться?
Метценгерштейн
массив заполняется результатом измерений- т.е. не константа.
Остальная программа- это работа с USB. Точно не знаю сколько. Тоже что-то ест.
fatlortroll
А в прошивке используется выделение памяти на куче (операторы new, new[]), или всё статически на этапе компиляции задаётся?
Метценгерштейн
опять наступаю на подобные грабли.
принимаю данные в массив от визнета.
как только размер массива задаю >50, сразу что-то не так в исполнении программы. Хотя, компилится без проблем.
uint8_t recv_IP[500];
объявлен как глобальный.
Получается, что он в ОЗУ объявляется? Массив меньше 1 Кб. ОЗУ же 192 с чем-то Кб.
Почему так? Должно же нормально объявляться? ОЗУ ему достаточно ведь для размещения массива?
Dejmos
А какой размер CSTACK в настройках стоит?
Метценгерштейн
вроде вот- по умолчанию
http://c2n.me/iOOyiX

только не на стеке же должен был выделиться?
Dejmos
Ну есть предположение что размера CSTACK не хватает, а т.к. его переполнение при работе не проверяется, то оно может портить память (было такое пару раз в IAR AVR).
Ну память явно чем-то портится, но вот чем? Можно для теста увеличить CSTACK раз в несколько и посмотреть что будет (хотя 0x2000 должно хватать, но мало ли). Если не оно, то значит портится в каком-то другом месте.
Метценгерштейн
0х2000- это 8 кб памяти.
Вопрос в другом- как ловить-то?
да и массив ведь не на стеке объявляется же
Dejmos
Массив не на стеке, но стек может переполниться чем-то еще и затереть не относящуюся к нему область RAM. С 8кб маловероятно, но лучше проверить... это будет проверить проще всего.
С остальным - хз, не встречал еще инструментария, которым можно отследить обращения к конкретной области памяти. Тут импровизировать надо: Выяснять в какой момент и какими модулями портится эта память (не в момент же записи там данные бьются).
Lagman
Цитата(Метценгерштейн @ Aug 28 2014, 21:20) *
...
как только размер массива задаю >50, сразу что-то не так в исполнении программы. Хотя, компилится без проблем.
uint8_t recv_IP[500];
объявлен как глобальный.
...

А как Вы туда данные кладете через указатель или по индексу массива?
Метценгерштейн
передаю массив в ф-ю. т.е. адрес его.
проверил и со стеком 0х8000 - результат тот же
массив на 32- работает, на 500- вылетает
Метценгерштейн
пересобрал проект в Кейл- эффект такой же. Т.е., скорее, это не ошибка или глюк компилятора. Буду копать.

Нашел ошибку свою- обнулял массив переменной uint8_t, а задавал большой массив на 300.
Но еще глюки вылавливаю.
Не лишним было узнать- где он выделяется.
gerber
Цитата(Метценгерштейн @ Aug 30 2014, 22:36) *
Не лишним было узнать- где он выделяется.

А ведь есть map-файл ...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.