Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия Следующая версия Следующая версия справа и слева | ||
ob:o7:memory [2017/04/06 23:34] иван_денисов |
ob:o7:memory [2019/10/27 09:44] иван_денисов |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | ====== | + | ====== |
При выполнении команды **O7ARMv{6, | При выполнении команды **O7ARMv{6, | ||
Строка 9: | Строка 9: | ||
* таблица указателей, | * таблица указателей, | ||
- | Куча используется только при динамическом выделении памяти через команду NEW, и она заполняется снизу вверх. Для сборки мусора в куче надо вызывать команду **MicroGC0.Collect**. Количество выделенной динамической памяти доступно в переменной **MicroKernel0.allocated**, | + | Куча используется только при динамическом выделении памяти через команду |
Стек заполняет выделенную под него память сверху вниз. И когда этот объем полностью заполняется, | Стек заполняет выделенную под него память сверху вниз. И когда этот объем полностью заполняется, | ||
Строка 24: | Строка 24: | ||
Переполнение стека возможно обнаружить и более простым путем, сравнив **stkPos** с **MicroKernel0.heapLim**. Если он меньше, | Переполнение стека возможно обнаружить и более простым путем, сравнив **stkPos** с **MicroKernel0.heapLim**. Если он меньше, | ||
+ | |||
+ | ===== Тестирования сборщика мусора ===== | ||
+ | |||
+ | Александр Ширяев разработал модуль для тестирования сборщика мусора: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | MODULE TmpTestGC0; | ||
+ | |||
+ | (* | ||
+ | Alexander Shiryaev, 2019.10 | ||
+ | |||
+ | Dynamic memory (and garbage collection) test | ||
+ | |||
+ | Board: Nucleo-F446RE | ||
+ | PA2: UART TX | ||
+ | PA3: UART RX | ||
+ | PA5: LED | ||
+ | *) | ||
+ | |||
+ | IMPORT | ||
+ | SYSTEM, | ||
+ | ARMv7M := MicroARMv7M, | ||
+ | Traps := MicroARMv7MTraps, | ||
+ | Kernel := MicroKernel0, | ||
+ | GC := MicroGC0, | ||
+ | TPorts := MicroSTM32F4TPorts, | ||
+ | Pins := MicroSTM32F4Pins, | ||
+ | Sys := MicroSTM32F405System, | ||
+ | SysTick0 := DplaARMv7MSTM32SysTick0, | ||
+ | WWDG := MicroARMv7MSTM32F4WWDG; | ||
+ | |||
+ | CONST | ||
+ | enableLED = TRUE; | ||
+ | |||
+ | led0PinPort = Pins.A; | ||
+ | led0PinN = 5; | ||
+ | led0BSRR = Pins.GPIOABSRR; | ||
+ | |||
+ | freq0 = 128; (* Hz *) | ||
+ | |||
+ | TYPE | ||
+ | Operation = POINTER TO OperationDesc; | ||
+ | OperationDesc = RECORD | ||
+ | END; | ||
+ | Repeat = POINTER TO RepeatDesc; | ||
+ | RepeatDesc = RECORD (OperationDesc) | ||
+ | value: INTEGER | ||
+ | END; | ||
+ | End = POINTER TO EndDesc; | ||
+ | EndDesc = RECORD (OperationDesc) | ||
+ | END; | ||
+ | |||
+ | VAR | ||
+ | cnt0: INTEGER; | ||
+ | operations: | ||
+ | nOp: INTEGER; | ||
+ | port: TPorts.Port; | ||
+ | |||
+ | PROCEDURE LEDOn; | ||
+ | BEGIN | ||
+ | SYSTEM.PUT(led0BSRR, | ||
+ | END LEDOn; | ||
+ | |||
+ | PROCEDURE LEDOff; | ||
+ | BEGIN | ||
+ | SYSTEM.PUT(led0BSRR, | ||
+ | END LEDOff; | ||
+ | |||
+ | PROCEDURE InitOperations; | ||
+ | VAR i: INTEGER; | ||
+ | BEGIN | ||
+ | i := 0; | ||
+ | WHILE i < LEN(operations) DO | ||
+ | operations[i] := NIL; | ||
+ | INC(i) | ||
+ | END; | ||
+ | GC.Collect; | ||
+ | nOp := 0 | ||
+ | END InitOperations; | ||
+ | |||
+ | PROCEDURE AddRepeat (val: INTEGER); | ||
+ | VAR repeat: Repeat; | ||
+ | BEGIN | ||
+ | repeat := NIL; | ||
+ | NEW(repeat); | ||
+ | repeat.value := val; | ||
+ | operations[nOp] := repeat; | ||
+ | INC(nOp) | ||
+ | END AddRepeat; | ||
+ | |||
+ | PROCEDURE AddEnd; | ||
+ | VAR end: Repeat; | ||
+ | BEGIN | ||
+ | end := NIL; | ||
+ | NEW(end); | ||
+ | INC(nOp) | ||
+ | END AddEnd; | ||
+ | |||
+ | PROCEDURE PopulateOperations; | ||
+ | VAR i: INTEGER; | ||
+ | BEGIN | ||
+ | i := 0; | ||
+ | WHILE i < 10 DO | ||
+ | AddRepeat(i); | ||
+ | INC(i) | ||
+ | END; | ||
+ | i := 0; | ||
+ | WHILE i < 5 DO | ||
+ | AddEnd; | ||
+ | INC(i) | ||
+ | END | ||
+ | END PopulateOperations; | ||
+ | |||
+ | PROCEDURE Receive (id: CHAR; a: ARRAY OF CHAR; len: INTEGER); | ||
+ | VAR ok: BOOLEAN; | ||
+ | i: INTEGER; | ||
+ | BEGIN | ||
+ | IF id = 20X (* communication test *) THEN | ||
+ | TPorts.Send(port, | ||
+ | ELSIF id = 22X (* clear dynamic memory *) THEN | ||
+ | IF len = 0 THEN | ||
+ | InitOperations; | ||
+ | TPorts.Send(port, | ||
+ | END | ||
+ | ELSIF id = 24X (* populate dynamic memory *) THEN | ||
+ | IF len = 0 THEN | ||
+ | PopulateOperations; | ||
+ | TPorts.Send(port, | ||
+ | END | ||
+ | ELSIF id = 26X (* Kernel.allocated query *) THEN | ||
+ | IF len = 0 THEN | ||
+ | TPorts.Send(port, | ||
+ | END | ||
+ | ELSIF id = 28X (* TRAP test *) THEN | ||
+ | IF len = 0 THEN | ||
+ | ASSERT(FALSE) | ||
+ | END | ||
+ | ELSIF id = 2AX (* hangup test *) THEN | ||
+ | IF len = 0 THEN | ||
+ | REPEAT UNTIL FALSE | ||
+ | END | ||
+ | ELSIF id = 2CX (* multiple clear/ | ||
+ | IF len = 0 THEN | ||
+ | i := 1000; | ||
+ | REPEAT DEC(i); | ||
+ | InitOperations; | ||
+ | PopulateOperations; | ||
+ | WWDG.Update | ||
+ | UNTIL i = 0; | ||
+ | TPorts.Send(port, | ||
+ | END | ||
+ | END | ||
+ | END Receive; | ||
+ | |||
+ | PROCEDURE OnFreq0; | ||
+ | BEGIN | ||
+ | IF enableLED THEN | ||
+ | (* LED blink *) | ||
+ | INC(cnt0); | ||
+ | IF cnt0 MOD (freq0 DIV 4) = 0 THEN | ||
+ | LEDOn | ||
+ | ELSIF cnt0 MOD (freq0 DIV 4) = freq0 DIV 8 THEN | ||
+ | LEDOff | ||
+ | END | ||
+ | END; | ||
+ | |||
+ | WWDG.Update (* reset watchdog timer *) | ||
+ | END OnFreq0; | ||
+ | |||
+ | PROCEDURE MainLoop; | ||
+ | BEGIN | ||
+ | REPEAT | ||
+ | TPorts.Receive(port); | ||
+ | IF SysTick0.OnTimer() THEN | ||
+ | OnFreq0 | ||
+ | END; | ||
+ | ARMv7M.WFI | ||
+ | UNTIL FALSE | ||
+ | END MainLoop; | ||
+ | |||
+ | PROCEDURE Init; | ||
+ | VAR ok: BOOLEAN; | ||
+ | i: INTEGER; | ||
+ | |||
+ | PROCEDURE InitPort; | ||
+ | VAR p: TPorts.InitPar; | ||
+ | BEGIN | ||
+ | p.n := TPorts.USART2; | ||
+ | p.RXPinPort := Pins.A; | ||
+ | p.RXPinN := 3; | ||
+ | p.RXPinAF := Pins.AF7; | ||
+ | p.TXPinPort := Pins.A; | ||
+ | p.TXPinN := 2; | ||
+ | p.TXPinAF := Pins.AF7; | ||
+ | p.UCLK := Sys.PCLK1; | ||
+ | p.baud := 115200; | ||
+ | p.parity := TPorts.parityNone; | ||
+ | p.receive := Receive; | ||
+ | p.version1 := 1; | ||
+ | TPorts.Init(port, | ||
+ | END InitPort; | ||
+ | |||
+ | PROCEDURE InitLED; | ||
+ | BEGIN | ||
+ | Pins.Configure(led0PinPort, | ||
+ | Pins.output, | ||
+ | END InitLED; | ||
+ | |||
+ | BEGIN | ||
+ | InitPort; | ||
+ | IF enableLED THEN | ||
+ | InitLED; | ||
+ | END; | ||
+ | WWDG.Init(WWDG.WDGTBMax, | ||
+ | SysTick0.Init(Sys.HCLK, | ||
+ | |||
+ | IF Traps.trapFlag THEN Traps.ClearTrapFlag; | ||
+ | i := 3; | ||
+ | REPEAT DEC(i); | ||
+ | TPorts.Send(port, | ||
+ | UNTIL i = 0 | ||
+ | ELSE | ||
+ | i := 3; | ||
+ | REPEAT DEC(i); | ||
+ | TPorts.Send(port, | ||
+ | UNTIL i = 0 | ||
+ | END | ||
+ | END Init; | ||
+ | |||
+ | BEGIN | ||
+ | Init; | ||
+ | MainLoop | ||
+ | END TmpTestGC0. | ||
+ | |||
+ | O7ARMv7MLinker.Link STM32F446RE TmpTestGC0 | ||
---- | ---- | ||
Автор заметки: | Автор заметки: |