diff options
-rw-r--r-- | include/kern/init.h | 7 | ||||
-rw-r--r-- | linker/linker_script.ld | 83 | ||||
-rw-r--r-- | src/kern/init.c | 97 | ||||
-rw-r--r-- | src/kern/main.c | 105 |
4 files changed, 159 insertions, 133 deletions
diff --git a/include/kern/init.h b/include/kern/init.h index 0ebbeac..7c40d19 100644 --- a/include/kern/init.h +++ b/include/kern/init.h @@ -64,6 +64,13 @@ void(*init7_ptr)() = init7fn; \ static void init7fn +#define entry_point(fn) \ + static __attribute((__section__(".entry_point"))) __attribute((__used__)) \ + struct { \ + uint32_t _unused; \ + uint32_t entry_point; \ + } c = { 0x2000c000, (uint32_t) &fn } + typedef enum { INIT_LEVEL_0, INIT_LEVEL_1, diff --git a/linker/linker_script.ld b/linker/linker_script.ld index ea6fc8a..8497768 100644 --- a/linker/linker_script.ld +++ b/linker/linker_script.ld @@ -8,66 +8,77 @@ MEMORY SECTIONS { /* This is where the code goes. */ - WAT = ORIGIN(flash); . = ORIGIN(flash); - TEXT_START = .; .text ALIGN(0x04) : { + . = ALIGN(0x04); + VECTORS_START = .; *(.vectors); /* All .vector sections go here. */ - *(.text); /* All .text sections go here. */ - } >flash - TEXT_STOP = .; - . = ALIGN(0x04); - - .data : ALIGN(0x04) { - /* Data segment as defined in the flash. */ - INIT_DATA_VALUES = LOADADDR(.data); + VECTORS_END = .; - /* Data segment where it will be in memory. */ - . = ALIGN(0x04); - DATA_SEGMENT_START = .; - *(.data); - . = ALIGN(0x1c); - DATA_SEGMENT_STOP = .; + TEXT_START = .; + *(.text); /* All .text sections go here. */ + TEXT_END = .; - INIT_ROUTINES_FLASH_START = - LOADADDR(.data) + (DATA_SEGMENT_STOP - DATA_SEGMENT_START); + /* Start the init sections. The inits sections are text sections which are + * executed in order during startup. */ INITS_START = .; + INIT_0_START = .; *(.init0); - INIT_0_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_0_END = .; + INIT_1_START = .; *(.init1); - INIT_1_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_1_END = .; + INIT_2_START = .; *(.init2); - INIT_2_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_2_END = .; + INIT_3_START = .; *(.init3); - INIT_3_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_3_END = .; + INIT_4_START = .; *(.init4); - INIT_4_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_4_END = .; + INIT_5_START = .; *(.init5); - INIT_5_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_5_END = .; + INIT_6_START = .; *(.init6); - INIT_6_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_6_END = .; + INIT_7_START = .; *(.init7); - INIT_7_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START); + INIT_7_END = .; INITS_END = .; - INIT_ROUTINES_FLASH_STOP = - LOADADDR(.data) + (INITS_END - DATA_SEGMENT_START); + FLASH_STOP = .; + } >flash AT >flash + + /* Data segment as defined in the flash. */ + DATA_VALUES_IN_FLASH = LOADADDR(.data); + + .data : ALIGN(0x04) { + + /* Data segment where it will be in memory. */ + . = ALIGN(0x04); + DATA_SEGMENT_START = .; + *(.data); + DATA_SEGMENT_STOP = .; /* Align by 4 so we can optimize the copier to use uint32's. */ . = ALIGN(0x04); *(.noinit); - } >sram1 AT>flash + } >sram2 AT>flash - . = ALIGN(0x04); - BSS_START = .; - .bss : { + .bss : ALIGN(0x04){ + . = ALIGN(0x04); + BSS_START = .; *(.bss); . = ALIGN(0x04); - } > sram1 - BSS_END = .; + BSS_END = .; + } > sram2 - HEAP_START = .; - HEAP_STOP = ORIGIN(sram1) + LENGTH(sram1); + .heap : ALIGN(0x04) { + HEAP_START = .; + HEAP_STOP = ABSOLUTE(ORIGIN(sram1) + LENGTH(sram1)); + } > sram1 } diff --git a/src/kern/init.c b/src/kern/init.c index 550fea0..0267b7b 100644 --- a/src/kern/init.c +++ b/src/kern/init.c @@ -18,16 +18,15 @@ int main(); /* These are defined in the linker script. */ #ifdef ARCH_STM32L4 -extern uint32_t INIT_DATA_VALUES; + +extern uint32_t DATA_VALUES_IN_FLASH; extern uint32_t DATA_SEGMENT_START; extern uint32_t DATA_SEGMENT_STOP; -extern uint32_t TEXT_START; -extern uint32_t TEXT_STOP; extern uint32_t BSS_START; extern uint32_t BSS_END; -extern void (*INIT_ROUTINES_FLASH_START)(); -extern void (*INIT_ROUTINES_FLASH_STOP)(); +extern void (*INITS_START)(); +extern void (*INITS_END)(); extern uint32_t INIT_0_END; extern uint32_t INIT_1_END; @@ -38,19 +37,27 @@ extern uint32_t INIT_5_END; extern uint32_t INIT_6_END; extern uint32_t INIT_7_END; -extern uint32_t WAT; - -#define MAGIC_COOKIE 0xDEADBEEF -/* Test that data segment is properly set. */ -static uint32_t magic_cookie = MAGIC_COOKIE; +extern uint32_t INIT_0_START; +extern uint32_t INIT_1_START; +extern uint32_t INIT_2_START; +extern uint32_t INIT_3_START; +extern uint32_t INIT_4_START; +extern uint32_t INIT_5_START; +extern uint32_t INIT_6_START; +extern uint32_t INIT_7_START; + +extern uint32_t VECTORS_START; +extern uint32_t VECTORS_END; +extern uint32_t TEXT_START; +extern uint32_t TEXT_END; -void panic(const char*); +extern uint32_t FLASH_STOP; init2() { volatile uint32_t bss_start_ptr = (uint32_t)&BSS_START; volatile uint32_t bss_end_ptr = (uint32_t)&BSS_END; - volatile uint32_t init_data_values_ptr = (uint32_t)&INIT_DATA_VALUES; + volatile uint32_t init_data_values_ptr = (uint32_t)&DATA_VALUES_IN_FLASH; volatile uint32_t data_segment_start_ptr = (uint32_t)&DATA_SEGMENT_START; volatile uint32_t data_segment_stop_ptr = (uint32_t)&DATA_SEGMENT_STOP; @@ -58,7 +65,7 @@ init2() klogf(" .data ...\n"); klogf(" set (%p - %p)\n", &DATA_SEGMENT_START, &DATA_SEGMENT_STOP); - klogf(" from (%p)\n", &INIT_DATA_VALUES); + klogf(" from (%p)\n", &DATA_VALUES_IN_FLASH); if ((data_segment_start_ptr | data_segment_start_ptr) & 3) { panic(".data segment not aligned with sizeof(uint32_t)!\n"); @@ -72,7 +79,7 @@ init2() uint32_t* src; uint32_t* dest; - src = &INIT_DATA_VALUES; + src = &DATA_VALUES_IN_FLASH; dest = &DATA_SEGMENT_START; /* Copy the values from flash into the data segment. */ @@ -94,11 +101,6 @@ init2() *(dest++) = 0; } - if (magic_cookie != MAGIC_COOKIE) { - panic("Data Segment Initialization Failed!"); - } - - klogf("Magic Cookie Matches!\n"); klogf("Done!\n"); } @@ -106,11 +108,23 @@ init3() { /* Set the vector offset table to be at the start * of FLASH memory. */ - SCB.vto_r = 0x08000000; + SCB.vto_r = (uint32_t) &VECTORS_START; + + klogf("Vector offset table set to %p\n", &VECTORS_START); } void run_init_routines() { + void* init_starts[] = { + &INIT_0_START, + &INIT_1_START, + &INIT_2_START, + &INIT_3_START, + &INIT_4_START, + &INIT_5_START, + &INIT_6_START, + &INIT_7_START, + }; void* init_boundaries[] = { &INIT_0_END, &INIT_1_END, @@ -124,55 +138,40 @@ void run_init_routines() void (**initfn)(); - klogf("WAT: %p\n", &WAT); + klogf(".vectors:\n at (%p - %p)\n", &VECTORS_START, &VECTORS_END); + klogf(".text:\n at (%p - %p)\n", &TEXT_START, &TEXT_END); - klogf( - "Init routines at (%p - %p)\n", - &INIT_ROUTINES_FLASH_START, - &INIT_ROUTINES_FLASH_STOP); + klogf("inits: (%p - %p)\n", &INITS_START, &INIT_7_END); + + for (size_t i = 0; i < 8; ++i) { + klogf(".init%d\n at (%p - %p)\n", i, init_starts[i], init_boundaries[i]); + } klogf( - "Data segment at (%p - %p) from (%p)\n", + ".data:\n at (%p - %p)\n from (%p)\n", &DATA_SEGMENT_START, &DATA_SEGMENT_STOP, - &INIT_DATA_VALUES); + &DATA_VALUES_IN_FLASH); klogf( - "Bss segment at (%p - %p)\n", - &BSS_START, - &BSS_END); - - klogf( - "Heap at (%p - %p)\n", + ".heap:\n at (%p - %p) size %d bytes\n", &HEAP_START, - &HEAP_STOP); - - klogf( - "Text at (%p - %p)\n", - &TEXT_START, - &TEXT_STOP); - - klogf( "Init Boundary 0: %p\n", &INIT_0_END); - klogf( "Init Boundary 1: %p\n", &INIT_1_END); - klogf( "Init Boundary 2: %p\n", &INIT_2_END); + &HEAP_STOP, + (uint32_t)(&HEAP_STOP - &HEAP_START)); - // for (size_t i = 0; i < sizeof(init_boundaries) / sizeof(void*); ++ i) { - // klogf("Init Boundary %d at %p\n", i, init_boundaries[i]); - // } + klogf(".bss:\n at (%p - %p)\n", &BSS_START, &BSS_END); /* Enable a higher clock speed. This is the first thing we do * beacuse it will boost the boot up time. */ set_system_clock_MHz(80); klogf("[Init Level 0]\n"); - for (initfn = &INIT_ROUTINES_FLASH_START; initfn < &INIT_ROUTINES_FLASH_STOP; - ++initfn) { + for (initfn = &INITS_START; initfn < &INITS_END; ++initfn) { while (initfn >= init_boundaries[initlevel] && initlevel < INIT_LEVEL_7) { ++initlevel; klogf("[Init Level %d]\n", initlevel); } - klogf("Calling (%p)\n", initfn); (*initfn)(); } } diff --git a/src/kern/main.c b/src/kern/main.c index 61e60c9..7c0b65d 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -35,7 +35,7 @@ volatile struct { signed int timetick; ws2812b_t* drv; uint8_t brightness; - uint8_t n_leds; + uint16_t n_leds; uint8_t off; uint8_t n_snow; uint8_t n_red; @@ -201,7 +201,8 @@ static void reset_state() memset((void*)&state, 0, sizeof(state)); state.drv = tmp; state.brightness = 255; - state.n_leds = 250; + state.n_leds = 300; + state.n_red = 100; state.off = 8; state.timetick = 10; state.power = 1; @@ -211,52 +212,60 @@ static void reset_state() /* Main function. This gets executed from the interrupt vector defined above. */ int main() { - klogf("Entering Main (%p).\n", main); - - // systick_add_callback(on_systick, NULL); - // enable_systick(10000); - // configure_gpio(); - - // ir_begin_listen(); - // enable_ir_control(); - - // add_ir_code_callback(RC_HIGH, printit, "RC_HIGH"); - // add_ir_code_callback(RC_TEMP_UP, timetick_up, NULL); - // add_ir_code_callback(RC_DRY, set_red, NULL); - // add_ir_code_callback(RC_LOW, printit, "RC_LOW"); - // add_ir_code_callback(RC_TEMP_DOWN, timetick_down, NULL); - // add_ir_code_callback(RC_COOL, toggle_cool, NULL); - // add_ir_code_callback(RC_CONTINUOUS, set_snow, "RC_CONTINUOUS"); - // add_ir_code_callback(RC_FAN, toggle_brightness, NULL); - // add_ir_code_callback(RC_SLEEP, toggle_sleep, NULL); - // add_ir_code_callback(RC_UNITS, printit, "RC_UNITS"); - // add_ir_code_callback(RC_TIMER, reset_state, NULL); - // add_ir_code_callback(RC_POWER, toggle_power, NULL); - - // int ec; - // state.drv = ws2812b_new(SPI_SELECT_SPI1, &ec); - - // if (ec || !state.drv) { - // panic("Unable to create WS2812b driver :( (%d)\n", ec); - // } - - // reset_state(); - - // for (int i = 0; i < state.n_leds; ++i) { - // /* Clear the LED strip. */ - // disable_all_interrupts(); - // ws2812b_write_rgb_sync(state.drv, 0, 0, 0); - // enable_all_interrupts(); - // } - // ws2812b_latch(state.drv); - - // for (;;) { - // // while (!do_redraw) - // // ; - // // do_redraw = 0; - // if (!state.sleep) redraw(); - // } - for (;;); + klogf("Entering Main\n"); + + gpio_reserved_pin_t pin3 = get_sysled(); + + systick_add_callback(on_systick, NULL); + enable_systick(10000); + configure_gpio(); + + ir_begin_listen(); + enable_ir_control(); + + add_ir_code_callback(RC_HIGH, printit, "RC_HIGH"); + add_ir_code_callback(RC_TEMP_UP, timetick_up, NULL); + add_ir_code_callback(RC_DRY, set_red, NULL); + add_ir_code_callback(RC_LOW, printit, "RC_LOW"); + add_ir_code_callback(RC_TEMP_DOWN, timetick_down, NULL); + add_ir_code_callback(RC_COOL, toggle_cool, NULL); + add_ir_code_callback(RC_CONTINUOUS, set_snow, "RC_CONTINUOUS"); + add_ir_code_callback(RC_FAN, toggle_brightness, NULL); + add_ir_code_callback(RC_SLEEP, toggle_sleep, NULL); + add_ir_code_callback(RC_UNITS, printit, "RC_UNITS"); + add_ir_code_callback(RC_TIMER, reset_state, NULL); + add_ir_code_callback(RC_POWER, toggle_power, NULL); + + int ec; + state.drv = ws2812b_new(SPI_SELECT_SPI1, &ec); + + if (ec || !state.drv) { + panic("Unable to create WS2812b driver :( (%d)\n", ec); + } + + reset_state(); + + for (int i = 0; i < state.n_leds; ++i) { + /* Clear the LED strip. */ + disable_all_interrupts(); + ws2812b_write_rgb_sync(state.drv, 0, 0, 0); + enable_all_interrupts(); + } + ws2812b_latch(state.drv); + + for (int i = 0; ; ++ i) { + if (i % 64 == 0) { + set_gpio_pin_high(pin3); + } + // while (!do_redraw) + // ; + // do_redraw = 0; + if (!state.sleep) redraw(); + + if (i % 64 == 0) { + set_gpio_pin_low(pin3); + } + } } #endif |