kernel: add support for switching to main thread without _Swap()
It's possible that an architecture needs a custom way of switching to the main() task, rather than using _Swap() with a dummy thread. Change-Id: I14e9bc67be35174ff16209bcea27b18a069ff754 Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
parent
8fcc7f69da
commit
296a234ddb
2 changed files with 25 additions and 3 deletions
|
@ -354,3 +354,12 @@ config HEAP_MEM_POOL_SIZE
|
||||||
heap memory pool is defined.
|
heap memory pool is defined.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config ARCH_HAS_CUSTOM_SWAP_TO_MAIN
|
||||||
|
bool
|
||||||
|
# hidden
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
It's possible that an architecture port cannot use _Swap() to swap to
|
||||||
|
the _main() thread, but instead must do something custom. It must
|
||||||
|
enable this option in that case.
|
||||||
|
|
|
@ -241,6 +241,9 @@ void __weak main(void)
|
||||||
*/
|
*/
|
||||||
static void prepare_multithreading(struct k_thread *dummy_thread)
|
static void prepare_multithreading(struct k_thread *dummy_thread)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
|
||||||
|
ARG_UNUSED(dummy_thread);
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Initialize the current execution thread to permit a level of
|
* Initialize the current execution thread to permit a level of
|
||||||
* debugging output if an exception should happen during nanokernel
|
* debugging output if an exception should happen during nanokernel
|
||||||
|
@ -257,6 +260,7 @@ static void prepare_multithreading(struct k_thread *dummy_thread)
|
||||||
*/
|
*/
|
||||||
dummy_thread->base.flags = K_ESSENTIAL;
|
dummy_thread->base.flags = K_ESSENTIAL;
|
||||||
dummy_thread->base.prio = K_PRIO_COOP(0);
|
dummy_thread->base.prio = K_PRIO_COOP(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* _kernel.ready_q is all zeroes */
|
/* _kernel.ready_q is all zeroes */
|
||||||
|
|
||||||
|
@ -298,6 +302,9 @@ static void prepare_multithreading(struct k_thread *dummy_thread)
|
||||||
|
|
||||||
static void switch_to_main_thread(void)
|
static void switch_to_main_thread(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
|
||||||
|
_arch_switch_to_main_thread(main_stack, MAIN_STACK_SIZE, _main);
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Context switch to main task (entry function is _main()): the
|
* Context switch to main task (entry function is _main()): the
|
||||||
* current fake thread is not on a wait queue or ready queue, so it
|
* current fake thread is not on a wait queue or ready queue, so it
|
||||||
|
@ -305,6 +312,7 @@ static void switch_to_main_thread(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_Swap(irq_lock());
|
_Swap(irq_lock());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_CANARIES
|
#ifdef CONFIG_STACK_CANARIES
|
||||||
|
@ -357,9 +365,14 @@ extern void *__stack_chk_guard;
|
||||||
*/
|
*/
|
||||||
FUNC_NORETURN void _Cstart(void)
|
FUNC_NORETURN void _Cstart(void)
|
||||||
{
|
{
|
||||||
/* floating point operations are NOT performed during nanokernel init */
|
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
|
||||||
|
void *dummy_thread = NULL;
|
||||||
|
#else
|
||||||
|
/* floating point is NOT used during nanokernel init */
|
||||||
|
|
||||||
char __stack dummy_thread[_K_THREAD_NO_FLOAT_SIZEOF];
|
char __stack dummy_stack[_K_THREAD_NO_FLOAT_SIZEOF];
|
||||||
|
void *dummy_thread = dummy_stack;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize nanokernel data structures. This step includes
|
* Initialize nanokernel data structures. This step includes
|
||||||
|
@ -367,7 +380,7 @@ FUNC_NORETURN void _Cstart(void)
|
||||||
* before the hardware initialization phase.
|
* before the hardware initialization phase.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
prepare_multithreading((struct k_thread *)&dummy_thread);
|
prepare_multithreading(dummy_thread);
|
||||||
|
|
||||||
/* Deprecated */
|
/* Deprecated */
|
||||||
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRIMARY);
|
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRIMARY);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue