OS fundamental documentation
diff --git a/docs/os/core_os/mynewt_os.md b/docs/os/core_os/mynewt_os.md
index 5a38dd0..56fa662 100644
--- a/docs/os/core_os/mynewt_os.md
+++ b/docs/os/core_os/mynewt_os.md
@@ -1,21 +1,13 @@
-# Mynewt OS
+# Mynewt Core OS
-Insert introduction here
+The Mynewt Core OS is a multitasking, preemptive real-time operating system combining a scheduler with typical RTOS features such as mutexes, semaphores, memory pools, etc. The Mynewt Core OS also provides a number of useful utilities such as a task watchdog, networking stack memory buffers and time management API. Each of these features is described in detail in their own sections of the manual.
-## Real-Time Kernel <Modify as you Wish>
+A multitasking, preemptive operating system is one in which a number of different tasks can be instantiated and assigned a priority, with higher priority tasks running before lower priority tasks. Furthermore, if a lower priority task is running and a higher priority task wants to run, the lower priority task is halted and the higher priority task is allowed to run. In other words, the lower priority task is preempted by the higher priority task.
- Description
+# Why use an OS?
+You may ask yourself "why do I need a multitasking preemptive OS"? The answer may indeed be that you do not. Some applications are simple and only require a polling loop. Others are more complex and may require that certain jobs are executed in a timely manner or before other jobs are executed. If you have a simple polling loop, you cant move on to service a job until the current job is done being serviced. With the Mynewt OS, the application developer need not worry about certain jobs taking too long or not executing in a timely fashion; the OS provides mechanisms to deal with these situations. Another benefit of using an OS is that it helps shield application developers form other application code being written; the developer does not have to worry (or has to worry less) about other application code behaving badly and causing undesirable behavior or preventing their code from executing properly. Other benefits of using an OS (and the Mynewt OS in particular) is that it also provides features that the developer would need to create on their own.
-## Real-Time OS <Modify as you Wish>
-
- Description
-
-
-## Insert topic of your choice
-
- Description
-
-## Features
+# Core OS Features
<Insert basic feature descriptions, how the various pieces fit together etc., what's special in Mynewt OS>
@@ -32,6 +24,131 @@
* [Callouts](callout/callout.md)
* [Porting OS to other platforms](porting/port_os.md)
+
+# Basic OS Application Creation
+Creating an application using the Mynewt Core OS is a relatively simple task: once you have installed the basic newt structure for your application and created your bsp, the developer initializes the os by calling `os_init()`, performs application specific initializations, and then starts the os by calling `os_start()`. The `os_init()` API performs two basic functions: calls architecture and bsp specific setup and initializes the idle task of the OS. This is required before the os is started. The os start API initializes the OS time tick interrupt and starts the highest priority task running (i.e starts the scheduler). Note that `os_start()` never returns; once called the device is either running in an application task context or in idle task context.
+
+Initializing application modules and tasks can get somewhat complicated with RTOS's similar to Mynewt. Care must be taken that API provided by a task are initialized prior to being called by another (higher priority) task. For example, take a simple application with two tasks (tasks 1 and 2, with task 1 higher priority than task 2). Task 2 provides an API which has a semaphore lock and this semaphore is initialized by task 2 when the task handler for task 2 is called. Task 1 is expected to call this API.
+
+Consider the sequence of events when the OS is started. The scheduler starts running and picks the highest priority task (task 1 in this case). The task handler function for task 1 is called and will keep running until it yields execution. Before yielding, code in the task 1 handler function calls the API provided by task 2. The semaphore being accessed in the task 2 API has yet to be initialized since the task 2 handler function has not yet had a chance to run! This will lead to undesirable behavior and will need to be addressed by the application developer. Note that the Mynewt OS does guard against internal API being called before the OS has started (they will return error) but it does not safeguard application defined objects from access prior to initialization.
+
+# Example
+
+One way to avoid initialization issues like the one described above is to perform task initializations prior to starting the OS. The code example shown below illustrates this concept. The application initializes the os, calls an application specific "task initialization" function and then starts the OS. The application task initialization function is responsible for initializing all the data objects that each task exposes to the other tasks. The tasks themselves are also initialized at this time (by calling `os_task_init()`).
+
+
+In the example, each task works in a ping-pong like fashion: task 1 wakes up, adds a token to semaphore 1 and then waits for a token from semaphore 2. Task 2 waits for a token on semaphore 1 and once it gets it, adds a token to semaphore 2. Notice that the semaphores are initialized by the application specific task initialization functions and not inside the task handler functions. If task 2 (being lower in priority than task 1) had called os_sem_init() for task2_sem inside task2_handler(), task 1 would have called os_sem_pend() using task2_sem before task2_sem was initialized.
+
+<br>
+
+
+```no-highlight
+
+/* Task 1 handler function */
+void
+task1_handler(void *arg)
+{
+ while (1) {
+ /* Release semaphore to task 2 */
+ os_sem_release(&task1_sem);
+
+ /* Wait for semaphore from task 2 */
+ os_sem_pend(&task2_sem, OS_TIMEOUT_NEVER);
+ }
+}
+
+/* Task 2 handler function */
+void
+task2_handler(void *arg)
+{
+ struct os_task *t;
+
+ while (1) {
+ /* Wait for semaphore from task1 */
+ os_sem_pend(&task1_sem, OS_TIMEOUT_NEVER);
+
+ /* Release task2 semaphore */
+ os_sem_release(&task2_sem);
+ }
+}
+
+
+/* Initialize task 1 exposed data objects */
+void
+task1_init(void)
+{
+ /* Initialize task1 semaphore */
+ os_sem_init(&task1_sem, 0);
+}
+
+/* Initialize task 2 exposed data objects */
+void
+task2_init(void)
+{
+ /* Initialize task1 semaphore */
+ os_sem_init(&task2_sem, 0);
+}
+
+/**
+ * init_app_tasks
+ *
+ * Called by main.c after os_init(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static int
+init_app_tasks(void)
+{
+ /*
+ * Initialize tasks 1 and 2. Note that the task handlers are not called yet; they will
+ * be called when the OS is started.
+ */
+ os_task_init(&task1, "task1", task1_handler, NULL, TASK1_PRIO,
+ OS_WAIT_FOREVER, task1_stack, TASK1_STACK_SIZE);
+
+ os_task_init(&task2, "task2", task2_handler, NULL, TASK2_PRIO,
+ OS_WAIT_FOREVER, task2_stack, TASK2_STACK_SIZE);
+
+ /* Call task specific initialization functions. */
+ task1_init();
+ task2_init();
+
+ return 0;
+}
+
+/**
+ * main
+ *
+ * The main function for the application. This function initializes the os, calls
+ * the application specific task initialization function. then starts the
+ * OS. We should not return from os start!
+ */
+int
+main(void)
+{
+ int i;
+ int rc;
+ uint32_t seed;
+
+ /* Initialize OS */
+ os_init();
+
+ /* Initialize application specific tasks */
+ init_app_tasks();
+
+ /* Start the OS */
+ os_start();
+
+ /* os start should never return. If it does, this should be an error */
+ assert(0);
+
+ return rc;
+}
+
+```
+
+
## OS Functions
diff --git a/docs/os/core_os/os_init.md b/docs/os/core_os/os_init.md
index e69de29..a8873ab 100644
--- a/docs/os/core_os/os_init.md
+++ b/docs/os/core_os/os_init.md
@@ -0,0 +1,30 @@
+## <font color="#F2853F" style="font-size:24pt">os_init</font>
+
+```no-highlight
+void os_init(void)
+```
+
+Initializes the OS. Must be called before the OS is started (i.e. os_start() is called).
+
+<br>
+
+#### Arguments
+
+None
+
+<br>
+
+#### Returned values
+None
+
+<br>
+
+#### Notes
+
+The call to os_init performs architecture and bsp initializations and initializes the idle task.
+
+This function does not start the OS, the OS time tick interrupt, or the scheduler.
+
+<br>
+
+---------------------
diff --git a/docs/os/core_os/os_start.md b/docs/os/core_os/os_start.md
index e69de29..1b2ab0a 100644
--- a/docs/os/core_os/os_start.md
+++ b/docs/os/core_os/os_start.md
@@ -0,0 +1,30 @@
+## <font color="#F2853F" style="font-size:24pt">os_start</font>
+
+```no-highlight
+void os_start(void)
+```
+
+Starts the OS by initializing and enabling the OS time tick and starting the scheduler.
+
+This function does not return
+
+<br>
+
+#### Arguments
+
+None
+
+<br>
+
+#### Returned values
+None (does not return).
+
+<br>
+
+#### Notes
+
+Once os_start has been called, context is switched to the highest priority task that was initialized prior to calling os_start.
+
+<br>
+
+---------------------
diff --git a/docs/os/core_os/os_started.md b/docs/os/core_os/os_started.md
index e69de29..202dcb0 100644
--- a/docs/os/core_os/os_started.md
+++ b/docs/os/core_os/os_started.md
@@ -0,0 +1,22 @@
+## <font color="#F2853F" style="font-size:24pt">os_started</font>
+
+```no-highlight
+int os_started(void)
+```
+
+Returns 'true' (1) if the os has been started; 0 otherwise.
+
+<br>
+
+#### Arguments
+
+None
+
+<br>
+
+#### Returned values
+Integer value with 0 meaning the OS has not been started and a 1 indicating the OS has been started (i.e. os_start() has been called).
+
+<br>
+
+---------------------