summaryrefslogtreecommitdiff
path: root/nuttx/sched/init
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-08 15:30:59 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-08 15:30:59 -0600
commitb415d5f6e7f3bb0e4eca3c51d8a121a9ce4adcfc (patch)
treefb1eb4603a497ffcad2e2eae6e802363f5faca91 /nuttx/sched/init
parent0dc82c9ce3122c309e91981ed62a4d2a08744b86 (diff)
downloadnuttx-b415d5f6e7f3bb0e4eca3c51d8a121a9ce4adcfc.tar.gz
nuttx-b415d5f6e7f3bb0e4eca3c51d8a121a9ce4adcfc.tar.bz2
nuttx-b415d5f6e7f3bb0e4eca3c51d8a121a9ce4adcfc.zip
Move initialization functions from sched/ to sched/init
Diffstat (limited to 'nuttx/sched/init')
-rw-r--r--nuttx/sched/init/Make.defs41
-rw-r--r--nuttx/sched/init/init.h115
-rw-r--r--nuttx/sched/init/os_bringup.c252
-rw-r--r--nuttx/sched/init/os_start.c538
4 files changed, 946 insertions, 0 deletions
diff --git a/nuttx/sched/init/Make.defs b/nuttx/sched/init/Make.defs
new file mode 100644
index 000000000..d48d73617
--- /dev/null
+++ b/nuttx/sched/init/Make.defs
@@ -0,0 +1,41 @@
+############################################################################
+# sched/init/Make.defs
+#
+# Copyright (C) 2014 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+INIT_SRCS = os_start.c os_bringup.c
+
+# Include init build support
+
+DEPPATH += --dep-path init
+VPATH += :init
diff --git a/nuttx/sched/init/init.h b/nuttx/sched/init/init.h
new file mode 100644
index 000000000..b52920a5c
--- /dev/null
+++ b/nuttx/sched/init/init.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+ * sched/init/init.h
+ *
+ * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_INIT_INIT_H
+#define __SCHED_INIT_INIT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <queue.h>
+#include <sched.h>
+
+#include <nuttx/kmalloc.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+/****************************************************************************
+ * Name: os_start
+ *
+ * Description:
+ * This function is called to initialize the operating system and to spawn
+ * the user initialization thread of execution. This is the initial entry
+ * point into NuttX
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned value:
+ * Does not return.
+ *
+ ****************************************************************************/
+
+void os_start(void);
+
+/****************************************************************************
+ * Name: os_bringup
+ *
+ * Description:
+ * Start all initial system tasks. This does the "system bring-up" after
+ * the conclusion of basic OS initialization. These initial system tasks
+ * may include:
+ *
+ * - pg_worker: The page-fault worker thread (only if CONFIG_PAGING is
+ * defined.
+ * - work_thread: The work thread. This general thread can be used to
+ * perform most any kind of queued work. Its primary
+ * function is to serve as the "bottom half" of device
+ * drivers.
+ *
+ * And the main application entry point:
+ * symbols:
+ *
+ * - USER_ENTRYPOINT: This is the default user application entry point.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int os_bringup(void);
+
+#endif /* __SCHED_INIT_INIT_H */
diff --git a/nuttx/sched/init/os_bringup.c b/nuttx/sched/init/os_bringup.c
new file mode 100644
index 000000000..4701b47ff
--- /dev/null
+++ b/nuttx/sched/init/os_bringup.c
@@ -0,0 +1,252 @@
+/****************************************************************************
+ * sched/init/os_bringup.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * With extensions by:
+ *
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <stdlib.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/init.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/kthread.h>
+#include <nuttx/userspace.h>
+
+#include "os_internal.h"
+#ifdef CONFIG_PAGING
+# include "paging/paging.h"
+#endif
+# include "init/init.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If NuttX is built as a separately compiled module, then the config.h header
+ * file should contain the address of the user module entry point. If not
+ * then the default entry point is user_start.
+ */
+
+/* Customize some strings */
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+# ifdef CONFIG_SCHED_HPWORK
+# if defined(CONFIG_SCHED_LPWORK)
+# define HPWORKNAME "hpwork"
+# define LPWORKNAME "lpwork"
+# elif defined(CONFIG_SCHED_USRWORK)
+# define HPWORKNAME "knlwork"
+# else
+# define HPWORKNAME "work"
+# endif
+# endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: os_bringup
+ *
+ * Description:
+ * Start all initial system tasks. This does the "system bring-up" after
+ * the conclusion of basic OS initialization. These initial system tasks
+ * may include:
+ *
+ * - pg_worker: The page-fault worker thread (only if CONFIG_PAGING is
+ * defined.
+ * - work_thread: The work thread. This general thread can be used to
+ * perform most any kind of queued work. Its primary
+ * function is to serve as the "bottom half" of device
+ * drivers.
+ *
+ * And the main application entry point:
+ * symbols:
+ *
+ * - USER_ENTRYPOINT: This is the default user application entry point.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int os_bringup(void)
+{
+ int taskid;
+
+ /* Setup up the initial environment for the idle task. At present, this
+ * may consist of only the initial PATH variable. The PATH variable is
+ * (probably) not used by the IDLE task. However, the environment
+ * containing the PATH variable will be inherited by all of the threads
+ * created by the IDLE task.
+ */
+
+#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL)
+ (void)setenv("PATH", CONFIG_PATH_INITIAL, 1);
+#endif
+
+ /* Start the page fill worker kernel thread that will resolve page faults.
+ * This should always be the first thread started because it may have to
+ * resolve page faults in other threads
+ */
+
+#ifdef CONFIG_PAGING
+ svdbg("Starting paging thread\n");
+
+ g_pgworker = KERNEL_THREAD("pgfill", CONFIG_PAGING_DEFPRIO,
+ CONFIG_PAGING_STACKSIZE,
+ (main_t)pg_worker, (FAR char * const *)NULL);
+ DEBUGASSERT(g_pgworker > 0);
+#endif
+
+ /* Start the worker thread that will serve as the device driver "bottom-
+ * half" and will perform misc garbage clean-up.
+ */
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+#ifdef CONFIG_SCHED_HPWORK
+
+#ifdef CONFIG_SCHED_LPWORK
+ svdbg("Starting high-priority kernel worker thread\n");
+#else
+ svdbg("Starting kernel worker thread\n");
+#endif
+
+ g_work[HPWORK].pid = KERNEL_THREAD(HPWORKNAME, CONFIG_SCHED_WORKPRIORITY,
+ CONFIG_SCHED_WORKSTACKSIZE,
+ (main_t)work_hpthread, (FAR char * const *)NULL);
+ DEBUGASSERT(g_work[HPWORK].pid > 0);
+
+ /* Start a lower priority worker thread for other, non-critical continuation
+ * tasks
+ */
+
+#ifdef CONFIG_SCHED_LPWORK
+
+ svdbg("Starting low-priority kernel worker thread\n");
+
+ g_work[LPWORK].pid = KERNEL_THREAD(LPWORKNAME, CONFIG_SCHED_LPWORKPRIORITY,
+ CONFIG_SCHED_LPWORKSTACKSIZE,
+ (main_t)work_lpthread, (FAR char * const *)NULL);
+ DEBUGASSERT(g_work[LPWORK].pid > 0);
+
+#endif /* CONFIG_SCHED_LPWORK */
+#endif /* CONFIG_SCHED_HPWORK */
+
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_SCHED_USRWORK)
+ /* Start the user-space work queue */
+
+ DEBUGASSERT(USERSPACE->work_usrstart != NULL);
+ taskid = USERSPACE->work_usrstart();
+ DEBUGASSERT(taskid > 0);
+#endif
+
+#endif /* CONFIG_SCHED_WORKQUEUE */
+
+ /* Once the operating system has been initialized, the system must be
+ * started by spawning the user init thread of execution. This is the
+ * first user-mode thead.
+ */
+
+ svdbg("Starting init thread\n");
+
+ /* Perform any last-minute, board-specific initialization, if so
+ * configured.
+ */
+
+#ifdef CONFIG_BOARD_INITIALIZE
+ board_initialize();
+#endif
+
+ /* Start the default application. In a flat build, this is entrypoint
+ * is given by the definitions, CONFIG_USER_ENTRYPOINT. In the kernel
+ * build, however, we must get the address of the entrypoint from the
+ * header at the beginning of the user-space blob.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ DEBUGASSERT(USERSPACE->us_entrypoint != NULL);
+ taskid = TASK_CREATE("init", SCHED_PRIORITY_DEFAULT,
+ CONFIG_USERMAIN_STACKSIZE, USERSPACE->us_entrypoint,
+ (FAR char * const *)NULL);
+#else
+ taskid = TASK_CREATE("init", SCHED_PRIORITY_DEFAULT,
+ CONFIG_USERMAIN_STACKSIZE,
+ (main_t)CONFIG_USER_ENTRYPOINT,
+ (FAR char * const *)NULL);
+#endif
+ ASSERT(taskid > 0);
+
+ /* We an save a few bytes by discarding the IDLE thread's environment. */
+
+#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL)
+ (void)clearenv();
+#endif
+
+ return OK;
+}
diff --git a/nuttx/sched/init/os_start.c b/nuttx/sched/init/os_start.c
new file mode 100644
index 000000000..57ef6d5fa
--- /dev/null
+++ b/nuttx/sched/init/os_start.c
@@ -0,0 +1,538 @@
+/****************************************************************************
+ * sched/init/os_start.c
+ *
+ * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/compiler.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+#include <nuttx/lib.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/init.h>
+
+#include "os_internal.h"
+#include "signal/signal.h"
+#include "wdog/wdog.h"
+#include "semaphore/semaphore.h"
+#ifndef CONFIG_DISABLE_MQUEUE
+# include "mqueue/mqueue.h"
+#endif
+#ifndef CONFIG_DISABLE_PTHREAD
+# include "pthread/pthread.h"
+#endif
+#include "clock/clock.h"
+#include "timer/timer.h"
+#include "irq/irq.h"
+#ifdef HAVE_TASK_GROUP
+#include "group/group.h"
+#endif
+#include "init/init.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* Task Lists ***************************************************************/
+/* The state of a task is indicated both by the task_state field of the TCB
+ * and by a series of task lists. All of these tasks lists are declared
+ * below. Although it is not always necessary, most of these lists are
+ * prioritized so that common list handling logic can be used (only the
+ * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists need
+ * to be prioritized).
+ */
+
+/* This is the list of all tasks that are ready to run. The head of this
+ * list is the currently active task; the tail of this list is always the
+ * IDLE task.
+ */
+
+volatile dq_queue_t g_readytorun;
+
+/* This is the list of all tasks that are ready-to-run, but cannot be placed
+ * in the g_readytorun list because: (1) They are higher priority than the
+ * currently active task at the head of the g_readytorun list, and (2) the
+ * currently active task has disabled pre-emption.
+ */
+
+volatile dq_queue_t g_pendingtasks;
+
+/* This is the list of all tasks that are blocked waiting for a semaphore */
+
+volatile dq_queue_t g_waitingforsemaphore;
+
+/* This is the list of all tasks that are blocked waiting for a signal */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+volatile dq_queue_t g_waitingforsignal;
+#endif
+
+/* This is the list of all tasks that are blocked waiting for a message
+ * queue to become non-empty.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+volatile dq_queue_t g_waitingformqnotempty;
+#endif
+
+/* This is the list of all tasks that are blocked waiting for a message
+ * queue to become non-full.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+volatile dq_queue_t g_waitingformqnotfull;
+#endif
+
+/* This is the list of all tasks that are blocking waiting for a page fill */
+
+#ifdef CONFIG_PAGING
+volatile dq_queue_t g_waitingforfill;
+#endif
+
+/* This the list of all tasks that have been initialized, but not yet
+ * activated. NOTE: This is the only list that is not prioritized.
+ */
+
+volatile dq_queue_t g_inactivetasks;
+
+/* These are lists of dayed memory deallocations that need to be handled
+ * within the IDLE loop or worker thread. These deallocations get queued
+ * by sched_kufree and sched_kfree() if the OS needs to deallocate memory
+ * while it is within an interrupt handler.
+ */
+
+volatile sq_queue_t g_delayed_kufree;
+
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+volatile sq_queue_t g_delayed_kfree;
+#endif
+
+/* This is the value of the last process ID assigned to a task */
+
+volatile pid_t g_lastpid;
+
+/* The following hash table is used for two things:
+ *
+ * 1. This hash table greatly speeds the determination of
+ * a new unique process ID for a task, and
+ * 2. Is used to quickly map a process ID into a TCB.
+ * It has the side effects of using more memory and limiting
+ *
+ * the number of tasks to CONFIG_MAX_TASKS.
+ */
+
+struct pidhash_s g_pidhash[CONFIG_MAX_TASKS];
+
+/* This is a table of task lists. This table is indexed by
+ * the task state enumeration type (tstate_t) and provides
+ * a pointer to the associated static task list (if there
+ * is one) as well as a boolean indication as to if the list
+ * is an ordered list or not.
+ */
+
+const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] =
+{
+ { NULL, false }, /* TSTATE_TASK_INVALID */
+ { &g_pendingtasks, true }, /* TSTATE_TASK_PENDING */
+ { &g_readytorun, true }, /* TSTATE_TASK_READYTORUN */
+ { &g_readytorun, true }, /* TSTATE_TASK_RUNNING */
+ { &g_inactivetasks, false }, /* TSTATE_TASK_INACTIVE */
+ { &g_waitingforsemaphore, true } /* TSTATE_WAIT_SEM */
+#ifndef CONFIG_DISABLE_SIGNALS
+ ,
+ { &g_waitingforsignal, false } /* TSTATE_WAIT_SIG */
+#endif
+#ifndef CONFIG_DISABLE_MQUEUE
+ ,
+ { &g_waitingformqnotempty, true }, /* TSTATE_WAIT_MQNOTEMPTY */
+ { &g_waitingformqnotfull, true } /* TSTATE_WAIT_MQNOTFULL */
+#endif
+#ifdef CONFIG_PAGING
+ ,
+ { &g_waitingforfill, true } /* TSTATE_WAIT_PAGEFILL */
+#endif
+};
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+/* This is the task control block for this thread of execution. This thread
+ * of execution is the IDLE task. NOTE: the system boots into the IDLE
+ * task. The IDLE task spawns the user initialization task (user_start) and
+ * that user init task is responsible for bringing up the rest of the system
+ */
+
+static FAR struct task_tcb_s g_idletcb;
+
+/* This is the name of the idle task */
+
+static FAR const char g_idlename[] = "Idle Task";
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: os_start
+ *
+ * Description:
+ * This function is called to initialize the operating system and to spawn
+ * the user initialization thread of execution. This is the initial entry
+ * point into NuttX
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned value:
+ * Does not return.
+ *
+ ****************************************************************************/
+
+void os_start(void)
+{
+ int i;
+
+ slldbg("Entry\n");
+
+ /* Initialize RTOS Data ***************************************************/
+ /* Initialize all task lists */
+
+ dq_init(&g_readytorun);
+ dq_init(&g_pendingtasks);
+ dq_init(&g_waitingforsemaphore);
+#ifndef CONFIG_DISABLE_SIGNALS
+ dq_init(&g_waitingforsignal);
+#endif
+#ifndef CONFIG_DISABLE_MQUEUE
+ dq_init(&g_waitingformqnotfull);
+ dq_init(&g_waitingformqnotempty);
+#endif
+#ifdef CONFIG_PAGING
+ dq_init(&g_waitingforfill);
+#endif
+ dq_init(&g_inactivetasks);
+ sq_init(&g_delayed_kufree);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+ sq_init(&g_delayed_kfree);
+#endif
+
+ /* Initialize the logic that determine unique process IDs. */
+
+ g_lastpid = 0;
+ for (i = 0; i < CONFIG_MAX_TASKS; i++)
+ {
+ g_pidhash[i].tcb = NULL;
+ g_pidhash[i].pid = INVALID_PROCESS_ID;
+ }
+
+ /* Assign the process ID of ZERO to the idle task */
+
+ g_pidhash[PIDHASH(0)].tcb = &g_idletcb.cmn;
+ g_pidhash[PIDHASH(0)].pid = 0;
+
+ /* Initialize the IDLE task TCB *******************************************/
+ /* Initialize a TCB for this thread of execution. NOTE: The default
+ * value for most components of the g_idletcb are zero. The entire
+ * structure is set to zero. Then only the (potentially) non-zero
+ * elements are initialized. NOTE: The idle task is the only task in
+ * that has pid == 0 and sched_priority == 0.
+ */
+
+ bzero((void*)&g_idletcb, sizeof(struct task_tcb_s));
+ g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING;
+ g_idletcb.cmn.entry.main = (main_t)os_start;
+
+ /* Set the IDLE task name */
+
+#if CONFIG_TASK_NAME_SIZE > 0
+ strncpy(g_idletcb.cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE-1);
+#endif /* CONFIG_TASK_NAME_SIZE */
+
+ /* Configure the task name in the argument list. The IDLE task does
+ * not really have an argument list, but this name is still useful
+ * for things like the NSH PS command.
+ *
+ * In the kernel mode build, the arguments are saved on the task's stack
+ * and there is no support that yet.
+ */
+
+#if defined(CONFIG_CUSTOM_STACK) || !defined(CONFIG_NUTTX_KERNEL)
+#if CONFIG_TASK_NAME_SIZE > 0
+ g_idletcb.argv[0] = g_idletcb.cmn.name;
+#else
+ g_idletcb.argv[0] = (char*)g_idlename;
+#endif /* CONFIG_TASK_NAME_SIZE */
+#endif /* CONFIG_CUSTOM_STACK || !CONFIG_NUTTX_KERNEL */
+
+ /* Then add the idle task's TCB to the head of the ready to run list */
+
+ dq_addfirst((FAR dq_entry_t*)&g_idletcb, (FAR dq_queue_t*)&g_readytorun);
+
+ /* Initialize the processor-specific portion of the TCB */
+
+ up_initial_state(&g_idletcb.cmn);
+
+ /* Initialize RTOS facilities *********************************************/
+ /* Initialize the semaphore facility(if in link). This has to be done
+ * very early because many subsystems depend upon fully functional
+ * semaphores.
+ */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (sem_initialize != NULL)
+#endif
+ {
+ sem_initialize();
+ }
+
+ /* Initialize the memory manager */
+
+ {
+ FAR void *heap_start;
+ size_t heap_size;
+
+ /* Get the user-mode heap from the platform specific code and configure
+ * the user-mode memory allocator.
+ */
+
+ up_allocate_heap(&heap_start, &heap_size);
+ kumm_initialize(heap_start, heap_size);
+
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+ /* Get the kernel-mode heap from the platform specific code and configure
+ * the kernel-mode memory allocator.
+ */
+
+ up_allocate_kheap(&heap_start, &heap_size);
+ kmm_initialize(heap_start, heap_size);
+#endif
+ }
+
+ /* Initialize tasking data structures */
+
+#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (task_initialize != NULL)
+#endif
+ {
+ task_initialize();
+ }
+#endif
+
+ /* Initialize the interrupt handling subsystem (if included) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (irq_initialize != NULL)
+#endif
+ {
+ irq_initialize();
+ }
+
+ /* Initialize the watchdog facility (if included in the link) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (wd_initialize != NULL)
+#endif
+ {
+ wd_initialize();
+ }
+
+ /* Initialize the POSIX timer facility (if included in the link) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (clock_initialize != NULL)
+#endif
+ {
+ clock_initialize();
+ }
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (timer_initialize != NULL)
+#endif
+ {
+ timer_initialize();
+ }
+#endif
+
+ /* Initialize the signal facility (if in link) */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (sig_initialize != NULL)
+#endif
+ {
+ sig_initialize();
+ }
+#endif
+
+ /* Initialize the named message queue facility (if in link) */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (mq_initialize != NULL)
+#endif
+ {
+ mq_initialize();
+ }
+#endif
+
+ /* Initialize the thread-specific data facility (if in link) */
+
+#ifndef CONFIG_DISABLE_PTHREAD
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (pthread_initialize != NULL)
+#endif
+ {
+ pthread_initialize();
+ }
+#endif
+
+ /* Initialize the file system (needed to support device drivers) */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (fs_initialize != NULL)
+#endif
+ {
+ fs_initialize();
+ }
+#endif
+
+ /* Initialize the network system */
+
+#ifdef CONFIG_NET
+ net_initialize();
+#endif
+
+ /* The processor specific details of running the operating system
+ * will be handled here. Such things as setting up interrupt
+ * service routines and starting the clock are some of the things
+ * that are different for each processor and hardware platform.
+ */
+
+ up_initialize();
+
+ /* Initialize the C libraries (if included in the link). This
+ * is done last because the libraries may depend on the above.
+ */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (lib_initialize != NULL)
+#endif
+ {
+ lib_initialize();
+ }
+
+ /* IDLE Group Initialization **********************************************/
+ /* Allocate the IDLE group and suppress child status. */
+
+#ifdef HAVE_TASK_GROUP
+ DEBUGVERIFY(group_allocate(&g_idletcb));
+#endif
+
+ /* Create stdout, stderr, stdin on the IDLE task. These will be
+ * inherited by all of the threads created by the IDLE task.
+ */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+ DEBUGVERIFY(group_setupidlefiles(&g_idletcb));
+#endif
+
+ /* Complete initialization of the IDLE group. Suppress retention
+ * of child status in the IDLE group.
+ */
+
+#ifdef HAVE_TASK_GROUP
+ DEBUGVERIFY(group_initialize(&g_idletcb));
+ g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT;
+#endif
+
+ /* Bring Up the System ****************************************************/
+ /* Create initial tasks and bring-up the system */
+
+ DEBUGVERIFY(os_bringup());
+
+ /* The IDLE Loop **********************************************************/
+ /* When control is return to this point, the system is idle. */
+
+ sdbg("Beginning Idle Loop\n");
+ for (;;)
+ {
+ /* Perform garbage collection (if it is not being done by the worker
+ * thread). This cleans-up memory de-allocations that were queued
+ * because they could not be freed in that execution context (for
+ * example, if the memory was freed from an interrupt handler).
+ */
+
+#ifndef CONFIG_SCHED_WORKQUEUE
+ /* We must have exclusive access to the memory manager to do this
+ * BUT the idle task cannot wait on a semaphore. So we only do
+ * the cleanup now if we can get the semaphore -- this should be
+ * possible because if the IDLE thread is running, no other task is!
+ */
+
+ if (kmm_trysemaphore() == 0)
+ {
+ sched_garbagecollection();
+ kmm_givesemaphore();
+ }
+#endif
+
+ /* Perform any processor-specific idle state operations */
+
+ up_idle();
+ }
+}