diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-03-14 22:44:06 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-03-14 22:44:06 +0000 |
commit | 256ff9a480238dfd1d30b7dfb3d61835991b3ee7 (patch) | |
tree | 3c62d071240bc4d2f9df1cd127113b94d7fbf332 /nuttx/sched/task_start.c | |
parent | c601d953ae2de87bc41d3666f6b510805bf4e67b (diff) | |
download | px4-nuttx-256ff9a480238dfd1d30b7dfb3d61835991b3ee7.tar.gz px4-nuttx-256ff9a480238dfd1d30b7dfb3d61835991b3ee7.tar.bz2 px4-nuttx-256ff9a480238dfd1d30b7dfb3d61835991b3ee7.zip |
Switch to user-mode before starting a new task
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5742 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/sched/task_start.c')
-rw-r--r-- | nuttx/sched/task_start.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/nuttx/sched/task_start.c b/nuttx/sched/task_start.c index 8e012b515..e9667d486 100644 --- a/nuttx/sched/task_start.c +++ b/nuttx/sched/task_start.c @@ -43,10 +43,13 @@ #include <sched.h> #include <debug.h> +#include <nuttx/arch.h> +#include <nuttx/sched.h> + #include "os_internal.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** @@ -92,6 +95,7 @@ void task_start(void) { FAR struct task_tcb_s *tcb = (FAR struct task_tcb_s*)g_readytorun.head; + int exitcode; int argc; DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); @@ -117,9 +121,24 @@ void task_start(void) } } - /* Call the 'main' entry point passing argc and argv. If/when - * the task returns. + /* Call the 'main' entry point passing argc and argv. In the kernel build + * this has to be handled differently if we are starting a user-space task; + * we have to switch to user-mode before calling the task. */ - exit(tcb->cmn.entry.main(argc, tcb->argv)); +#ifdef CONFIG_NUTTX_KERNEL + if ((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) + { + up_task_start(tcb->cmn.entry.main, argc, tcb->argv); + exitcode = EXIT_FAILURE; /* Should not get here */ + } + else +#endif + { + exitcode = tcb->cmn.entry.main(argc, tcb->argv); + } + + /* Call exit() if/when the task returns */ + + exit(exitcode); } |