Skip to content

Commit ed378cd

Browse files
committed
stm: Tidy up memory labels; optimise GC root scanning.
Addresses issues adafruit#272 and adafruit#273.
1 parent d46ca25 commit ed378cd

6 files changed

Lines changed: 83 additions & 39 deletions

File tree

stm/gccollect.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,36 @@
88
#include "gccollect.h"
99
#include "systick.h"
1010

11-
void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
11+
machine_uint_t gc_helper_get_regs_and_sp(machine_uint_t *regs);
12+
13+
// obsolete
14+
// void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
1215

1316
void gc_collect(void) {
17+
// get current time, in case we want to time the GC
1418
uint32_t start = sys_tick_counter;
19+
20+
// start the GC
1521
gc_collect_start();
16-
gc_collect_root((void**)&_ram_start, ((uint32_t)&_heap_start - (uint32_t)&_ram_start) / sizeof(uint32_t));
22+
23+
// scan everything in RAM before the heap
24+
// this includes the data and bss segments
25+
// TODO possibly don't need to scan data, since all pointers should start out NULL and be in bss
26+
gc_collect_root((void**)&_ram_start, ((uint32_t)&_bss_end - (uint32_t)&_ram_start) / sizeof(uint32_t));
27+
28+
// get the registers and the sp
1729
machine_uint_t regs[10];
18-
gc_helper_get_regs_and_clean_stack(regs, (machine_uint_t)&_heap_end);
19-
gc_collect_root((void**)&_heap_end, ((uint32_t)&_ram_end - (uint32_t)&_heap_end) / sizeof(uint32_t)); // will trace regs since they now live in this function on the stack
30+
machine_uint_t sp = gc_helper_get_regs_and_sp(regs);
31+
32+
// trace the stack, including the registers (since they live on the stack in this function)
33+
gc_collect_root((void**)sp, ((uint32_t)&_ram_end - sp) / sizeof(uint32_t));
34+
35+
// end the GC
2036
gc_collect_end();
21-
uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
2237

2338
if (0) {
2439
// print GC info
40+
uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
2541
gc_info_t info;
2642
gc_info(&info);
2743
printf("GC@%lu %lums\n", start, ticks);

stm/gccollect.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
// variables defining memory layout
2+
// (these probably belong somewhere else...)
3+
extern uint32_t _text_end;
4+
extern uint32_t _data_start_init;
15
extern uint32_t _ram_start;
6+
extern uint32_t _data_start;
7+
extern uint32_t _data_end;
8+
extern uint32_t _bss_start;
9+
extern uint32_t _bss_end;
210
extern uint32_t _heap_start;
3-
extern uint32_t _ram_end;
411
extern uint32_t _heap_end;
12+
extern uint32_t _stack_end;
13+
extern uint32_t _ram_end;
514

615
void gc_collect(void);
716

stm/gchelper.s

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@
44
.text
55
.align 2
66

7+
@ uint gc_helper_get_regs_and_sp(r0=uint regs[10])
8+
.global gc_helper_get_regs_and_sp
9+
.thumb
10+
.thumb_func
11+
.type gc_helper_get_regs_and_sp, %function
12+
gc_helper_get_regs_and_sp:
13+
@ store registers into given array
14+
str r4, [r0], #4
15+
str r5, [r0], #4
16+
str r6, [r0], #4
17+
str r7, [r0], #4
18+
str r8, [r0], #4
19+
str r9, [r0], #4
20+
str r10, [r0], #4
21+
str r11, [r0], #4
22+
str r12, [r0], #4
23+
str r13, [r0], #4
24+
25+
@ return the sp
26+
mov r0, sp
27+
bx lr
28+
29+
30+
@ this next function is now obsolete
31+
32+
.size gc_helper_get_regs_and_clean_stack, .-gc_helper_get_regs_and_clean_stack
733
@ void gc_helper_get_regs_and_clean_stack(r0=uint regs[10], r1=heap_end)
834
.global gc_helper_get_regs_and_clean_stack
935
.thumb

stm/main.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,13 @@ static mp_obj_t pyb_info(void) {
171171

172172
// to print info about memory
173173
{
174-
extern void *_sidata;
175-
extern void *_sdata;
176-
extern void *_edata;
177-
extern void *_sbss;
178-
extern void *_ebss;
179-
extern void *_estack;
180-
extern void *_etext;
181-
printf("_etext=%p\n", &_etext);
182-
printf("_sidata=%p\n", &_sidata);
183-
printf("_sdata=%p\n", &_sdata);
184-
printf("_edata=%p\n", &_edata);
185-
printf("_sbss=%p\n", &_sbss);
186-
printf("_ebss=%p\n", &_ebss);
187-
printf("_estack=%p\n", &_estack);
174+
printf("_text_end=%p\n", &_text_end);
175+
printf("_data_start_init=%p\n", &_data_start_init);
176+
printf("_data_start=%p\n", &_data_start);
177+
printf("_data_end=%p\n", &_data_end);
178+
printf("_bss_start=%p\n", &_bss_start);
179+
printf("_bss_end=%p\n", &_bss_end);
180+
printf("_stack_end=%p\n", &_stack_end);
188181
printf("_ram_start=%p\n", &_ram_start);
189182
printf("_heap_start=%p\n", &_heap_start);
190183
printf("_heap_end=%p\n", &_heap_end);

stm/startup_stm32f40xx.s

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@
4747

4848
/* start address for the initialization values of the .data section.
4949
defined in linker script */
50-
.word _sidata
50+
.word _data_start_init
5151
/* start address for the .data section. defined in linker script */
52-
.word _sdata
52+
.word _data_start
5353
/* end address for the .data section. defined in linker script */
54-
.word _edata
54+
.word _data_end
5555
/* start address for the .bss section. defined in linker script */
56-
.word _sbss
56+
.word _bss_start
5757
/* end address for the .bss section. defined in linker script */
58-
.word _ebss
58+
.word _bss_end
5959
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
6060

6161
/**
@@ -90,9 +90,9 @@ LoopCopyDataInit:
9090
cmp r2, r3
9191
bcc CopyDataInit
9292
*/
93-
ldr r0, =_sidata @ source pointer
94-
ldr r1, =_sdata @ destination pointer
95-
ldr r2, =_edata @ maximum destination pointer
93+
ldr r0, =_data_start_init @ source pointer
94+
ldr r1, =_data_start @ destination pointer
95+
ldr r2, =_data_end @ maximum destination pointer
9696
b data_init_entry
9797
data_init_loop:
9898
ldr r3, [r0], #4
@@ -117,8 +117,8 @@ LoopFillZerobss:
117117
*/
118118

119119
movs r0, #0 @ source value
120-
ldr r1, =_sbss @ destination pointer
121-
ldr r2, =_ebss @ maximum destination pointer
120+
ldr r1, =_bss_start @ destination pointer
121+
ldr r2, =_bss_end @ maximum destination pointer
122122
b bss_init_entry
123123
bss_init_loop:
124124
str r0, [r1], #4
@@ -158,7 +158,7 @@ Infinite_Loop:
158158

159159

160160
g_pfnVectors:
161-
.word _estack
161+
.word _stack_end
162162
.word Reset_Handler
163163
.word NMI_Handler
164164
.word HardFault_Handler

stm/stm32f405.ld

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ _minimum_stack_size = 2K;
1717
_minimum_heap_size = 16K;
1818

1919
/* top end of the stack */
20-
_estack = ORIGIN(RAM) + LENGTH(RAM);
20+
_stack_end = ORIGIN(RAM) + LENGTH(RAM);
2121

2222
/* RAM extents for the garbage collector */
2323
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
@@ -47,8 +47,8 @@ SECTIONS
4747
/* *(.glue_7t) */ /* glue thumb to arm code */
4848

4949
. = ALIGN(4);
50-
_etext = .; /* define a global symbol at end of code */
51-
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
50+
_text_end = .; /* define a global symbol at end of code */
51+
_data_start_init = _text_end; /* This is used by the startup in order to initialize the .data secion */
5252
} >FLASH_TEXT
5353

5454
/*
@@ -69,29 +69,29 @@ SECTIONS
6969
The program executes knowing that the data is in the RAM
7070
but the loader puts the initial values in the FLASH (inidata).
7171
It is one task of the startup to copy the initial values from FLASH to RAM. */
72-
.data : AT ( _sidata )
72+
.data : AT ( _data_start_init )
7373
{
7474
. = ALIGN(4);
75-
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
75+
_data_start = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
7676
_ram_start = .; /* create a global symbol at ram start for garbage collector */
7777
*(.data) /* .data sections */
7878
*(.data*) /* .data* sections */
7979

8080
. = ALIGN(4);
81-
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
81+
_data_end = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
8282
} >RAM
8383

8484
/* Uninitialized data section */
8585
.bss :
8686
{
8787
. = ALIGN(4);
88-
_sbss = .; /* define a global symbol at bss start; used by startup code */
88+
_bss_start = .; /* define a global symbol at bss start; used by startup code */
8989
*(.bss)
9090
*(.bss*)
9191
*(COMMON)
9292

9393
. = ALIGN(4);
94-
_ebss = .; /* define a global symbol at bss end; used by startup code */
94+
_bss_end = .; /* define a global symbol at bss end; used by startup code and GC */
9595
} >RAM
9696

9797
/* this is to define the start of the heap, and make sure we have a minimum size */

0 commit comments

Comments
 (0)