diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/cortex-m/ec.lds.S | 29 | ||||
-rw-r--r-- | core/cortex-m/task.c | 42 |
2 files changed, 42 insertions, 29 deletions
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S index 18d8fe6dc8..4eee36f763 100644 --- a/core/cortex-m/ec.lds.S +++ b/core/cortex-m/ec.lds.S @@ -96,11 +96,21 @@ SECTIONS #endif #ifdef COMPILE_FOR_RAM } > IRAM - __ro_end = . ; - .data : { #else } > FLASH +#endif __ro_end = . ; + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss.tasks) + *(.bss) + . = ALIGN(4); + __bss_end = .; + } > IRAM +#ifdef COMPILE_FOR_RAM + .data : { +#else .data : AT(ADDR(.rodata) + SIZEOF(.rodata)) { #endif . = ALIGN(4); @@ -111,6 +121,10 @@ SECTIONS *(.iram.text) . = ALIGN(4); __data_end = .; + + /* Shared memory buffer must be at the end of preallocated RAM, so it + * can expand to use all the remaining RAM. */ + __shared_mem_buf = .; } > IRAM /* The linker won't notice if the .data section is too big to fit, * apparently because we're sending it into IRAM, not FLASH. The following @@ -127,17 +141,6 @@ SECTIONS *(.google) } #endif - .bss : { - . = ALIGN(4); - __bss_start = .; - *(.bss) - . = ALIGN(4); - __bss_end = .; - - /* Shared memory buffer must be at the end of preallocated RAM, so it - * can expand to use all the remaining RAM. */ - __shared_mem_buf = .; - } > IRAM /DISCARD/ : { *(.ARM.*) } } diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index 3041f431c8..4bd194bd78 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -33,9 +33,6 @@ typedef union { uint32_t context[TASK_SIZE/4]; } task_; -#define CONTEXT_SP (__builtin_offsetof(task_, sp) / sizeof(uint32_t)) -#define CONTEXT_GUARD (__builtin_offsetof(task_, guard) / sizeof(uint32_t)) - /* declare task routine prototypes */ #define TASK(n, r, d) int r(void *); #include TASK_LIST @@ -94,24 +91,23 @@ static void task_exit_trap(void) #define GUARD_VALUE 0x12345678 -/* Declare and fill the contexts for all tasks. Note that while it would be - * more readable to use the struct fields (.sp, .guard) where applicable, gcc - * can't mix initializing some fields on one side of the union and some fields - * on the other, so we have to use .context for all initialization. */ -#define TASK(n, r, d) { \ - .context[CONTEXT_SP] = (uint32_t)(tasks + TASK_ID_##n + 1) - 64,\ - .context[CONTEXT_GUARD] = GUARD_VALUE, \ - .context[TASK_SIZE/4 - 8/*r0*/] = (uint32_t)d, \ - .context[TASK_SIZE/4 - 3/*lr*/] = (uint32_t)task_exit_trap, \ - .context[TASK_SIZE/4 - 2/*pc*/] = (uint32_t)r, \ - .context[TASK_SIZE/4 - 1/*psr*/] = 0x01000000 }, +/* Startup parameters for all tasks. */ +#define TASK(n, r, d) { \ + .r0 = (uint32_t)d, \ + .pc = (uint32_t)r, \ +}, #include TASK_LIST -static task_ tasks[] __attribute__((section(".data.tasks"))) - __attribute__((aligned(TASK_SIZE))) = { +static const struct { + uint32_t r0; + uint32_t pc; +} const tasks_init[] = { TASK(IDLE, __idle, 0) CONFIG_TASK_LIST }; #undef TASK +/* Contexts and stacks for all tasks. */ +static task_ tasks[TASK_ID_COUNT] __attribute__((section(".bss.tasks"))) + __attribute__((aligned(TASK_SIZE))); /* Reserve space to discard context on first context switch. */ uint32_t scratchpad[17] __attribute__((section(".data.tasks"))); @@ -561,6 +557,20 @@ DECLARE_CONSOLE_COMMAND(taskready, command_task_ready); int task_pre_init(void) { + int i; + + /* fill the task memory with initial values */ + for (i = 0; i < TASK_ID_COUNT; i++) { + tasks[i].sp = (uint32_t)(tasks + i + 1) - 64; + tasks[i].guard = GUARD_VALUE; + /* initial context on stack */ + tasks[i].context[TASK_SIZE/4 - 8/*r0*/] = tasks_init[i].r0; + tasks[i].context[TASK_SIZE/4 - 3/*lr*/] = + (uint32_t)task_exit_trap; + tasks[i].context[TASK_SIZE/4 - 2/*pc*/] = tasks_init[i].pc; + tasks[i].context[TASK_SIZE/4 - 1/*psr*/] = 0x01000000; + } + /* Fill in guard value in scratchpad to prevent stack overflow * detection failure on the first context switch. */ ((task_ *)scratchpad)->guard = GUARD_VALUE; |