You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2017/02/20 16:30:50 UTC

[2/4] incubator-mynewt-site git commit: Update Event Queue OS Guide and Tutorial for new event queue implementation. 1) Updated Event Queue OS guide description, added description for os_eventq_designate and os_eventq_run functions, deleted os_eventq_df

Update Event Queue OS Guide and Tutorial for new event queue implementation.
1) Updated Event Queue OS guide description,  added description for os_eventq_designate and os_eventq_run functions,
deleted os_eventq_dflt_set function.
2) Updated Event Queue tutorial to show how to use Mynewt default eventq and to create dedicated event queue.
3) Modified the example to use the nRF52 board.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/commit/f9e50056
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/tree/f9e50056
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/diff/f9e50056

Branch: refs/heads/develop
Commit: f9e50056fc3b0a87b3ab67fcd03e230cb740dfb9
Parents: bfbef86
Author: cwanda <wa...@happycity.com>
Authored: Wed Feb 15 23:01:38 2017 -0800
Committer: cwanda <wa...@happycity.com>
Committed: Thu Feb 16 07:00:43 2017 -0800

----------------------------------------------------------------------
 docs/os/core_os/event_queue/event_queue.md      |  94 ++-
 .../core_os/event_queue/os_eventq_designate.md  |  44 ++
 .../core_os/event_queue/os_eventq_dflt_get.md   |  25 +-
 docs/os/core_os/event_queue/os_eventq_get.md    |  31 +-
 docs/os/core_os/event_queue/os_eventq_init.md   |  16 +-
 docs/os/core_os/event_queue/os_eventq_inited.md |  15 +-
 docs/os/core_os/event_queue/os_eventq_put.md    |  64 ++-
 docs/os/core_os/event_queue/os_eventq_remove.md |  24 +-
 docs/os/core_os/event_queue/os_eventq_run.md    |  40 ++
 docs/os/tutorials/event_queue.md                | 568 ++++++++++++-------
 mkdocs.yml                                      |   8 +-
 11 files changed, 594 insertions(+), 335 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/event_queue.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/event_queue.md b/docs/os/core_os/event_queue/event_queue.md
index f4ec8e5..68f7ae5 100644
--- a/docs/os/core_os/event_queue/event_queue.md
+++ b/docs/os/core_os/event_queue/event_queue.md
@@ -1,32 +1,30 @@
 # Event Queues
 
 
-Event queue is a way for a task to serialize events sent to it. This makes it easy to process events required to happen inside the task's context. Events may arrive either from an interrupt handler, or from another task.
+An event queue allows a task to serialize incoming events and simplify event processing. Events are stored in a queue and a task removes and processes an event from the queue.  An event is processed in the context this task.  Events may be generated by [OS callouts](../callout/callout.md), interrupt handlers, and other tasks.  
 
 ### Description
 
-Events arrive in form the of a data structure `struct os_event` and 
-they are queued to another data structure `struct os_eventq`.
+Mynewt's event queue model uses callback functions to process events. Each event is associated with a callback function that is called to process the event. This model enables a library package, that uses events in its implementation but does not have real-time timing requirements, to use an application event queue instead of creating a dedicated event queue and task to process its events.  The callback function executes in the context of the task that the application creates to manage the event queue.  This model reduces an application's memory requirement because memory must be allocated for the task's stack when a task is created.  A package that has real-time timing requirements and must run at a specific task priority should create a dedicated event queue and task to process its events.
 
-The Event Queue must be initialized before trying to add events to 
-it. This is done using `os_eventq_init()`.
+In the Mynewt model, a package defines its events and implements the callback functions for the events. A package that does not have real-time timing requirements should use Mynewt's default event queue for its events.  The callback function for an event from the Mynewt default event queue is executed in the context of the application main task. A package can, optionally, export a function that allows an application to specify the event queue for the package to use. (See the example in the `os_eventq_designate()` function description on how to write such a function.) The application task handler that manages the event queue simply pulls events from the event queue and executes the event's callback function in its context.  
 
-A common way of using event queues is to have a task loop while calling `os_eventq_get()`, 
-waiting for work to do. Other tasks (or interrupts) then call `os_eventq_put()` 
-to wake it up. Once an event has been queued, the task waiting on that queue is woken up. The event dispatching logic is built into each event via a callback function pointer. The task handler can simply pull events
-off the queue and call its callback handler. The processing task would then act according to the event type. 
 
-When `os_event` is queued, it should not be freed until processing task is done with it.
+A common way that Mynewt applications or packages process events from an event queue is to have a task that executes in an infinite loop and calls the `os_eventq_get()` function to dequeue and return the event from the head of the event queue.  The task then calls the event callback function to process the event.  The `os_eventq_get()` function puts the task in to the `sleeping` state when there are no events on the queue.  (See [Scheduler](../context_switch/context_switch.md) for more information on task execution states.) Other tasks (or interrupts) call the `os_eventq_put()` function to add an event to the queue. The `os_eventq_put()` function determines whether a task is blocked waiting for an event on the queue and puts the task into the `ready-to-run` state.  
 
-It is assumed that there is only one task consuming events from an event queue. Only one task should be sleeping on a particular `os_eventq` at a time.
+A task can use the `os_eventq_run()` wrapper function that calls the `os_eventq_get()` function to dequeue an event from the queue and then calls the event callback function to process the event.
 
-Note that [os_callout](../callout/callout.md) subsystem assumes that event queue is used as the wakeup mechanism.
+Note:
+
+* Only one task should consume or block waiting for events from an event queue.
+* The [os_callout](../callout/callout.md) subsystem uses events for timer expiration notification.
 
 ### Data structures
 
-```c
-typedef void os_event_fn(struct os_event *ev);
 
+The `os_event` structure defines an event and has the following fields:
+
+```c
 struct os_event {
     uint8_t ev_queued;
     os_event_fn *ev_cb;
@@ -37,48 +35,39 @@ struct os_event {
 
 | Element | Description |
 |---------|-------------|
-| `ev_queued` | Internal field, which tells whether event is linked into an *os_eventq* already |
-| `ev_cb` | A callback function pointer that is called when a new event arrives on the queue |
-| `ev_arg` | Can be used further as input to task processing this event |
+| `ev_queued` | Internal field that indicates whether this event is currently linked to an event queue |
+| `ev_cb` | Pointer to the callback function to call to process this event |
+| `ev_arg` | Pointer to an optional opaque data that the callback function uses to process this event |
 | `ev_next` | Linkage attaching this event to an event queue |
 
-With the callback function pointer, the dispatch logic gets built into each event. The task handler simply pulls an event off its queue and blindly calls its callback function.  A helper function was added to do just this: 
-`os_eventq_run()`.  As an example, the task handler for the bleprph application is below:
-
+  
+An event callback function has the following function prototype:
 ```c
-static void
-bleprph_task_handler(void *unused)
-{
-    while (1) {
-        os_eventq_run(&bleprph_evq);
-    }
-}
+typedef void os_event_fn(struct os_event *ev);
+
 ```
-  
-The callback associated with an event is specified when the event gets
-initialized.  For example, here are some statically-initialized events
-in the NimBLE host:
+A pointer to the `os_event` structure for the event is passed as an argument to the callback function. 
+
+Notes: If the memory for the `os_event` structure is dynamically allocated: 
+
+* You must not free the memory for an event that is currently on an event queue.
+* You must free the memory in the callback function after it completes processing the event.
+
+You must set the callback function for an event when you initialize the event.  For example, here is an example of a statically-initialized event in the NimBLE host:
 
 ```c
 static void ble_hs_event_tx_notify(struct os_event *ev);
-static void ble_hs_event_reset(struct os_event *ev);
 
 /** OS event - triggers tx of pending notifications and indications. */
 static struct os_event ble_hs_ev_tx_notifications = {
     .ev_cb = ble_hs_event_tx_notify,
 };
 
-/** OS event - triggers a full reset. */
-static struct os_event ble_hs_ev_reset = {
-    .ev_cb = ble_hs_event_reset,
-};
 ```
 
-The callback function receives a single parameter: a
-pointer to the event being processed.  If the event is allocated
-dynamically, the callback function should free the event.   
-   
-   
+<br>   
+The `os_eventq` structure defines an event queue and has the following fields:   
+
 ```c
 struct os_eventq {
     struct os_task *evq_task;
@@ -89,23 +78,26 @@ struct os_eventq {
 
 | Element | Description |
 |---------|-------------|
-| `evq_task` | Pointer to task if there is task sleeping on *os_eventq_get()* |
-| `evq_list` | Queue head for list of events in this queue |
+| `evq_task` | Pointer to the task, if any, that is waiting (in the `sleeping` state) for the `os_eventq_get()` function to return  an event |
+| `evq_list` | Head of the list of events in this queue |
+
+You must call the `os_eventq_init()` function to initialize an event queue before you can add events to the queue.
 
 ### List of Functions
 
 
-The functions available in event queue feature are:
+The functions available in the Event Queue feature are:
 
 | **Function** | **Description** |
 |---------|-------------|
-| [`os_eventq_init`](os_eventq_init.md) | Initializes the given event queue, making it ready for use. |
-| [`os_eventq_inited`](os_eventq_inited.md) | Has the event queue been initialized. |
-| [`os_eventq_get`](os_eventq_get.md) | Fetches the first event from a queue. Task will sleep until something gets queued. |
-| [`os_eventq_put`](os_eventq_put.md) | Queues an event to tail of the event queue. |
-| [`os_eventq_remove`](os_eventq_remove.md) | Removes an event which has been placed in a queue. |
-| [`os_eventq_dflt_set`](os_eventq_dflt_set.md) | Set the default event queue. |
-| [`os_eventq_dflt_get`](os_eventq_dflt_get.md) | Get the default event queue. |
+| [`os_eventq_init`](os_eventq_init.md) | Initializes an event queue. |
+| [`os_eventq_inited`](os_eventq_inited.md) | Indicates whether an event queue has been initialized. |
+| [`os_eventq_get`](os_eventq_get.md) | Dequeues an event from the head of an event queue. The calling task blocks (in the `sleeping` state) when the event queue is empty. | 
+| [`os_eventq_put`](os_eventq_put.md) | Enqueues an event at the tail of an event queue and puts a task waiting for an event on the queue into the `ready-to-run` state. |
+| [`os_eventq_remove`](os_eventq_remove.md) | Removes an event from an event queue. |
+| [`os_eventq_dflt_get`](os_eventq_dflt_get.md) | Gets the default event queue. |
+| [`os_eventq_designate`](os_eventq_designate.md) | Reassigns a package's current event queue to a new event queue. |
+| [`os_eventq_run`](os_eventq_run.md) | Wrapper function that dequeues an event from an event queue and calls the callbck function for the event. |
 
 
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_designate.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_designate.md b/docs/os/core_os/event_queue/os_eventq_designate.md
new file mode 100644
index 0000000..901231e
--- /dev/null
+++ b/docs/os/core_os/event_queue/os_eventq_designate.md
@@ -0,0 +1,44 @@
+## <font color="F2853F" style="font-size:24pt"> os_eventq_designate</font>
+
+```c
+   void
+    os_eventq_designate(struct os_eventq **cur_evq, struct os_eventq *new_evq,  struct os_event *start_ev)
+```
+ 
+Reassigns a package's current event queue pointer to point to a new event queue. If a startup event 
+is specified, the event is added to the new event queue and removed from the current event queue.
+
+
+#### Arguments
+
+| Arguments | Description |
+|-----------|-------------|
+| `cur_evq`|  Current event queue pointer to reassign |
+| `new_evq` | New event queue to use for the package |
+| `start_ev` | Start event to add to the new event queue |
+
+#### Returned values
+
+None
+
+#### Notes
+
+
+#### Example
+
+<Add text to set up the context for the example here>
+
+This example shows the `mgmt_evq_set()` function that the `mgmt/newtmgr` package implements. The function
+allows an application to specify an event queue for `newtmgr` to use. The `mgmt_evq_set()` function calls the `os_eventq_designate()` function to reassign the `nmgr_evq` to the event queue that the application specifies. 
+
+
+```c
+void
+mgmt_evq_set(struct os_eventq *evq)
+{
+    os_eventq_designate(&nmgr_evq, evq, NULL);
+}
+
+
+```
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_dflt_get.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_dflt_get.md b/docs/os/core_os/event_queue/os_eventq_dflt_get.md
index b174b7e..3cf0718 100644
--- a/docs/os/core_os/event_queue/os_eventq_dflt_get.md
+++ b/docs/os/core_os/event_queue/os_eventq_dflt_get.md
@@ -5,7 +5,7 @@
    *os_eventq_dflt_get(void)
 ```
 
-Get the default event queue that was set
+Gets the OS default event queue that Mynewt creates at startup.
 
 #### Arguments
 
@@ -13,7 +13,7 @@ None
 
 #### Returned values
 
-`struct os_eventq *` A pointer to the default event queue, if set.  
+`struct os_eventq *`: Pointer to OS the default event queue.  
 
 #### Notes
 
@@ -23,19 +23,20 @@ None
 #### Example
 
 <Add text to set up the context for the example here>
-This checks the default event queue and sets it if not already set.
+
+This example shows an application's `main()` function processing events from the OS default event queue.
 
 
 ```c
-struct os_eventq g_my_evq;
-
-int
-event_q_check()
-{    
-    if(os_eventq_dflt_get() == NULL)
-    {
-        os_eventq_dflt_set(g_my_evq);
-    }
+void main(int argc, char**argv)
+{
+     sysinit();
+
+      ...
+
+     while (1) {
+         os_eventq_run(os_eventq_dflt_get());
+     }
 
 }
 ```

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_get.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_get.md b/docs/os/core_os/event_queue/os_eventq_get.md
index 9bff17c..6e01f45 100644
--- a/docs/os/core_os/event_queue/os_eventq_get.md
+++ b/docs/os/core_os/event_queue/os_eventq_get.md
@@ -1,39 +1,44 @@
 ## <font color="#F2853F" style="font-size:24pt"> os_eventq_get</font>
 
 ```c
-void
+struct os_event *
 os_eventq_get(struct os_eventq *evq)
 ```
 
-Fetches the first event from a queue. Task will sleep until something gets queued.
+Dequeues and returns an event from the head of an event queue. When the event queue is empty, 
+the function puts the task into the `sleeping` state.
 
 
 #### Arguments
 
 | Arguments | Description |
 |-----------|-------------|
-| `evq` |  Queue to wait on  |
+| `evq` |  Event queue to retrieve the event from |
 
 
 #### Returned values
 
-Will return with a pointer to first `struct event` which is in the queue.
+A pointer to the `os_event` structure for the event dequeued from the queue. 
 
 #### Notes 
-
+In most cases, you do not need to call this function directly. You should call the `os_eventq_run()` wrapper
+function that calls this function to retrieve an event and then calls the callback function to process the event. 	
 
 #### Example
 
-Main loop of an example task.
+Example of the `os_eventq_run()` wrapper function that calls this function:
 
 ```c
-    while (1) {
-        ev = os_eventq_get(&task1_evq);
-        assert(ev);
-        if (ev->ev_type == CONS_EV_TYPE) {
-			/* XXX do stuff */
-        }
-    }
+void
+os_eventq_run(struct os_eventq *evq)
+{
+    struct os_event *ev;
+
+    ev = os_eventq_get(evq);
+    assert(ev->ev_cb != NULL);
+
+    ev->ev_cb(ev);
+}
 
 ```
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_init.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_init.md b/docs/os/core_os/event_queue/os_eventq_init.md
index 0c712bd..86b25b3 100644
--- a/docs/os/core_os/event_queue/os_eventq_init.md
+++ b/docs/os/core_os/event_queue/os_eventq_init.md
@@ -5,13 +5,13 @@
     os_eventq_init(struct os_eventq *evq)
 ```
 
-Initializes `struct os_eventq`, making it ready for use.
+Initializes an event queue. 
 
 #### Arguments
 
 | Arguments | Description |
 |-----------|-------------|
-| `evq` |  Pointer to event queue getting initialized  |
+| `evq` |  Pointer to the event queue to initialize |
 
 #### Returned values
 
@@ -19,26 +19,26 @@ None
 
 #### Notes
 
-Usually done at subsystem init time; before OS has been started, and before interrupts generating events have been enabled.
+Called during OS, package, and application initialization and before interrupts generating events have been enabled.
 
 
 #### Example
 
 <Add text to set up the context for the example here>
-This initializes event queue used by newtmgr task.
-
+This example shows the `app/bletest` application initializing the `g_bletest_evq` event queue.
 
 ```c
-struct os_eventq g_nmgr_evq;
+struct os_eventq g_bletest_evq;
 
 int
-nmgr_task_init(uint8_t prio, os_stack_t *stack_ptr, uint16_t stack_len)
+main(void)
 {
     /* variable declarations here */
 
-    os_eventq_init(&g_nmgr_evq);
+    os_eventq_init(&g_bletest_evq);
 
     /* initialization continues here */
+
 }
 ```
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_inited.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_inited.md b/docs/os/core_os/event_queue/os_eventq_inited.md
index 0d0511a..44fadf0 100644
--- a/docs/os/core_os/event_queue/os_eventq_inited.md
+++ b/docs/os/core_os/event_queue/os_eventq_inited.md
@@ -5,28 +5,27 @@
     os_eventq_inited(const struct os_eventq *evq)
 ```
 
-Check if event queue `const struct os_eventq` is ready for use.
+Indicates whether an event queue has been initialized.
 
 #### Arguments
 
 | Arguments | Description |
 |-----------|-------------|
-| `evq` |  Pointer to event queue to check  |
+| `evq` |  Pointer to the event queue to check  |
 
 #### Returned values
 
-`0` if event queue is ready
+* 1 if the event queue has been initialized and ready for use.
+* 0 if the event queue has not been initialized.
 
 #### Notes
-
-If an event queue was properly initialized (and the proper checks were done at initialization)
-this check is not needed prior to using an event queue.
-
+You do not need to call this function prior to using an event queue if you have called the `os_eventq_init()` function 
+to initialize the queue.
 
 #### Example
 
 <Add text to set up the context for the example here>
-This checks an event queue before using it.
+This example checks whether an event queue has been initialized.
 
 
 ```c

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_put.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_put.md b/docs/os/core_os/event_queue/os_eventq_put.md
index d46197c..453aede 100644
--- a/docs/os/core_os/event_queue/os_eventq_put.md
+++ b/docs/os/core_os/event_queue/os_eventq_put.md
@@ -5,15 +5,15 @@ void
 os_eventq_put(struct os_eventq *evq, struct os_event *ev)
 ```
 
-Queues an event to the tail of the event queue.
+Enqueues an event onto the tail of an event queue.  It puts a task, if any, that is in the `sleeping ` state waiting for an event into the `ready-to-run` state.
 
 
 #### Arguments
 
 | Arguments | Description |
 |-----------|-------------|
-| `evq` |  Queue where event is being placed  |
-| `ev` |  Event which is being queued  |
+| `evq` |  Event queue to add the event to |
+| `ev` |  Event to enqueue |
 
 
 #### Returned values
@@ -23,22 +23,52 @@ N/A
 #### Example
 
 <Add text to set up the context for the example here>
-This is used to pass info about an event to a task handling it.
-
+This example shows the ble host adding a host controller interface event to the `ble_hs_eventq` event queue.
 ```c
-    /* Get an event structure off the queue */
-    ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool);
-    if (!ev) {
-        err = os_memblock_put(&g_hci_cmd_pool, hci_ev);
-        assert(err == OS_OK);
-        return -1;
-    }
 
-    /* Fill out the event and post to Link Layer */
-    ev->ev_queued = 0;
-    ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT;
-    ev->ev_arg = hci_ev;
-    os_eventq_put(&ble_hs_evq, ev);
+/* Returns the ble_hs_eventq */
+static struct os_eventq *
+ble_hs_evq_get(void)
+{
+    return ble_hs_evq;
+}
+
+/* Event callback function */
+static void
+ble_hs_event_rx_hci_ev(struct os_event *ev)
+{
+    uint8_t *hci_evt;
+    int rc;
+
+    hci_evt = ev->ev_arg;
+    rc = os_memblock_put(&ble_hs_hci_ev_pool, ev);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+
+    ble_hs_hci_evt_process(hci_evt);
+}
 
+void
+ble_hs_enqueue_hci_event(uint8_t *hci_evt)
+{
+    struct os_event *ev;
+
+    /* Allocates memory for the event */
+    ev = os_memblock_get(&ble_hs_hci_ev_pool);
+
+    if (ev == NULL) {
+        ble_hci_trans_buf_free(hci_evt);
+    } else {
+        /* 
+         * Initializes the event with the ble_hs_event_rx_hci_ev callback function 
+         * and the hci_evt data for the callback function to use. 
+         */ 
+        ev->ev_queued = 0;
+        ev->ev_cb = ble_hs_event_rx_hci_ev;
+        ev->ev_arg = hci_evt;
+
+        /* Enqueues the event on the ble_hs_evq */
+        os_eventq_put(ble_hs_evq_get(), ev);
+    }
+}
 ```
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_remove.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_remove.md b/docs/os/core_os/event_queue/os_eventq_remove.md
index 7adcd36..f221212 100644
--- a/docs/os/core_os/event_queue/os_eventq_remove.md
+++ b/docs/os/core_os/event_queue/os_eventq_remove.md
@@ -5,15 +5,15 @@ void
 os_eventq_remove(struct os_eventq *evq, struct os_event *ev)
 ```
 
-Removes an event which has been placed in a queue.
+Removes an event from an event queue.
 
 
 #### Arguments
 
 | Arguments | Description |
 |-----------|-------------|
-| `evq` |  Queue where event is being removed from |
-| `ev` |  Event which is being removed  |
+| `evq` |  Event queue to remove the event from |
+| `ev` |  Event to remove  |
 
 
 #### Returned values
@@ -26,11 +26,27 @@ N/A
 #### Example
 
 <Add text to set up the context for the example here>
-This is from `os_callout_stop()`. User wants to stop a callout from getting passed to a task. If the event has already been queued, then remove it before it is seen.
+This example from the `os_callout_stop()` function shows how to remove a callout event from an event queue. It removes
+the event from the queue if the event is queued.
 
 ```c
+void
+os_callout_stop(struct os_callout *c)
+{
+    os_sr_t sr;
+
+    OS_ENTER_CRITICAL(sr);
+
+    if (os_callout_queued(c)) {
+        TAILQ_REMOVE(&g_callout_list, c, c_next);
+        c->c_next.tqe_prev = NULL;
+    }
+
     if (c->c_evq) {
         os_eventq_remove(c->c_evq, &c->c_ev);
     }
+
+    OS_EXIT_CRITICAL(sr);
+}
 ```
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/core_os/event_queue/os_eventq_run.md
----------------------------------------------------------------------
diff --git a/docs/os/core_os/event_queue/os_eventq_run.md b/docs/os/core_os/event_queue/os_eventq_run.md
new file mode 100644
index 0000000..52a754c
--- /dev/null
+++ b/docs/os/core_os/event_queue/os_eventq_run.md
@@ -0,0 +1,40 @@
+## <font color="F2853F" style="font-size:24pt"> os_eventq_run</font>
+
+```c
+   void
+    os_eventq_run(struct os_eventq *evq)
+```
+Wrapper function that calls the `os_eventq_get()` function to dequeue the event from the head of the event queue and then calls the callback function for the event.
+
+#### Arguments
+
+| Arguments | Description |
+|-----------|-------------|
+| `evq`|  Event queue to dequeue the event from |
+
+#### Returned values
+
+None
+
+#### Notes
+
+
+#### Example
+
+<Add text to set up the context for the example here>
+This example shows an application `main()` that calls the `os_eventq_run()` function to process events from the OS default event queue in an infinite loop.
+
+```c
+int
+main(int argc, char **argv)
+{
+
+     sysinit();
+       ...
+
+     while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+     }
+}
+```
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/docs/os/tutorials/event_queue.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/event_queue.md b/docs/os/tutorials/event_queue.md
index 880d9b5..e860f49 100644
--- a/docs/os/tutorials/event_queue.md
+++ b/docs/os/tutorials/event_queue.md
@@ -1,367 +1,495 @@
-## How to define a task which uses event queues to manage multiple events
+
+## How to Use Event Queues to Manage Multiple Events
 
 ### Introduction
 
-Event queue is a mechanism by which you can serialize incoming events for your task. You can use it to get info about arrived hardware interrupts, callout expirations and messages from other tasks.
+The event queue mechanism allows you to serialize incoming events for your task. You can use it to get information about hardware interrupts, callout expirations,  and messages from other tasks.
 
-The benefit of doing inter-task communication this way is that there should be less resources that need to be locked.
+The benefit of using events for inter-task communication is that it can reduce the number of resources that need to be shared and locked.  
 
-The benefit of doing interrupt processing in a task context instead of inside an interrupt context is that you are not blocking other HW interrupts when doing the work. The same goes for high priority tasks in the system; they're blocked until the interrupt handler returns. From the task context you'll also be able to access other OS facilities; you can sleep while waiting for a lock, for example.
+The benefit of processing interrupts in a task context instead of the interrupt context is that other interrupts and high priority tasks are not blocked waiting for the interrupt handler to complete processing.  A task can also access other OS facilities and sleep.
 
-<br>
+This tutorial assumes that you have read about [Event Queues](../core_os/event_queue/event_queue.md), the [Hardware Abstraction Layer](../modules/hal/hal.md), and [OS Callouts](../core_os/callout/callout.md) in the OS User's Guide. 
 
-### Example app
+This tutorial shows you how to create an application that uses events for: 
 
-Here you are going to write an app which demonstrates the use of event queues for communication between tasks. You will  also use OS callouts for timer expiration and another event from a GPIO interrupt.
+* Inter-task communication 
+* OS callouts for timer expiration 
+* GPIO interrupts  
 
-You will  use inputs from 3 sources to toggle 3 GPIO outputs on my STM32F3discovery board.
+It also shows you how to:
 
-<br>
+* Use the Mynewt default event queue and application main task to process your events. 
+* Create a dedicated event queue and task for your events.  
+
+To reduce an application's memory requirement,  we recommend that you use the Mynewt default event queue if your application or package does not have real-time timing requirements. 
+
+###Prerequisites
 
-#### Create project
+Ensure that you have met the following prerequisites before continuing with this tutorial:
 
-You start by creating a project and populating it with repositories incubator-mynewt-core and mynewt_stm32f3. See [STM32F3 tutorial](STM32F303.md) if you need help with this. You can also read the tutorial on [Additional Repositories](repo/add_repos.md) for a more thorough understanding. 
+* Install the newt tool.
+* Install the newtmgr tool.
+* Have Internet connectivity to fetch remote Mynewt components.
+* Install the compiler tools to support native compiling to build the project this tutorial creates.
+* Have a cable to establish a serial USB connection between the board and the laptop.
 
-<br> 
+### Example Application
 
-#### Create application
+In this example, you will write an application, for the Nordic nRF52 board, that uses events from three input sources to toggle three GPIO outputs and light up the LEDs.  If you are using a different board, you will need to adjust the GPIO pin numbers in the code example.
 
-Here's what the pkg.yml looks for the application.
+The application handles events from three sources on two event queues:
+
+* Events generated by an application task at periodic intervals are added to the Mynewt default event queue. 
+* OS callouts for timer events are added to the `my_timer_interrupt_eventq` event queue. 
+* GPIO interrupt events are added to the `my_timer_interrupt_eventq` event queue.
+<br>
+#### Create the Project
+Follow the instructions in the [nRF52 tutorial](nRF52.md) to create a project.
+<br>
+#### Create the Application
+Create the `pkg.yml` file for the application:
 
 ```no-highlight
-[marko@IsMyLaptop:~/src/events]$ cat apps/event_sample/pkg.yml
-pkg.name: apps/event_sample
+pkg.name: apps/eventq_example
 pkg.type: app
 
 pkg.deps:
-    - "@apache-mynewt-core/libs/os"
-    - "@apache-mynewt-core/hw/hal"
-    - "@apache-mynewt-core/libs/console/stub"
+    - kernel/os
+    - hw/hal
+    - sys/console/stub
 ```
-
 <br>
+#### Application Task Generated Events
 
-#### Initialize the event queue structure
+The application creates a task that generates events, at periodic intervals, to toggle the LED at pin `TASK_LED`. The event is queued on the Mynewt default event queue and is processed in the context of the application main task. 
 
-This must be done before anyone tries to place events to the queue. Here it's done before any task gets created. Initialization is done by calling *os_eventq_init()*.
+Declare and initialize the `gen_task_ev` event with the `my_ev_cb()` callback function to process the event:
 
 ```c
-#define MY_TASK_PRIO		4
-#define MY_TASK_STACK_SZ	512
-    
-static struct os_eventq my_eventq;
-static os_stack_t my_task_stack[MY_TASK_STACK_SZ];
-static struct os_task my_task_str;
 
-void
-init_tasks(void)
-{
-	struct os_task taskid;
+/* Callback function for application task event */
+static void my_ev_cb(struct os_event *);
 
-	os_eventq_init(&my_eventq);
-	os_task_init(&my_task_str, "task", my_task, NULL, MY_TASK_PRIO,
-	    OS_WAIT_FOREVER, my_task_stack, MY_TASK_STACK_SZ);
+/* Initialize the event with the callback function */
+static struct os_event gen_task_ev = {
+    .ev_cb = my_ev_cb,
+};
 
 ```
 
 <br>
+Implement the `my_ev_cb()` callback function to process a task generated event and toggle the LED at pin `TASK_LED`:
 
-#### Processing events
-
-Here event processing is done inside *my_task*. The main loop of the task is pulling events from the queue, and then taking action. We look at the type of the event to figure out what to do.
+```c
 
-The code snippet shows what the main loop of the event handler looks like. Events are removed from the head of the queue using os_eventq_get
+/* LED 1 (P0.17 on the board) */
+#define TASK_LED        17
 
-```c
-void
-my_task(void *arg)
+/*
+ * Event callback function for events generated by gen_task. It toggles 
+ * the LED at pin TASK_LED.
+ */
+static void my_ev_cb(struct os_event *ev)
 {
-	struct os_event *ev;
-
-	while (1) {
-		ev = os_eventq_get(&my_eventq);
-		switch (ev->ev_type) {
-		/* more event types here */
-		default:
-			assert(0);
-		}
-	}
+    assert(ev);
+    hal_gpio_toggle(TASK_LED);
+    return;
 }
-```
-
-<br>
-
-#### Event types
-
-You can define your own event types. Some numbers are already reserved by the OS, so you should not use those as your own types.
-
-Reserved event types are defined in *libs/os/include/os/os_eventq.h*. One example of a reserved type is OS_EVENT_T_TIMER, which is used as type in OS callouts.
-
-You should start your event numbers from *OS_EVENT_T_PERUSER*, and go higher.
-
-You are going to generate events from GPIO interrupt handler, from another task as well as from a callout. OS callout already has a type, but you'll need to define types for the other uses.
 
-```c
-#define MY_TASK_GPIO_EVENT	(OS_EVENT_T_PERUSER)
-#define MY_TASK_TASK_EVENT	(OS_EVENT_T_PERUSER + 1)
 ```
-
 <br>
+Create a task that generates an event at periodic intervals and adds, using the `os_eventq_put()` function,  the event to the Mynewt default event queue:
 
-#### Posting events from another task
-
-Events are posted to a queue by calling *os_eventq_put()*. You need to preallocate memory for the event structure. Here it's done by declaring the event structure as a global variable.
-
-Note that you can call *os_eventq_put()* with an event which has already been queued. In that case, the call has no effect; the position of the event is not changed within the queue.
+```c
 
-In the code snippet we declare the os_event structure, and initialize it. We also create the event generating task, and periodically post event to the event queue.
+#define GEN_TASK_PRIO       3     
+#define GEN_TASK_STACK_SZ   512
 
-```c
-#define GEN_TASK_PRIO		3
-#define GEN_TASK_STACK_SZ	512
-    
-static struct os_event gen_task_ev;
 static os_stack_t gen_task_stack[GEN_TASK_STACK_SZ];
 static struct os_task gen_task_str;
-    
-void
+
+/* 
+ * Task handler to generate an event to toggle the LED at pin TASK_LED. 
+ * The event is added to the Mynewt default event queue. 
+ */
+static void
 gen_task(void *arg)
 {
-	while (1) {
-		os_time_delay(OS_TICKS_PER_SEC / 4);
-		os_eventq_put(&my_eventq, &gen_task_ev);
-	}
+    while (1) {
+        os_time_delay(OS_TICKS_PER_SEC / 4);
+        os_eventq_put(os_eventq_dflt_get(), &gen_task_ev);
+    }
 }
-    
-void
+
+static void
 init_tasks(void)
 {
-	/* .... */
-	gen_task_ev.ev_type = MY_TASK_TASK_EVENT;
-	os_task_init(&gen_task_str, "gen_task", gen_task, NULL, GEN_TASK_PRIO,
-	    OS_WAIT_FOREVER, gen_task_stack, GEN_TASK_STACK_SZ);
-}
-```
 
-<br>
+    /* Create a task to generate events to toggle the LED at pin TASK_LED */
 
-#### Callout events
+    os_task_init(&gen_task_str, "gen_task", gen_task, NULL, GEN_TASK_PRIO,
+                 OS_WAIT_FOREVER, gen_task_stack, GEN_TASK_STACK_SZ);
 
-You can get timer events delivered to your task's event queue with OS callout. Check [callout documentation](../core_os/callout/callout.md) for description on how to use the API.
+      ...
 
-For this example, you'll use only one type of callout; so you can use the simpler structure.
+}
 
-In the code snippet we declare the os_callout structure and initialize it. Then we arm the timer.
+```
+<br>
+Implement the application `main()` function to call the `os_eventq_run()` function to dequeue an event from the Mynewt default event queue and call the callback function to process the event. 
 
 ```c
-static struct os_callout my_callout;
 
-void
-init_tasks(void)
+int
+main(int argc, char **argv)
 {
-	/* .... */
-
-	os_callout_init(&my_callout, &my_eventq, NULL);
-	os_callout_reset(&my_callout, OS_TICKS_PER_SEC);
+    sysinit();
+
+    init_tasks();
+  
+    while (1) {
+       os_eventq_run(os_eventq_dflt_get());     
+    }
+    assert(0);
 }
 
 ```
 
 <br>
+#### OS Callout Timer Events
+
+Set up OS callout timer events. For this example, we use a dedicated event queue for timer events to show you how to create a dedicated event queue and a task to process the events.
+
 
+Implement the `my_timer_ev_cb()` callback function to process a timer event and toggle the LED at pin `CALLOUT_LED`:
 
-#### Posting events from interrupt handler
+```c
+
+/* LED 2 (P0.18 on the board) */
+#define CALLOUT_LED     18
 
-Another place where posting events makes sense is from an interrupt handler. In this tutorial you will do it when GPIO changes state.
+/* The timer callout */
+static struct os_callout my_callout;
 
-You'll use HAL GPIO interface to register a routine which is getting called from the interrupt handler context. This routine will then post event to your queue.
+/*
+ * Event callback function for timer events. It toggles the LED at pin CALLOUT_LED.
+ */
+static void my_timer_ev_cb(struct os_event *ev)
+{
+    assert(ev != NULL);
+  
+    hal_gpio_toggle(CALLOUT_LED);
+       
+    os_callout_reset(&my_callout, OS_TICKS_PER_SEC / 2);
+}
 
-On STM32F3Discovery board, there is a button connected to PA0. The identifier for this GPIO pin is 0.
+```
+<br>
+In the `init_tasks()` function, initialize the `my_timer_interrupt_eventq` event queue, create a task to process events from the queue, and initialize the OS callout for the timer: 
 
 ```c
-static struct os_event gpio_ev;
+#define MY_TIMER_INTERRUPT_TASK_PRIO  4
+#define MY_TIMER_INTERRUPT_TASK_STACK_SZ    512
 
-void
+static os_stack_t my_timer_interrupt_task_stack[MY_TIMER_INTERRUPT_TASK_STACK_SZ];
+static struct os_task my_timer_interrupt_task_str;
+
+static void
 init_tasks(void)
 {
-	/* .... */
+    /* Use a dedicate event queue for timer and interrupt events */
+ 
+    os_eventq_init(&my_timer_interrupt_eventq);  
+
+    /* 
+     * Create the task to process timer and interrupt events from the
+     * my_timer_interrupt_eventq event queue.
+     */
+    os_task_init(&my_timer_interrupt_task_str, "timer_interrupt_task", 
+                 my_timer_interrupt_task, NULL, 
+                 MY_TIMER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, 
+                 my_timer_interrupt_task_stack, 
+                 MY_TIMER_INTERRUPT_TASK_STACK_SZ);
+     /* 
+      * Initialize the callout for a timer event.  
+      * The my_timer_ev_cb callback function processes the timer events.
+      */
+    os_callout_init(&my_callout, &my_timer_interrupt_eventq,  
+                    my_timer_ev_cb, NULL);
+
+    os_callout_reset(&my_callout, OS_TICKS_PER_SEC);
 
-	gpio_ev.ev_type = MY_TASK_GPIO_EVENT;
-	hal_gpio_irq_init(0, my_gpio_irq, NULL, GPIO_TRIG_RISING,
-	    GPIO_PULL_NONE);
-	hal_gpio_irq_enable(0);
 }
+```
+<br>
+Implement the `my_timer_interrupt_task()` task handler to dispatch events from the `my_timer_interrupt_eventq` event queue:
+
+```c
 
 static void
-my_gpio_irq(void *arg)
+my_timer_interrupt_task(void *arg)
 {
-	os_eventq_put(&my_eventq, &gpio_ev);
+    while (1) {
+        os_eventq_run(&my_timer_interrupt_eventq);
+    }
 }
-```
 
+```
 <br>
+#### Interrupt Events
 
-#### Event processing finalized
+The application toggles the LED each time button 1 on the board is pressed.  The interrupt handler generates an event when the GPIO for button 1 (P0.13) changes state. The events are added to the `my_timer_interrupt_eventq` event queue, the same queue as the timer events.
 
-Now that you are posting events from different sources, you will fill in the parts in the task main loop to trigger different behaviors depending on event type.
+Declare and initialize the `gpio_ev` event with the `my_interrupt_ev_cb()` callback function to process the event:
 
-You'll drive different LEDs depending on what type of event arrived. LEDs on this board are connected to PE8, PE9, PE10 and so on. These have GPIO identifiers starting from 72 onwards.
+```c
+static struct os_event gpio_ev {
+    .ev_cb = my_interrupt_ev_cb,
+};
+
+```
+<br>
+Implement the `my_interrupt_ev_cb()` callback function to process an interrupt event and toggle the LED at pin `GPIO_LED`:
 
 ```c
-#define TASK_LED		72
-#define CALLOUT_LED		73
-#define GPIO_LED		74
 
-void
-init_tasks(void)
+/* LED 3 (P0.19 on the board) */
+#define GPIO_LED     19
+
+/*
+ * Event callback function for interrupt events. It toggles the LED at pin GPIO_LED.
+ */
+static void my_interrupt_ev_cb(struct os_event *ev)
 {
-	/* .... */
-	hal_gpio_init_out(TASK_LED, 1);
-	hal_gpio_init_out(CALLOUT_LED, 1);
-	hal_gpio_init_out(GPIO_LED, 1);
+    assert(ev != NULL);
+    
+    hal_gpio_toggle(GPIO_LED);
 }
 ```
+<br>
 
-And here is the new main loop for your task. Note that when callout event arrives, we re-arm the callout.
+Implement the `my_gpio_irq()` handler to post an interrupt event to the `my_timer_interrupt_eventq` event queue:
 
 ```c
-void
-my_task(void *arg)
+static void
+my_gpio_irq(void *arg)
 {
-	struct os_event *ev;
-    
-	while (1) {
-		ev = os_eventq_get(&my_eventq);
-		switch (ev->ev_type) {
-		case MY_TASK_TASK_EVENT:
-			hal_gpio_toggle(TASK_LED);
-			break;
-		case OS_EVENT_T_TIMER:
-			hal_gpio_toggle(CALLOUT_LED);
-			os_callout_reset(&my_callout, OS_TICKS_PER_SEC / 2);
-			break;
-		case MY_TASK_GPIO_EVENT:
-			hal_gpio_toggle(GPIO_LED);
-			break;
-		default:
-			assert(0);
-		}
-	}
+    os_eventq_put(&my_timer_interrupt_eventq, &gpio_ev);
 }
 ```
-
 <br>
 
-Now you're done. Once you load this to your board, the task LED will blink at an interval of 250ms, the callout LED with an interval of 500ms, and the GPIO LED every time you press the button.
+In the `init_tasks()` function, add the code to set up and enable the GPIO input pin for the button and initialize the GPIO output pins for the LEDs:
+
+```c
+/* LED 1 (P0.17 on the board) */
+#define TASK_LED        17 
+
+/*  2 (P0.18 on the board) */
+#define CALLOUT_LED     18 
+
+/* LED 3 (P0.19 on the board) */
+#define GPIO_LED        19
+
+/* Button 1 (P0.13 on the board) */
+#define BUTTON1_PIN     13
+
+void 
+init_tasks()
 
+    /* Initialize OS callout for timer events. */
+
+          ....
+
+    /* 
+     * Initialize and enable interrupts for the pin for button 1 and 
+     * configure the button with pull up resistor on the nrf52dk.
+     */ 
+    hal_gpio_irq_init(BUTTON1_PIN, my_gpio_irq, NULL, HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP);
+
+    hal_gpio_irq_enable(BUTTON1_PIN);
+
+    /* Initialize the GPIO output pins. Value 1 is off for these LEDs.  */
+   
+    hal_gpio_init_out(TASK_LED, 1);
+    hal_gpio_init_out(CALLOUT_LED, 1);
+    hal_gpio_init_out(GPIO_LED, 1);
+}
+```
 <br>
+### Putting It All Together
+
+Here is the complete `main.c` source for your application.  Build the application and load it on your board. The task LED (LED1) blinks at an interval of 250ms, the callout LED (LED2) blinks at an interval of 500ms, and the GPIO LED (LED3) toggles on or off each time you press Button 1.
 
-### Code for the example
 
 ```c
 #include <os/os.h>
 #include <bsp/bsp.h>
 #include <hal/hal_gpio.h>
 #include <assert.h>
+#include <sysinit/sysinit.h>
+
 
+#define MY_TIMER_INTERRUPT_TASK_PRIO  4
+#define MY_TIMER_INTERRUPT_TASK_STACK_SZ    512
 
-#define MY_TASK_PRIO		4
-#define MY_TASK_STACK_SZ	512
+#define GEN_TASK_PRIO       3
+#define GEN_TASK_STACK_SZ   512
 
-#define GEN_TASK_PRIO		3
-#define GEN_TASK_STACK_SZ	512
+/* LED 1 (P0.17 on the board) */
+#define TASK_LED        17
 
-#define MY_TASK_GPIO_EVENT	(OS_EVENT_T_PERUSER)
-#define MY_TASK_TASK_EVENT	(OS_EVENT_T_PERUSER + 1)
+/* LED 2 (P0.18 on the board) */
+#define CALLOUT_LED     18
 
-#define TASK_LED		72
-#define CALLOUT_LED		73
-#define GPIO_LED		74
+/* LED 3 (P0.19 on the board) */
+#define GPIO_LED        19
 
-static struct os_eventq my_eventq;
-static os_stack_t my_task_stack[MY_TASK_STACK_SZ];
-static struct os_task my_task_str;
+/* Button 1 (P0.13 on the board) */
+#define BUTTON1_PIN     13
+
+
+static void my_ev_cb(struct os_event *);
+static void my_timer_ev_cb(struct os_event *);
+static void my_interrupt_ev_cb(struct os_event *);
+
+static struct os_eventq my_timer_interrupt_eventq;
+
+static os_stack_t my_timer_interrupt_task_stack[MY_TIMER_INTERRUPT_TASK_STACK_SZ];
+static struct os_task my_timer_interrupt_task_str;
 
-static struct os_event gen_task_ev;
 static os_stack_t gen_task_stack[GEN_TASK_STACK_SZ];
 static struct os_task gen_task_str;
 
+static struct os_event gen_task_ev = {
+    .ev_cb = my_ev_cb,
+};
+
+static struct os_event gpio_ev = {
+    .ev_cb = my_interrupt_ev_cb,
+};
+
+
 static struct os_callout my_callout;
 
-static struct os_event gpio_ev;
+/*
+ * Task handler to generate an event to toggle the LED at pin TASK_LED.
+ * The event is added to the Mynewt default event queue.
+ */
 
-void
-my_task(void *arg)
+static void
+gen_task(void *arg)
+{
+    while (1) {
+        os_time_delay(OS_TICKS_PER_SEC / 4);
+        os_eventq_put(os_eventq_dflt_get(), &gen_task_ev);
+    }
+}
+
+/*
+ * Event callback function for events generated by gen_task. It toggles the LED at pin TASK_LED. 
+ */
+static void my_ev_cb(struct os_event *ev)
+{
+    assert(ev);
+    hal_gpio_toggle(TASK_LED);
+    return;
+}
+
+/*
+ * Event callback function for timer events. It toggles the LED at pin CALLOUT_LED.
+ */
+static void my_timer_ev_cb(struct os_event *ev)
 {
-	struct os_event *ev;
-
-	while (1) {
-		ev = os_eventq_get(&my_eventq);
-		switch (ev->ev_type) {
-		case MY_TASK_TASK_EVENT:
-			hal_gpio_toggle(TASK_LED);
-			break;
-		case OS_EVENT_T_TIMER:
-			hal_gpio_toggle(CALLOUT_LED);
-			os_callout_reset(&my_callout, OS_TICKS_PER_SEC / 2);
-			break;
-		case MY_TASK_GPIO_EVENT:
-			hal_gpio_toggle(GPIO_LED);
-			break;
-		default:
-			assert(0);
-		}
-	}
+    assert(ev != NULL);
+  
+    hal_gpio_toggle(CALLOUT_LED);
+    os_callout_reset(&my_callout, OS_TICKS_PER_SEC / 2);
+}
+
+/*
+ * Event callback function for interrupt events. It toggles the LED at pin GPIO_LED.
+ */
+static void my_interrupt_ev_cb(struct os_event *ev)
+{
+    assert(ev != NULL);
+    
+    hal_gpio_toggle(GPIO_LED);
 }
 
 static void
 my_gpio_irq(void *arg)
 {
-	os_eventq_put(&my_eventq, &gpio_ev);
+    os_eventq_put(&my_timer_interrupt_eventq, &gpio_ev);
 }
 
-void
-gen_task(void *arg)
+
+
+static void
+my_timer_interrupt_task(void *arg)
 {
-	while (1) {
-		os_time_delay(OS_TICKS_PER_SEC / 4);
-		os_eventq_put(&my_eventq, &gen_task_ev);
-	}
+    while (1) {
+        os_eventq_run(&my_timer_interrupt_eventq);
+    }
 }
 
 void
 init_tasks(void)
 {
-	os_eventq_init(&my_eventq);
-	os_task_init(&my_task_str, "task", my_task, NULL, MY_TASK_PRIO,
-	    OS_WAIT_FOREVER, my_task_stack, MY_TASK_STACK_SZ);
+    
+    /* Create a task to generate events to toggle the LED at pin TASK_LED */
+
+    os_task_init(&gen_task_str, "gen_task", gen_task, NULL, GEN_TASK_PRIO,
+        OS_WAIT_FOREVER, gen_task_stack, GEN_TASK_STACK_SZ);
+
 
-	gen_task_ev.ev_type = MY_TASK_TASK_EVENT;
-	os_task_init(&gen_task_str, "gen_task", gen_task, NULL, GEN_TASK_PRIO,
-	    OS_WAIT_FOREVER, gen_task_stack, GEN_TASK_STACK_SZ);
+    /* Use a dedicate event queue for timer and interrupt events */
+    os_eventq_init(&my_timer_interrupt_eventq);  
 
-	os_callout_init(&my_callout, &my_eventq, NULL);
-	os_callout_reset(&my_callout, OS_TICKS_PER_SEC);
+    /* 
+     * Create the task to process timer and interrupt events from the
+     * my_timer_interrupt_eventq event queue.
+     */
+    os_task_init(&my_timer_interrupt_task_str, "timer_interrupt_task", 
+                 my_timer_interrupt_task, NULL, 
+                 MY_TIMER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, 
+                 my_timer_interrupt_task_stack, 
+                 MY_TIMER_INTERRUPT_TASK_STACK_SZ);
 
-	gpio_ev.ev_type = MY_TASK_GPIO_EVENT;
-	hal_gpio_irq_init(0, my_gpio_irq, NULL, GPIO_TRIG_RISING,
-	    GPIO_PULL_NONE);
-	hal_gpio_irq_enable(0);
+    /* 
+     * Initialize the callout for a timer event.  
+     * The my_timer_ev_cb callback function processes the timer event.
+     */
+    os_callout_init(&my_callout, &my_timer_interrupt_eventq,  
+                    my_timer_ev_cb, NULL);
 
-	hal_gpio_init_out(TASK_LED, 1);
-	hal_gpio_init_out(CALLOUT_LED, 1);
-	hal_gpio_init_out(GPIO_LED, 1);
+    os_callout_reset(&my_callout, OS_TICKS_PER_SEC);
+
+    /* 
+     * Initialize and enable interrupt for the pin for button 1 and 
+     * configure the button with pull up resistor on the nrf52dk.
+     */ 
+    hal_gpio_irq_init(BUTTON1_PIN, my_gpio_irq, NULL, HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP);
+
+    hal_gpio_irq_enable(BUTTON1_PIN);
+
+    hal_gpio_init_out(TASK_LED, 1);
+    hal_gpio_init_out(CALLOUT_LED, 1);
+    hal_gpio_init_out(GPIO_LED, 1);
 }
 
 int
 main(int argc, char **argv)
 {
-	os_init();
-
-	init_tasks();
-	os_start();
-	assert(0);
-	return 0;
+    sysinit();
+
+    init_tasks();
+  
+    while (1) {
+       os_eventq_run(os_eventq_dflt_get());     
+    }
+    assert(0);
 }
 
 ```

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/f9e50056/mkdocs.yml
----------------------------------------------------------------------
diff --git a/mkdocs.yml b/mkdocs.yml
index b69741f..cb27b88 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -46,7 +46,10 @@ pages:
         - 'Tasks and Priority Management': 'os/tutorials/tasks_lesson.md'
         - 'Enable Wi-Fi on Arduino Zero': 'os/tutorials/wi-fi_on_arduino.md'
         - 'Write a Test Suite for a Package': 'os/tutorials/unit_test.md'
-        - 'Add task to manage multiple events': 'os/tutorials/event_queue.md'
+        - 'Air-quality Sensor project': 
+            - 'Basic Air Quality Sensor': 'os/tutorials/air_quality_sensor.md'
+            - 'Bluetooth-enabled Air Quality Sensor': 'os/tutorials/air_quality_ble.md'
+        - 'Events and Event Queues': 'os/tutorials/event_queue.md'
         - 'Project Slinky for remote comms':
             - 'Slinky on sim device': 'os/tutorials/project-slinky.md'
             - 'Slinky on STM32 board': 'os/tutorials/project-target-slinky.md'
@@ -109,8 +112,9 @@ pages:
                     - 'os_eventq_get': 'os/core_os/event_queue/os_eventq_get.md'
                     - 'os_eventq_put': 'os/core_os/event_queue/os_eventq_put.md'
                     - 'os_eventq_remove': 'os/core_os/event_queue/os_eventq_remove.md'
-                    - 'os_eventq_dflt_set': 'os/core_os/event_queue/os_eventq_dflt_set.md'
                     - 'os_eventq_dflt_get': 'os/core_os/event_queue/os_eventq_dflt_get.md'
+                    - 'os_eventq_designate': 'os/core_os/event_queue/os_eventq_designate.md'
+                    - 'os_eventq_run': 'os/core_os/event_queue/os_eventq_run.md'
             - Semaphores:
                 - toc: 'os/core_os/semaphore/semaphore.md'
                 - 'Functions':