unified: handle MDEF files that declare main()

Before, the kernel would run the main() function twice; first
as an entry in k_task_list, and then again from _main(). The
_main() invocation would be using a potentially insufficient stack
size.

Now if an MDEF file declares a main() thread, invoke it from
_main(), but honor the desired priority and stack size.

Issue: ZEP-1145
Change-Id: I1abf38fc038e270059589b11d96fae1b3f265208
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-10-28 12:45:05 -07:00 committed by Benjamin Walsh
commit f1c373c2d5
2 changed files with 48 additions and 6 deletions

View file

@ -21,6 +21,7 @@
* This module contains routines that are used to initialize the nanokernel.
*/
#include <zephyr.h>
#include <offsets.h>
#include <kernel.h>
#include <misc/printk.h>
@ -82,7 +83,18 @@ uint64_t __noinit __idle_tsc; /* timestamp when CPU goes idle */
#error "IDLE_STACK_SIZE must be a multiple of the stack alignment"
#endif
static char __noinit __stack main_stack[CONFIG_MAIN_STACK_SIZE];
/* Some projects may specify their main thread and parameters in the
* MDEF file. In this case, we need to use the stack size specified there
* and not in Kconfig
*/
#if defined(MDEF_MAIN_STACK_SIZE) && \
(MDEF_MAIN_STACK_SIZE > CONFIG_MAIN_STACK_SIZE)
#define MAIN_STACK_SIZE MDEF_MAIN_STACK_SIZE
#else
#define MAIN_STACK_SIZE CONFIG_MAIN_STACK_SIZE
#endif
static char __noinit __stack main_stack[MAIN_STACK_SIZE];
static char __noinit __stack idle_stack[IDLE_STACK_SIZE];
k_tid_t const _main_thread = (k_tid_t)main_stack;
@ -186,6 +198,14 @@ static void _main(void *unused1, void *unused2, void *unused3)
_main_thread->flags &= ~ESSENTIAL;
extern void main(void);
/* If we're going to load the MDEF main() in this context, we need
* to now set the priority to be what was specified in the MDEF file
*/
#if defined(MDEF_MAIN_THREAD_PRIORITY) && \
(MDEF_MAIN_THREAD_PRIORITY != CONFIG_MAIN_THREAD_PRIORITY)
k_thread_priority_set(_main_thread, MDEF_MAIN_THREAD_PRIORITY);
#endif
main();
}
@ -244,7 +264,7 @@ static void prepare_multithreading(struct k_thread *dummy_thread)
sys_dlist_init(&_nanokernel.ready_q.q[ii]);
}
_new_thread(main_stack, CONFIG_MAIN_STACK_SIZE, NULL,
_new_thread(main_stack, MAIN_STACK_SIZE, NULL,
_main, NULL, NULL, NULL,
CONFIG_MAIN_THREAD_PRIORITY, ESSENTIAL);
_mark_thread_as_started(_main_thread);

View file

@ -422,8 +422,14 @@ def kernel_main_c_tasks_unified():
kernel_main_c_out("\n")
for task in task_list:
entry = task[2]
if entry == "main":
# We will re-use existing main_thread
continue
kernel_main_c_out("EXTERN_C void %s(void *, void *, void *);\n" %
task[2])
entry)
# thread_init objects
@ -436,6 +442,10 @@ def kernel_main_c_tasks_unified():
entry = task[2]
stack_size = task[3]
if entry == "main":
# We will re-use existing main thread
continue
groups = get_group_bitmask(task[4])
params = (task[5], task[6], task[7])
@ -1201,14 +1211,26 @@ def generate_sysgen_h_obj_ids():
sysgen_h_data += "\n"
for task in task_list:
name = task[0];
prio = task[1]
entry = task[2]
stack_size = task[3]
if kernel_type == 'micro':
sysgen_h_data += \
"extern struct k_task _k_task_obj_%s;\n" % (name) + \
"#define %s ((ktask_t)&_k_task_obj_%s)\n" % (name, name)
elif (kernel_type == 'unified'):
sysgen_h_data += \
"extern char _k_thread_obj_%s[];\n" % (name) + \
"#define %s ((k_tid_t)_k_thread_obj_%s)\n" % (name, name)
if entry == "main":
# Special case: if the MDEF defines a main() thread,
# re-purpose the already existing main_thread for it.
sysgen_h_data += \
"#define MDEF_MAIN_STACK_SIZE %d\n" % stack_size
sysgen_h_data += \
"#define MDEF_MAIN_THREAD_PRIORITY %d\n" % prio
else:
sysgen_h_data += \
"extern char _k_thread_obj_%s[];\n" % (name) + \
"#define %s ((k_tid_t)_k_thread_obj_%s)\n" % (name, name)
# event object ids