Инструменты пользователя

Инструменты сайта


ob:o7:memory

Особенности работы с памятью

При выполнении команды O7ARMv{6,7}Linker.Link в рабочий журнал будет выведено, сколько полученная программа потребляет ROM и RAM. Например, для программы из первого урока требуется 880 байт ROM и 16 байт RAM.

Доступная память RAM используется под следующие ресурсы:

  • куча;
  • стек;
  • глобальные переменные;
  • таблица указателей, строки, таблица модулей.

Куча используется только при динамическом выделении памяти через команду NEW, и она заполняется снизу вверх. Для сборки мусора в куче надо вызывать команду MicroGC0.Collect. Количество выделенной динамической памяти доступно в переменной MicroKernel0.allocated, начало кучи — MicroKernel0.heapOrg, конец — MicroKernel0.heapLim. Следовательно общий размер легко вычислить как их разность.

Стек заполняет выделенную под него память сверху вниз. И когда этот объем полностью заполняется, он начинает расти поверх кучи. Поэтому большие переменные рекомендуется размещать либо глобально, либо в куче, выход за границы которой контролируется автоматически. При переполнении кучи указатель будет равен NIL после вызова NEW.

Размер памяти, выделяемой под стек, определяется константой StkSize в модуле System для конкретного контроллера. Например, для STM32F4 это 8192 байта, для STM32F103x{8,B} — 2048 байт. Это значение вы можете легко изменить исходя из требований вашего проекта. Если вы используете рекурсивные алгоритмы, то скорее всего вам потребуется зарезервировать больше места под стек.

Степень заполнение стека возможно вычислить, исходя из положения начала и его текущего положения:

SYSTEM.GET(SYSTEM.REG(MT), stkOrg); (* MT = 6 *)
SYSTEM.GET(SYSTEM.REG(SP), stkPos); (* SP = 13 *)
stkLen := stkOrg - stkPos;

Так возможно контролировать при отладке, не превышает ли stkLen значение StkSize

Переполнение стека возможно обнаружить и более простым путем, сравнив stkPos с MicroKernel0.heapLim. Если он меньше, значит стек уже начал писаться в область памяти, выделенной для кучи. Так возможно добавить ASSERT для аварийной остановки в случае переполнения стека. Про обработку аварийных остановок читайте заметку про отладку.


Автор заметки: И.А. Денисов

ob/o7/memory.txt · Последние изменения: 2017/04/06 23:34 — иван_денисов