diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-08-08 15:30:59 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-08-08 15:30:59 -0600 |
commit | b415d5f6e7f3bb0e4eca3c51d8a121a9ce4adcfc (patch) | |
tree | fb1eb4603a497ffcad2e2eae6e802363f5faca91 /nuttx/sched/init | |
parent | 0dc82c9ce3122c309e91981ed62a4d2a08744b86 (diff) | |
download | nuttx-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.defs | 41 | ||||
-rw-r--r-- | nuttx/sched/init/init.h | 115 | ||||
-rw-r--r-- | nuttx/sched/init/os_bringup.c | 252 | ||||
-rw-r--r-- | nuttx/sched/init/os_start.c | 538 |
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(); + } +} |