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

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


ob:o7:memory

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

ob:o7:memory [2018/11/30 01:13]
127.0.0.1 внешнее изменение
ob:o7:memory [2020/10/29 07:08]
Строка 1: Строка 1:
-====== Особенности работы с памятью ====== 
  
-При выполнении команды **O7ARMv{6,7}Linker.Link** в рабочий журнал будет выведено, сколько полученная программа потребляет ROM и RAM. Например, для программы из [[ob:o7:stm32f103|первого урока]] требуется 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 для аварийной остановки в случае переполнения стека. Про обработку аварийных остановок читайте [[http://obertone.ru/ob/o7/debug|заметку про отладку]]. 
- 
----- 
- 
-Автор заметки: [[http://iadenisov.ru|И.А. Денисов]] 
ob/o7/memory.txt · Последнее изменение: 2020/10/29 07:08 (внешнее изменение)