diff options
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 7 | ||||
-rw-r--r-- | nuttx/Documentation/NuttxPortingGuide.html | 23 | ||||
-rw-r--r-- | nuttx/include/sched.h | 2 | ||||
-rw-r--r-- | nuttx/sched/os_bringup.c | 12 | ||||
-rw-r--r-- | nuttx/sched/os_internal.h | 20 | ||||
-rw-r--r-- | nuttx/sched/os_start.c | 1 | ||||
-rw-r--r-- | nuttx/sched/pthread_create.c | 10 | ||||
-rw-r--r-- | nuttx/sched/task_create.c | 170 | ||||
-rw-r--r-- | nuttx/sched/task_setup.c | 3 |
9 files changed, 180 insertions, 68 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 5ad9eaaf0..479a5c529 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1657,10 +1657,5 @@ (usually called current_regs) should be marked volatile; Added general capability to support nested interrupts (not fully realized for all architectures). - - - - - - + * sched/task_create.c: Add support for starting kernel-mode thread. diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index 5efc76e6c..b55dc6fd9 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@ <h1><big><font color="#3c34ec"> <i>NuttX RTOS Porting Guide</i> </font></big></h1> - <p>Last Updated: April 6, 2011</p> + <p>Last Updated: April 7, 2011</p> </td> </tr> </table> @@ -1217,14 +1217,23 @@ The system can be re-made subsequently by just typing <code>make</code>. <p><b>Prototype</b>: <code>void up_initial_state(FAR _TCB *tcb);</code></p> <p><b>Description</b>. - A new thread is being started and a new TCB - has been created. This function is called to initialize - the processor specific portions of the new TCB. + A new thread is being started and a new TCB has been created. + This function is called to initialize the processor specific portions of the new TCB. </p> <p> - This function must setup the initial architecture registers - and/or stack so that execution will begin at tcb->start - on the next context switch. + This function must setup the initial architecture registers and/or stack so that execution + will begin at tcb->start on the next context switch. +</p> +<p> + This function may also need to set up processor registers so that the new thread executes + with the correct privileges. + If <code>CONFIG_NUTTX_KERNEL</code> has been selected in the NuttX configuration, + then special initialization may need to be performed depending on the task type specified + in the TCB's flags field: + Kernel threads will require kernel-mode privileges; + User tasks and pthreads should have only user-mode privileges. + If <code>CONFIG_NUTTX_KERNEL</code> has <i>not</i> been selected, + then all threads should have kernel-mode privileges. </p> <h3><a name="upcreatestack">4.1.4 <code>up_create_stack()</code></a></h3> diff --git a/nuttx/include/sched.h b/nuttx/include/sched.h index 72c860f0d..aa1103bde 100644 --- a/nuttx/include/sched.h +++ b/nuttx/include/sched.h @@ -67,7 +67,7 @@ /* One processor family supported by NuttX has a single, fixed hardware stack. * That is the 8051 family. So for that family only, there is a variant form * of task_create() that does not take a stack size parameter. The following - * helper macro is provided to work around the ugliness of that exception. + * helper macros are provided to work around the ugliness of that exception. */ #ifndef CONFIG_CUSTOM_STACK diff --git a/nuttx/sched/os_bringup.c b/nuttx/sched/os_bringup.c index 84971ad6c..9f05a3c70 100644 --- a/nuttx/sched/os_bringup.c +++ b/nuttx/sched/os_bringup.c @@ -141,9 +141,9 @@ int os_bringup(void) #ifdef CONFIG_PAGING svdbg("Starting paging thread\n"); - g_pgworker = TASK_CREATE("pgfill", CONFIG_PAGING_DEFPRIO, - CONFIG_PAGING_STACKSIZE, - (main_t)pg_worker, (const char **)NULL); + g_pgworker = KERNEL_THREAD("pgfill", CONFIG_PAGING_DEFPRIO, + CONFIG_PAGING_STACKSIZE, + (main_t)pg_worker, (const char **)NULL); ASSERT(g_pgworker != ERROR); #endif @@ -152,9 +152,9 @@ int os_bringup(void) #ifdef CONFIG_SCHED_WORKQUEUE svdbg("Starting worker thread\n"); - g_worker = TASK_CREATE("work", CONFIG_SCHED_WORKPRIORITY, - CONFIG_SCHED_WORKSTACKSIZE, - (main_t)work_thread, (const char **)NULL); + g_worker = KERNEL_THREAD("work", CONFIG_SCHED_WORKPRIORITY, + CONFIG_SCHED_WORKSTACKSIZE, + (main_t)work_thread, (const char **)NULL); ASSERT(g_worker != ERROR); #endif diff --git a/nuttx/sched/os_internal.h b/nuttx/sched/os_internal.h index 8cd7257b4..ceeb70df1 100644 --- a/nuttx/sched/os_internal.h +++ b/nuttx/sched/os_internal.h @@ -106,6 +106,18 @@ enum os_crash_codes_e # define sched_releasefiles(t) (OK) #endif +/* One processor family supported by NuttX has a single, fixed hardware stack. + * That is the 8051 family. So for that family only, there is a variant form + * of kernel_thread() that does not take a stack size parameter. The following + * helper macro is provided to work around the ugliness of that exception. + */ + +#ifndef CONFIG_CUSTOM_STACK +# define KERNEL_THREAD(n,p,s,e,a) task_create(n,p,s,e,a) +#else +# define KERNEL_THREAD(n,p,s,e,a) task_create(n,p,e,a) +#endif + /* A more efficient ways to access the errno */ #define SET_ERRNO(e) \ @@ -254,7 +266,13 @@ extern int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main); extern int task_argsetup(FAR _TCB *tcb, const char *name, const char *argv[]); extern int task_deletecurrent(void); - +#ifndef CONFIG_CUSTOM_STACK +extern int kernel_thread(const char *name, int priority, + int stack_size, main_t entry, const char *argv[]); +#else +extern int kernel_thread(const char *name, int priority, + main_t entry, const char *argv[]); +#endif extern bool sched_addreadytorun(FAR _TCB *rtrtcb); extern bool sched_removereadytorun(FAR _TCB *rtrtcb); extern bool sched_addprioritized(FAR _TCB *newTcb, DSEG dq_queue_t *list); diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c index da34ad895..412c24ebc 100644 --- a/nuttx/sched/os_start.c +++ b/nuttx/sched/os_start.c @@ -287,6 +287,7 @@ void os_start(void) /* Initialize the processor-specific portion of the TCB */ + g_idletcb.flags = TCB_FLAG_TTYPE_KERNEL; up_initial_state(&g_idletcb); /* Initialize the memory manager */ diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c index e247ce372..d51a5956b 100644 --- a/nuttx/sched/pthread_create.c +++ b/nuttx/sched/pthread_create.c @@ -340,6 +340,12 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, #endif } + /* Mark this task as a pthread (this setting will be needed in + * task_schedsetup() when up_initial_state() is called. + */ + + ptcb->flags |= TCB_FLAG_TTYPE_PTHREAD; + /* Initialize the task control block */ status = task_schedsetup(ptcb, priority, pthread_start, @@ -352,10 +358,6 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, return EBUSY; } - /* Mark this task as a pthread */ - - ptcb->flags |= TCB_FLAG_TTYPE_PTHREAD; - /* Configure the TCB for a pthread receiving on parameter * passed by value */ diff --git a/nuttx/sched/task_create.c b/nuttx/sched/task_create.c index 3965e61ef..23478c810 100644 --- a/nuttx/sched/task_create.c +++ b/nuttx/sched/task_create.c @@ -67,32 +67,21 @@ ****************************************************************************/ /**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: task_create + * Name: thread_create * * Description: - * This function creates and activates a new task with a - * specified priority and returns its system-assigned ID. - * - * The entry address entry is the address of the "main" - * function of the task. This function will be called once - * the C environment has been set up. The specified - * function will be called with four arguments. Should - * the specified routine return, a call to exit() will - * automatically be made. - * - * Note that four (and only four) arguments must be passed for - * the spawned functions. + * This function creates and activates a new thread of the specified type + * with a specified priority and returns its system-assigned ID. It is the + * internal, commn implementation of task_create() and kernel_thread(). See + * comments with task_create() for further information. * * Input Parameters: * name - Name of the new task + * type - Type of the new task * priority - Priority of the new task * stack_size - size (in bytes) of the stack needed * entry - Entry point of a new task @@ -105,40 +94,39 @@ * NULL. * * Return Value: - * Returns the non-zero process ID of the new task or - * ERROR if memory is insufficient or the task cannot be - * created (errno is not set). + * Returns the non-zero process ID of the new task or ERROR if memory is + * insufficient or the task cannot be created. The errno will be set to + * indicate the nature of the error (always ENOMEM). * ****************************************************************************/ #ifndef CONFIG_CUSTOM_STACK -int task_create(const char *name, int priority, - int stack_size, main_t entry, const char *argv[]) +static int thread_create(const char *name, uint8_t type, int priority, + int stack_size, main_t entry, const char **argv) #else -int task_create(const char *name, int priority, - main_t entry, const char *argv[]) +static int thread_create(const char *name, uint8_t type, int priority, + main_t entry, const char **argv) #endif { FAR _TCB *tcb; - int status; pid_t pid; + int ret; /* Allocate a TCB for the new task. */ tcb = (FAR _TCB*)kzalloc(sizeof(_TCB)); if (!tcb) { - errno = ENOMEM; - return ERROR; + goto errout; } /* Associate file descriptors with the new task */ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 - if (sched_setuptaskfiles(tcb) != OK) + ret = sched_setuptaskfiles(tcb); + if (ret != OK) { - sched_releasetcb(tcb); - return ERROR; + goto errout_with_tcb; } #endif @@ -149,21 +137,25 @@ int task_create(const char *name, int priority, /* Allocate the stack for the TCB */ #ifndef CONFIG_CUSTOM_STACK - status = up_create_stack(tcb, stack_size); - if (status != OK) + ret = up_create_stack(tcb, stack_size); + if (ret != OK) { - sched_releasetcb(tcb); - return ERROR; + goto errout_with_tcb; } #endif + /* Mark the type of this thread (this setting will be needed in + * task_schedsetup() when up_initial_state() is called. + */ + + tcb->flags |= type; + /* Initialize the task control block */ - status = task_schedsetup(tcb, priority, task_start, entry); - if (status != OK) + ret = task_schedsetup(tcb, priority, task_start, entry); + if (ret != OK) { - sched_releasetcb(tcb); - return ERROR; + goto errout_with_tcb; } /* Setup to pass parameters to the new task */ @@ -176,13 +168,107 @@ int task_create(const char *name, int priority, /* Activate the task */ - status = task_activate(tcb); - if (status != OK) + ret = task_activate(tcb); + if (ret != OK) { dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); - sched_releasetcb(tcb); - return ERROR; + goto errout_with_tcb; } return pid; + +errout_with_tcb: + sched_releasetcb(tcb); + +errout: + errno = ENOMEM; + return ERROR; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: task_create + * + * Description: + * This function creates and activates a new task with a + * specified priority and returns its system-assigned ID. + * + * The entry address entry is the address of the "main" + * function of the task. This function will be called once + * the C environment has been set up. The specified + * function will be called with four arguments. Should + * the specified routine return, a call to exit() will + * automatically be made. + * + * Note that four (and only four) arguments must be passed for + * the spawned functions. + * + * Input Parameters: + * name - Name of the new task + * priority - Priority of the new task + * stack_size - size (in bytes) of the stack needed + * entry - Entry point of a new task + * arg - A pointer to an array of input parameters. + * Up to CONFIG_MAX_TASK_ARG parameters may + * be provided. If fewer than CONFIG_MAX_TASK_ARG + * parameters are passed, the list should be + * terminated with a NULL argv[] value. + * If no parameters are required, argv may be + * NULL. + * + * Return Value: + * Returns the non-zero process ID of the new task or ERROR if memory is + * insufficient or the task cannot be created. The errno will be set to + * indicate the nature of the error (always ENOMEM). + * + ****************************************************************************/ + +#ifndef CONFIG_CUSTOM_STACK +int task_create(const char *name, int priority, + int stack_size, main_t entry, const char *argv[]) +#else +int task_create(const char *name, int priority, + main_t entry, const char *argv[]) +#endif +{ +#ifndef CONFIG_CUSTOM_STACK + return thread_create(name, TCB_FLAG_TTYPE_TASK, priority, stack_size, entry, argv); +#else + return thread_create(name, TCB_FLAG_TTYPE_TASK, priority, entry, argv); +#endif } + +/**************************************************************************** + * Name: kernel_thread + * + * Description: + * This function creates and activates a kernel thread task with kernel- + * mode privileges. It is identical to task_create() except that it + * configures the newly started thread to run in kernel model. + * + * Input Parameters: + * (same as task_create()) + * + * Return Value: + * (same as task_create()) + * + ****************************************************************************/ + +#ifndef CONFIG_CUSTOM_STACK +int kernel_thread(const char *name, int priority, + int stack_size, main_t entry, const char *argv[]) +#else +int kernel_thread(const char *name, int priority, + main_t entry, const char *argv[]) +#endif +{ +#ifndef CONFIG_CUSTOM_STACK + return thread_create(name, TCB_FLAG_TTYPE_KERNEL, priority, stack_size, entry, argv); +#else + return thread_create(name, TCB_FLAG_TTYPE_KERNEL, priority, entry, argv); +#endif +} + diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c index 217bdc892..9fdbf3d25 100644 --- a/nuttx/sched/task_setup.c +++ b/nuttx/sched/task_setup.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task_setup.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -202,6 +202,7 @@ static inline void task_dupdspace(FAR _TCB *tcb) * priority - Priority of the new task * entry - Entry point of a new task * main - Application start point of the new task + * type - Type of the new thread: task, pthread, or kernel thread * * Return Value: * OK on success; ERROR on failure. |