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

есть большой массив- миллион значений uint32_t
при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?
Где про это почитать? Как правильно объявлять такие большие массивы?
миллион- может и много, но даже 10000 не хочет объявляться.
Сами данные будут линейно в памяти располагаться?
Если да, то линкером выделяете эту область, чтобы ее компилятор не использовал, а в программе делаете указатель на нее
Если будет нужен конкретный элемент, то обращение типа
Код
uint32_t *dp;
dp = (uint32_t*)0xYYYYYYYY;
*(dp+x) = 0xZZZZZZZZ;
если нужно - добавить volatile
Цитата(toweroff @ Aug 20 2014, 17:11)

Сами данные будут линейно в памяти располагаться?
Если да, то линкером выделяете эту область, чтобы ее компилятор не использовал, а в программе делаете указатель на нее
ЗАчем все это ? Либо кучу сделать достаточного размера и привет malloc, либо сегмент .bss и просто объявить этот массив статически.
Цитата(Метценгерштейн @ Aug 20 2014, 15:10)

есть большой массив- миллион значений uint32_t
при его объявлении выскакивает ошибка. Вероятно, массивы на стеке выделяются?
Где про это почитать? Как правильно объявлять такие большие массивы?
миллион- может и много, но даже 10000 не хочет объявляться.
Кто и какаую ошибку дает ? Какой компилятор-линкер использованы ? Сколько реально памяти в системе и как она разбита на секции ?
Метценгерштейн
Aug 20 2014, 14:42
немного не уточнил. Проект под STM32F4 IAR.
компилится нормально. Но, вывод по USB через VCP отваливается, как только массив больше 100. Просто ком порт не появляется в списке и все. Хотя, компиляция проходит. Причем без разницы- массив локальный или глобальный.
То есть никаких ошибок линкера, на плате реально более 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 столько памяти прицепить реальной..
Метценгерштейн
Aug 20 2014, 16:52
про 4 гига я уже потом подумал

Но оно и в 1000 значений не работает. И да, скомпилилось как ни в чем ни бывало. Вот странно.
Буду пробовать советы.
Еще раз описание- задействован вывод printf в USB.
массив на 1000 int32_t компилится нормально, и на 10 000 тоже нормально. Но путем поиска выяснил, что работает только при значении массива не более 100.
Как не работает- в диспетчере устройств- порты СОМ- он просто там не появляется. Напомню, у меня VCP драйвер ои ST стоит.
ВРоде все описал.
DASM, за примеры спасибо, запомню где что.
toweroff, Ваш пример- как раз то, как библиотека STM32 регистры назначения обрабатывает- нашел сходство )
fatlortroll
Aug 21 2014, 12:01
Массив с изменяемыми данными, или с константами? Насколько сильно отбирает ОЗУ остальная программа? Если добавить-убрать глобальных переменных, расположенных в ОЗУ, размер массива, с которого появляется ошибка, будет изменяться?
Метценгерштейн
Aug 21 2014, 18:51
массив заполняется результатом измерений- т.е. не константа.
Остальная программа- это работа с USB. Точно не знаю сколько. Тоже что-то ест.
fatlortroll
Aug 22 2014, 06:04
А в прошивке используется выделение памяти на куче (операторы new, new[]), или всё статически на этапе компиляции задаётся?
Метценгерштейн
Aug 28 2014, 17:20
опять наступаю на подобные грабли.
принимаю данные в массив от визнета.
как только размер массива задаю >50, сразу что-то не так в исполнении программы. Хотя, компилится без проблем.
uint8_t recv_IP[500];
объявлен как глобальный.
Получается, что он в ОЗУ объявляется? Массив меньше 1 Кб. ОЗУ же 192 с чем-то Кб.
Почему так? Должно же нормально объявляться? ОЗУ ему достаточно ведь для размещения массива?
Dejmos
Aug 28 2014, 23:23
А какой размер CSTACK в настройках стоит?
Метценгерштейн
Aug 29 2014, 09:44
вроде вот- по умолчанию
http://c2n.me/iOOyiXтолько не на стеке же должен был выделиться?
Dejmos
Aug 29 2014, 16:26
Ну есть предположение что размера CSTACK не хватает, а т.к. его переполнение при работе не проверяется, то оно может портить память (было такое пару раз в IAR AVR).
Ну память явно чем-то портится, но вот чем? Можно для теста увеличить CSTACK раз в несколько и посмотреть что будет (хотя 0x2000 должно хватать, но мало ли). Если не оно, то значит портится в каком-то другом месте.
Метценгерштейн
Aug 29 2014, 17:21
0х2000- это 8 кб памяти.
Вопрос в другом- как ловить-то?
да и массив ведь не на стеке объявляется же
Dejmos
Aug 29 2014, 18:18
Массив не на стеке, но стек может переполниться чем-то еще и затереть не относящуюся к нему область RAM. С 8кб маловероятно, но лучше проверить... это будет проверить проще всего.
С остальным - хз, не встречал еще инструментария, которым можно отследить обращения к конкретной области памяти. Тут импровизировать надо: Выяснять в какой момент и какими модулями портится эта память (не в момент же записи там данные бьются).
Lagman
Aug 29 2014, 19:46
Цитата(Метценгерштейн @ Aug 28 2014, 21:20)

...
как только размер массива задаю >50, сразу что-то не так в исполнении программы. Хотя, компилится без проблем.
uint8_t recv_IP[500];
объявлен как глобальный.
...
А как Вы туда данные кладете через указатель или по индексу массива?
Метценгерштейн
Aug 29 2014, 21:34
передаю массив в ф-ю. т.е. адрес его.
проверил и со стеком 0х8000 - результат тот же
массив на 32- работает, на 500- вылетает
Метценгерштейн
Aug 30 2014, 18:36
пересобрал проект в Кейл- эффект такой же. Т.е., скорее, это не ошибка или глюк компилятора. Буду копать.
Нашел ошибку свою- обнулял массив переменной uint8_t, а задавал большой массив на 300.
Но еще глюки вылавливаю.
Не лишним было узнать- где он выделяется.
gerber
Aug 31 2014, 11:00
Цитата(Метценгерштейн @ Aug 30 2014, 22:36)

Не лишним было узнать- где он выделяется.
А ведь есть map-файл ...
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.