Как я узнаю, когда моя память заполнится? - PullRequest
3 голосов
/ 10 ноября 2010

Я пишу прошивку для микроконтроллера Atmel XMEGA на языке c, и мне кажется, что я заполнил 4 КБ SRAM.Насколько я знаю, у меня есть только статические / глобальные данные и локальные переменные стека (я не использую malloc в моем коде).

Я использую локальную переменную для буферизации некоторого пикселяданные.Если я увеличу буфер до 51 байта, мой дисплей показывает странные результаты - буфер в 6 байтов работает нормально.Вот почему я думаю, что мой ОЗУ заполнен, а стек что-то перезаписывает.

Создание дополнительной свободной памяти - , а не моя проблема, потому что я могу просто переместить некоторые статические данные во флэш-память и загрузить толькоэто когда это нужно.Что меня беспокоит, так это то, что я никогда не мог обнаружить, что память переполнена.

Возможно ли как-то вывести (например, перезагрузить микроконтроллер), когда память заполнилась вместо того, чтобы позволить ей перезаписать какую-то другуюданные?

Ответы [ 4 ]

3 голосов
/ 10 ноября 2010

Может быть очень сложно предсказать, сколько именно стека вам понадобится (некоторые цепочки инструментов могут пойти на это, если вы включите правильные опции, но это только грубое руководство).

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

Код запуска вашей цепочки инструментов может даже иметь возможность заполнить стек для вас.

К сожалению, хотя концепции очень просты: заполните стек известным значением, подсчитайте количество оставшихся значений, для его реализации может потребоваться достаточно глубокое понимание того, как работают ваши конкретные инструменты (особенно запуск). код и компоновщик) работают.

Грубые способы проверить, является ли ваша проблема причиной переполнения стека, - сделать все ваши локальные массивы «статическими» и / или значительно увеличить размер стека, а затем посмотреть, работают ли они лучше. И то, и другое может быть трудно сделать в небольших встроенных системах.

1 голос
/ 10 ноября 2010

Обычно компоновщик отвечает за выделение памяти для кода, констант, статических данных, стеков и куч. Часто вы должны указать компоновщику требуемые размеры стека (и доступную память), который затем отметит ошибку, если он не может уместить все.

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

Если на вашем процессоре нет аппаратной проверки на переполнение стека (маловероятно), есть несколько приемов, которые вы можете использовать для мониторинга использования стека.

  • Заполните стопку известным шаблоном маркера и проверьте память стека (как выделено компоновщиком), чтобы определить, сколько маркера остается не поврежденным.
  • В случае прерывания по таймеру (или аналогичного) сравните указатель стека основного потока с основанием стека, чтобы проверить переполнение

Оба эти подхода полезны при отладке, но они не гарантированно перехватят все проблемы и, как правило, будут отмечать только проблему ПОСЛЕ того, как стек уже испортил что-то еще ...

1 голос
/ 10 ноября 2010

"Возможно ли как-то обмануться (например, перезагружая микроконтроллер), когда память заполнилась вместо позволить перезаписать некоторые другие данные? "

Полагаю, в настоящее время у вас есть отображение памяти, подобное (1). Когда размер стека и / или пространства переменных увеличивается, они сталкиваются и перезаписывают друг друга (*).

Другая возможность - отображение памяти, подобное (2). Когда размер стека или переменной превышает максимальное пространство, они попадают в не отображенное пространство адреса (*). В зависимости от контроллера (я не уверен в семействе AVR) это вызывает сброс / прерывание или подобное (= то, что вы хотели).

  [not mapped addr space][   RAM  mapped  addr  space   ][not mapped addr space] 
(1)                      [variables --->  *   <--- stack] 
(2)                     *[ <--- stack   variables --->  ]* 

(стрелки указывают направление роста, если используется больше переменной / стека)

Конечно, лучше заранее убедиться, что оперативная память достаточно велика.

0 голосов
/ 10 ноября 2010

Обычно ваш инструмент программирования знает параметры контроллера, поэтому вы должны быть предупреждены, если вы использовали больше (без mallocs, это известно во время компиляции).

Но вы должны быть осторожны с пиксельными данными, потому чтобольшинство дисплеев не имеют линейного адресного пространства.

РЕДАКТИРОВАТЬ: обычно вы можете указать размер стека вручную.Оставьте достаточно памяти для статических переменных, а оставшуюся часть оставьте для стека.

...