From 75e5427e1573a2ed94ea2b2d15fbad1e7cfda0aa Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 23 Jul 2015 17:17:40 -0700 Subject: [PATCH] microkernel: put _k_task_list into its own binary section The _k_task_list was a static array generated by sysgen, where it containing all pre-defined tasks from MDEF file. To support private task objects (aka, defining tasks within source files), the task list has to accommodate tasks that are not only processed through sysgen, but also those defined within source files. This is done by creating a new section in binary, and all task objects go into this section. By doing this, the task list can still be manipulated as an array, which is required for task group operation. Change-Id: I799d6967567079498bc414e0cb809e8af856b53e Signed-off-by: Daniel Leung --- include/arch/arm/CortexM/scripts/linker.cmd | 10 ++++ include/arch/x86/linker-common-sections.h | 10 ++++ kernel/microkernel/include/micro_private.h | 2 - kernel/microkernel/k_task.c | 5 +- scripts/sysgen | 53 ++++++++++----------- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/include/arch/arm/CortexM/scripts/linker.cmd b/include/arch/arm/CortexM/scripts/linker.cmd index 75a925c6821..6b175c4f0d8 100644 --- a/include/arch/arm/CortexM/scripts/linker.cmd +++ b/include/arch/arm/CortexM/scripts/linker.cmd @@ -192,6 +192,16 @@ SECTIONS __initconfig_end = .; } GROUP_LINK_IN(RAMABLE_REGION) + SECTION_PROLOGUE (_k_task_list, (OPTIONAL),) + { + _k_task_list_start = .; + *(._k_task_list.public.*) + _k_task_list_idle_start = .; + *(._k_task_list.idle.*) + KEEP(*(SORT_BY_NAME("._k_task_list*"))) + _k_task_list_end = .; + } GROUP_LINK_IN(RAMABLE_REGION) + __data_ram_end = .; SECTION_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) diff --git a/include/arch/x86/linker-common-sections.h b/include/arch/x86/linker-common-sections.h index d21df41e818..c687b55a66d 100644 --- a/include/arch/x86/linker-common-sections.h +++ b/include/arch/x86/linker-common-sections.h @@ -163,6 +163,16 @@ SECTIONS KEXEC_PGALIGN_PAD(MMU_PAGE_SIZE) } GROUP_LINK_IN(RAM) + SECTION_PROLOGUE (_k_task_list, (OPTIONAL),) + { + _k_task_list_start = .; + *(._k_task_list.public.*) + _k_task_list_idle_start = .; + *(._k_task_list.idle.*) + KEEP(*(SORT_BY_NAME("._k_task_list*"))) + _k_task_list_end = .; + } GROUP_LINK_IN(RAM) + __data_ram_end = .; SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD OPTIONAL),) diff --git a/kernel/microkernel/include/micro_private.h b/kernel/microkernel/include/micro_private.h index 712a71f54e5..ff18dcc6484 100644 --- a/kernel/microkernel/include/micro_private.h +++ b/kernel/microkernel/include/micro_private.h @@ -44,8 +44,6 @@ extern struct k_tqhd _k_task_priority_list[]; -extern int _k_task_count; - extern struct map_struct _k_mem_map_list[]; extern struct pool_struct _k_mem_pool_list[]; extern struct pipe_struct _k_pipe_list[]; diff --git a/kernel/microkernel/k_task.c b/kernel/microkernel/k_task.c index 6678b0f9044..e8b8ba32b83 100644 --- a/kernel/microkernel/k_task.c +++ b/kernel/microkernel/k_task.c @@ -42,6 +42,8 @@ #include #include +extern struct k_proc _k_task_list_start[]; +extern struct k_proc _k_task_list_end[]; /** * @@ -385,7 +387,6 @@ void _k_task_group_op(struct k_args *A) { ktask_group_t grp = A->Args.g1.group; int opt = A->Args.g1.opt; - int i; struct k_proc *X; #ifdef CONFIG_TASK_DEBUG @@ -395,7 +396,7 @@ void _k_task_group_op(struct k_args *A) _k_debug_halt = 0; #endif - for (i = 0, X = _k_task_list; i < _k_task_count; i++, X++) { + for (X = _k_task_list_start; X < _k_task_list_end; X++) { if (X->Group & grp) { switch (opt) { case TASK_GROUP_START: diff --git a/scripts/sysgen b/scripts/sysgen index a750e52df55..6a3aa0a6429 100755 --- a/scripts/sysgen +++ b/scripts/sysgen @@ -351,12 +351,6 @@ def kernel_main_c_tasks(): global num_prios - total_tasks = len(task_list) + 1 - - # task global variables - - kernel_main_c_out("\nint _k_task_count = %d;\n" % (total_tasks - 1)) - # task stack areas kernel_main_c_out("\n") @@ -373,15 +367,18 @@ def kernel_main_c_tasks(): kernel_main_c_out("extern void %s(void);\n" % task[2]) # task descriptors (including one for idle task) + # + # compiler puts these objects into the section as if + # it is a stack. hence the need to reverse the list. + # this is to preseve the order defined in MDEF file. - kernel_main_c_out("\n" + - "struct k_proc _k_task_list[%d] =\n" % (total_tasks) + - "{\n") - idx = 0 - for task in task_list: + kernel_main_c_out("\n") + for task in reversed(task_list): + name = task[0] prio = task[1] entry = task[2] size = task[3] + obj_name = "_k_task_obj_%s" % (name) stack = "__" + task[0] + "_stack" @@ -403,22 +400,26 @@ def kernel_main_c_tasks(): group_bitmask ^= group_dictionary['SYS'] kernel_main_c_out( - " {NULL, NULL, %d, (ktask_t)&_k_task_list[%d], " % (prio, idx) + - "0x00000001, %#010x,\n" % (group_bitmask) + - "%s, %s, %d, (taskabortfunction)NULL},\n" % (entry, stack, size)) - idx += 1 + "struct k_proc %s " % (obj_name)+ + "__section(_k_task_list, public, task) =\n" + + " {NULL, NULL, %d, (ktask_t)&%s,\n" % (prio, obj_name) + + " 0x00000001, %#010x,\n" % (group_bitmask) + + " %s, %s, %d,\n" % (entry, stack, size) + + " (taskabortfunction)NULL, NULL};\n") - kernel_main_c_out(" {NULL, NULL, %d, 0x00000000, " % (num_prios - 1) + - "0x00000000, 0x00000000,\n" + - "(taskstartfunction)NULL, main_task_stack, CONFIG_MAIN_STACK_SIZE, " + - "(taskabortfunction)NULL}\n") - kernel_main_c_out("};\n") + kernel_main_c_out( + "struct k_proc _k_task_idle " + + "__section(_k_task_list, idle, task) =\n" + + " {NULL, NULL, %d, 0x00000000,\n" % (num_prios - 1) + + " 0x00000000, 0x00000000,\n" + + " (taskstartfunction)NULL, main_task_stack,\n" + " CONFIG_MAIN_STACK_SIZE,\n" + + " (taskabortfunction)NULL, NULL};\n") # currently scheduled task (idle task) kernel_main_c_out("\n" + - "struct k_proc * _k_current_task = &_k_task_list[%d];\n" % - (total_tasks - 1)) + "struct k_proc * _k_current_task = &_k_task_idle;\n") def kernel_main_c_priorities(): @@ -438,8 +439,7 @@ def kernel_main_c_priorities(): " {NULL, (struct k_proc *)&_k_task_priority_list[%d]},\n" % (i - 1)) kernel_main_c_out( - " {&_k_task_list[%d], &_k_task_list[%d]}\n" % - (total_tasks - 1, total_tasks - 1) + + " {&_k_task_idle, &_k_task_idle}\n" + "};\n") # active priority queue (idle task's queue) @@ -943,13 +943,12 @@ def generate_zephyr_h_obj_ids(): # task object id - idx = 0 kernel_main_c_out("\n") for task in task_list: name = task[0]; zephyr_h_data += \ - "#define %s ((ktask_t)&_k_task_list[%d])\n" % (name, idx) - idx += 1 + "extern struct k_proc _k_task_obj_%s;\n" % (name) + \ + "#define %s ((ktask_t)&_k_task_obj_%s)\n" % (name, name) # all other object ids