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 <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2015-07-23 17:17:40 -07:00 committed by Anas Nashif
commit 75e5427e15
5 changed files with 49 additions and 31 deletions

View file

@ -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),)

View file

@ -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),)

View file

@ -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[];

View file

@ -42,6 +42,8 @@
#include <nano_private.h>
#include <start_task_arch.h>
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:

View file

@ -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) +
"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, (taskabortfunction)NULL},\n" % (entry, stack, size))
idx += 1
" %s, %s, %d,\n" % (entry, stack, size) +
" (taskabortfunction)NULL, NULL};\n")
kernel_main_c_out(" {NULL, NULL, %d, 0x00000000, " % (num_prios - 1) +
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, CONFIG_MAIN_STACK_SIZE, " +
"(taskabortfunction)NULL}\n")
kernel_main_c_out("};\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