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 2016/07/05 23:14:09 UTC

[2/2] incubator-mynewt-site git commit: Added a sample lesson unit under Tutorials in the develop version of documentation only

Added a sample lesson unit under Tutorials in the develop version of documentation only


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/b3005c0b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/tree/b3005c0b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/diff/b3005c0b

Branch: refs/heads/asf-site
Commit: b3005c0bd34a1dc0fcda05aa5bd740f053539a5b
Parents: c60c004
Author: aditihilbert <ad...@runtime.io>
Authored: Tue Jul 5 16:13:53 2016 -0700
Committer: aditihilbert <ad...@runtime.io>
Committed: Tue Jul 5 16:13:53 2016 -0700

----------------------------------------------------------------------
 community/index.html                            |   7 +-
 develop/mkdocs/search_index.json                |  90 +++
 develop/os/tutorials/STM32F303/index.html       |  13 +
 .../os/tutorials/air_quality_sensor/index.html  |  13 +
 develop/os/tutorials/arduino_zero/index.html    |  13 +
 develop/os/tutorials/blehci_project/index.html  |  13 +
 .../os/tutorials/bleprph/bleprph-adv/index.html |  13 +
 .../bleprph/bleprph-chr-access/index.html       |  13 +
 .../tutorials/bleprph/bleprph-conn/index.html   |  13 +
 .../tutorials/bleprph/bleprph-intro/index.html  |  13 +
 .../bleprph/bleprph-svc-reg/index.html          |  13 +
 develop/os/tutorials/bletiny_project/index.html |  13 +
 develop/os/tutorials/blinky_primo/index.html    |  13 +
 .../os/tutorials/blinky_sram_olimex/index.html  |  13 +
 develop/os/tutorials/event_queue/index.html     |  13 +
 develop/os/tutorials/ibeacon/index.html         |  13 +
 develop/os/tutorials/nRF52/index.html           |  13 +
 develop/os/tutorials/olimex/index.html          |  13 +
 develop/os/tutorials/pics/task_lesson.png       | Bin 0 -> 12445 bytes
 develop/os/tutorials/pin-wheel-mods/index.html  |  13 +
 develop/os/tutorials/project-slinky/index.html  |  13 +
 .../tutorials/project-target-slinky/index.html  |  13 +
 develop/os/tutorials/repo/add_repos/index.html  |  13 +
 .../os/tutorials/repo/create_repo/index.html    |  17 +-
 .../os/tutorials/repo/upgrade_repo/index.html   |  13 +
 develop/os/tutorials/tasks_lesson/index.html    | 792 +++++++++++++++++++
 develop/os/tutorials/tutorials/index.html       |  13 +
 develop/os/tutorials/unit_test/index.html       |  17 +-
 index.html                                      |   3 +
 29 files changed, 1205 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/community/index.html
----------------------------------------------------------------------
diff --git a/community/index.html b/community/index.html
index 58e3c36..513ceff 100644
--- a/community/index.html
+++ b/community/index.html
@@ -204,12 +204,12 @@
 
                 <h3>Contributing Code</h3>
                 <p>
-                You can start contributing right away, even if you are not a committer on Apache Mynewt! One requirement is that you adhere to the Apache's proposed workflow as explained <a href="https://git-wip-us.apache.org/docs/workflow.html">here</a>. Basically, you submit your initial edits for your peers to review and merge. After a few successful patches under your belt, you will get access to commit code directly to the module you are working on in the repository. And over time, you will get full access to all the repositories, where you can commit code to any module. </p>
+                You can start contributing right away, even if you are not a committer on Apache Mynewt! One requirement is that you adhere to the Apache's proposed workflow as explained <a href="https://git-wip-us.apache.org/docs/workflow.html">here</a>. Basically, you submit your initial edits for your peers to review and merge. After a few successful patches under your belt, you will get access to commit code directly to the module you are working on in the repository. And over time, you will get full access to all the repositories, where you can commit code to any module on the apache git repository (and not the github mirror). </p>
                 <p>You may choose to submit patches in one of the two following ways:
                 <br>
                 <ol>
                 <li>
-                Fork the mirrored repository to create your very own repo on github. Clone the forked repository into a local branch on your machine and make your changes. Then submit a pull request from the fork on the github mirror of the appropriate Apache Mynewt repository by clicking the green "New pull request" button on the page:
+                Fork the mirrored repository to create your very own repo on github. Clone the forked repository into a local branch on your machine. <mark> Either checkout the `develop` branch and make your changes in the develop branch or create a new branch out of `develop` and work there.</mark> Then submit a <mark> pull request to the `develop` branch </mark> on the github mirror of the appropriate Apache Mynewt repository by clicking the green "New pull request" button on your github fork page:
                    <ul>
                    <br>
                    <li><a href="https://github.com/apache/incubator-mynewt-larva">Apache Mynewt larva repo mirrored on github</a></li>
@@ -219,7 +219,8 @@
                    <li><a href="https://github.com/apache/incubator-mynewt-site">Apache Mynewt documentation repo mirrored on github</a></li>
                    <br>
                    </ul>
-                <p>In the comment for the pull request, include a description of the changes you have made and why. Github will automatically notify everyone on the commits@mynewt.incubator.apache.org mailing list about the newly opened pull requests. You can open a pull request even if you don't think the code is ready for merging but want some discussion on the matter. </p>
+                <p> <mark>The bottomline is to work with the `develop` branch. </mark> It has the latest code and you want your changes tested, working, and merged with that codebase. In the comment for the pull request, include a description of the changes you have made and why. Github will automatically notify everyone on the commits@mynewt.incubator.apache.org mailing list about the newly opened pull requests. You can open a pull request even if you don't think the code is ready for merging but want some discussion on the matter. </p>
+                <p> If you have already submitted a pull request against the `develop` branch on the mirror but have modified your code futher (e.g. after some feedback from the community or another clever idea popping into your head) <mark> there is no need to open a new pull request</mark>. The old pull request will get updated with your changes. Always remember to <mark> fetch the latest code from `develop` before committing your changes to the branch.</mark> </p>
                 <p> Upon receiving notification, one or more committers will review your work, ask for edits or clarifications, and merge when your proposed changes are ready.</p>
                 </li>
                 <li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/mkdocs/search_index.json
----------------------------------------------------------------------
diff --git a/develop/mkdocs/search_index.json b/develop/mkdocs/search_index.json
index bb442eb..eebbd68 100644
--- a/develop/mkdocs/search_index.json
+++ b/develop/mkdocs/search_index.json
@@ -936,6 +936,96 @@
             "title": "Resolving dependencies"
         }, 
         {
+            "location": "/os/tutorials/tasks_lesson/", 
+            "text": "Core OS Lesson: Tasks and Priority Management\n\n\nTarget Platform: Arduino M0 Pro\n (or legacy Arduino Zero or Zero Pro, but not Arduino M0)\n\n\nThis lesson is designed to teach core OS concepts and strategies encountered when building applications using Mynewt. Specifically, this lesson will cover tasks, simple multitasking, and priority management running on an Arduino M0 Pro.\n\n\nPrerequisites\n\n\nBefore starting, you should read about Mynewt in the \nIntroduction\n section and complete the \nQuickStart\n guide and the \nBlinky\n tutorial. Furthermore, it may be helpful to take a peek at the \ntask documentation\n for additional insights.\n\n\nEquipment\n\n\nYou will need the following equipment:\n\n\n\n\nArduino M0 Pro (or legacy Arduino Zero or Zero Pro, but not Arduino M0)\n\n\nComputer with Mynewt installed\n\n\nUSB to Micro USB Cable\n\n\n\n\nBuild Your Application\n\n\nTo save time, we will simply modify the Blinky app as it has the basic task struc
 ture already implemented. Follow the \nArduino Zero Blinky tutorial\n to create a new project and build your bootloader and application. Finally, build and load the application to your Arduino to verify that everything is in order. Now let\u2019s get started!\n\n\nCreate a New Task\n\n\nThe purpose of this section is to give an introduction to the important aspects of tasks and how to properly initialize them. First, let\u2019s define a second task called \nwork_task\n in main.c (located in apps/blinky/src):\n\n\nstruct\n \nos_task\n \nwork_task\n;\n\n\n\n\n\nA task is represented by the \nos_task\n  struct which will hold the task\u2019s information (name, state, priority, etc.). A task is made up of two main elements, a task function (also known as a task handler) and a task stack.\n\n\nNext, let\u2019s take a look at what is required to initialize our new task.\n\n\nTask Stack\n\n\nThe task stack is an array of type \nos_stack_t\n which holds the program stack frames. Mynewt give
 s us the ability to set the stack size for a task giving the application developer room to optimize memory usage. Since we\u2019re not short on memory, our \nblinky_stack\n and \nwork_stack\n are plenty large for the purpose of this lesson. Notice that the elements in our task stack are of type \nos_stack_t\n which are generally 32 bits, making our entire stack 1024 Bytes.\n\n\n  \n#define WORK_STACK_SIZE OS_STACK_ALIGN(256)\n\n  \nos_stack_t\n \nwork_stack\n[\nWORK_STACK_SIZE\n];\n\n\n\n\n\nNote: The \nOS_STACK_ALIGN\n macro is used to align the stack based on the hardware architecture.\n\n\nTask Function\n\n\nThe task function is essentially an infinite loop which waits for some \u201cevent\u201d to wake it up. In our Blinky app the task function, named \nblinky_task_handler()\n, is initially called when we call \nos_start()\n in \nmain()\n. In general, the task function is where the majority of work is done by a task. Let\u2019s write a task function for \nwork_task\n called \nwo
 rk_task_handler()\n:\n\n\nvoid\n\n\nwork_task_handler\n(\nvoid\n \n*arg\n)\n{\n    \nstruct\n \nos_task\n \n*t\n;\n\n    \ng_led_pin\n \n=\n \nLED_BLINK_PIN\n;\n    \nhal_gpio_init_out\n(\ng_led_pin\n, \n1\n);\n\n    \nwhile\n (\n1\n) {\n        \nt\n \n=\n \nos_sched_get_current_task\n();\n        \nassert\n(\nt-\nt_func\n \n==\n \nwork_task_handler\n);\n        \n/* Do work... */\n\n    }\n}\n\n\n\n\n\nThe task function is called when the task is initially put into the\n\nrunning\n state by the scheduler. We use an infinite loop to ensure that the task function never returns and assert that the current task\u2019s function is correct before doing any work.\n\n\nTask Priority\n\n\nAs a preemptive, multitasking RTOS, Mynewt decides which tasks to run based on which has a higher priority; the highest priority being 0 and the lowest 255. Thus, before initializing our task, we must choose a priority defined as a macro variable.\n\n\nLet\u2019s set the priority of \nwork_task\n to 0, be
 cause everyone knows that work is more important than blinking.\n\n\n  \n#define WORK_TASK_PRIO (0)\n\n\n\n\n\n\nInitialization\n\n\nTo initialize a new task we use \nos_task_init()\n which takes a number of arguments including our new task function, stack, and priority. Much like \nblinky_task\n, we\u2019re going to initialize \nwork_task\n inside \ninit_tasks\n to keep our main function clean.\n\n\nint\n\n\ninit_tasks\n(\nvoid\n)\n{\n    \n/* \u2026 */\n\n    \nos_task_init\n(\nwork_task\n, \nwork\n, \nwork_task_handler\n, \nNULL\n,\n            \nWORK_TASK_PRIO\n, \nOS_WAIT_FOREVER\n, \nwork_stack\n,\n            \nWORK_STACK_SIZE\n);\n\n    \ntasks_initialized\n \n=\n \n1\n;\n    \nreturn\n \n0\n;\n}\n\n\n\n\n\nReview\n\n\nBefore we run our new app, let\u2019s review what we need in order to create a task:\n\n\n1)\n   Define a new task, task stack, and priority\n\n\n/* My Task */\n\n\nos_task\n \nmytask\n\n\n/* My Task Stack */\n\n\n#define MYTASK_STACK_SIZE OS_STACK_ALIGN(256)\
 n\n\nos_stack_t\n \nmytask_stack\n[\nMYTASK_STACK_SIZE\n];\n\n/* My Task Priority */\n\n\n#define MYTASK_PRIO (0)\n\n\n\n\n\n\n2)\n Define task function\n\n\nvoid\n \n\nmytask_handler\n(\nvoid\n \n*arg\n)\n{\n    \n/* ... */\n\n}\n\n\n\n\n\n3)\n Initialize task before calling \nos_start()\n\n\nos_task_init\n(\nmytask\n, \nmytask\n, \nmytask_handler\n, \nNULL\n, \n            \nMYTASK_PRIO\n, \nOS_WAIT_FOREVER\n, \nmytask_stack\n,\n            \nMYTASK_STACK_SIZE\n);\n\n\n\n\n\nAnd that\u2019s it! Run your application and \u2026 \nwait, why doesn't our LED blink anymore?\n\n\nTask Priority, Preempting, and Context Switching\n\n\nA preemptive RTOS is one in which a higher priority task that is \nready to run\n will preempt (i.e. take the place of) the lower priority task which is \nrunning\n. When a lower priority task is preempted by a higher priority task, the lower priority task\u2019s context data (stack pointer, registers, etc.) is saved and the new task is switched in.\n\n\nIn o
 ur example, \nwork_task\n has a higher priority than \nblinky_task\n and, because it is never put into a \nsleep\n state, holds the processor focus on its context. Let\u2019s give \nwork_task\n a delay and some simulated work to keep it busy. Because the delay is measured in os ticks, the actual number of ticks per second is dependent on the board. Therefore, we multiply \nOS_TICKS_PER_SEC\n, which is defined in the MCU, by the number of seconds we wish to delay.\n\n\nvoid\n\n\nwork_task_handler\n(\nvoid\n \n*arg\n)\n{\n    \nstruct\n \nos_task\n \n*t\n;\n\n    \ng_led_pin\n \n=\n \nLED_BLINK_PIN\n;\n    \nhal_gpio_init_out\n(\ng_led_pin\n, \n1\n);\n\n    \nwhile\n (\n1\n) {\n        \nt\n \n=\n \nos_sched_get_current_t\n:ask\n();\n        \nassert\n(\nt-\nt_func\n \n==\n \nwork_task_handler\n);\n        \n/* Do work... */\n\n        \nint\n \ni\n;\n        \nfor\n(\ni\n \n=\n \n0\n; \ni\n \n \n1000000\n; \n++i\n) {\n            \n//simulate doing a noticeable amount of work\n\n    
         \nhal_gpio_set\n(\ng_led_pin\n);\n        }\n        \nos_time_delay\n(\n3\n*OS_TICKS_PER_SECOND\n);\n    }\n}\n\n\n\n\n\nIn order to notice the LED changing, modify the time delay in \nblinky_task_handler()\n to blink at a higher frequency.\n\n\nos_time_delay\n(\n100\n);\n\n\n\n\n\nBefore we run the app, let\u2019s predict the behavior. With the newest\nadditions to \nwork_task_handler()\n, our first action will be to sleep for three seconds. This will allow \nblinky_task\n to take over the CPU and blink to its heart\u2019s content. After three seconds, \nwork_task\n will wake up and be made \nready to run\n, causing it to preempt \nblinky_task\n. The LED will then remain lit for a short period while \nwork_task\n loops, then blink again for another three seconds while \nwork_task\n sleeps. \n\n\nViola, you should see that our prediction was correct! What would happen when both priorities are the same? Try it out for yourself!\n\n\nPriority Management Considerations\n\n\nWh
 en projects grow in scope, from blinking LEDs into more sophisticated applications, the number of tasks needed increases alongside complexity. It remains important, then, that each of our tasks is capable of doing its work within a reasonable amount of time.\n\n\nSome tasks, such as the Shell task, execute quickly and require almost instantaneous response. Therefore, the Shell task should be given a high priority. On the other hand, tasks which may be communicating over a network, or processing data, should be given a low priority in order to not hog the CPU.\n\n\nThe diagram below showcases the different scheduling patterns we. would expect from swapping blinky and work tasks priorities.\n\n\n\n\nIn the second case where \nblinky_task\n has a higher priority, the \u201cwork\u201d done by \nwork_task\n would be executed during the millisecond delays in \nblinky_task\n, saving us idle time compared to the first case.\n\n\nComparing Priority Strategies\n\n\nInstead of stepping through
  a bunch of changes to our blinky app, clone my task lesson application from github and copy an existing target.\n\n\nChange directory into apps and clone the repository to get our new\nfiles:\n\n\n$ cd apps\n$ git clone https://github.com/bgiori/mynewt_tasks_lesson.git\n\n\n\n\n\nChange directory back to your project root and copy  the arduino_blinky target to a new target called task_tgt.\n\n\n$\n \nnewt\n \ntarget\n \ncopy\n \narduino_blinky\n \ntask_tgt\n\n\n\n\n\n\nSet a new app location.\n\n\n$\n \nnewt\n \ntarget\n \nset\n \ntask_tgt\n \napp=apps/mynewt_tasks_lesson\n\n\n\n\n\n\nNow let\u2019s take a look at our new code. First, notice that we have abandoned blinking, instead choosing to use the \nconsole\n and \nshell\n to follow our tasks through execution.\n\n\nAdditionally, we have a number of different tasks:\n\n\n\n\n\n\nTask A\n (\na_task\n):\n\n\n\n\nPriority\n: 3 \u2192 2\n\n\nDescription\n: Task A is supposed to represent a task which frequently does a small amount 
 of work, such as one which rapidly polls a sensor for data. Much like \nblinky_task\n, Task A will loop 10,000 times then wait 1 millisecond. Priority is changed by \ntimer_task\n after the first simulation.\n\n\n\n\n\n\n\n\nTask B\n (\nb_task\n):\n\n\n\n\nPriority\n: 2 \u2192 3\n\n\nDescription\n: Task B is supposed to represent a task which does a large amount of work relatively infrequently, such as one which sends/receives data from the cloud. Like work_task, Task B will loop 1,000,000 times then wait 3 seconds. Priority is changed by timer_task after the first simulation.\n\n\n\n\n\n\n\n\nTimer Task\n (\ntimer_task\n):\n\n\n\n\nPriority\n: 1\n\n\nDescription\n: With default settings, Timer Task will wait 20 seconds then print the first simulations data for Task A and B. Timer task will then swap A and B\u2019s priorities and restart the simulation. After the second simulation, timer will again print simulation data then compare the two and calculate a final speedup (simulation2
  / simulation1).\n\n\n\n\n\n\n\n\nShell Task\n:\n\n\n\n\nPriority\n: 0\n\n\nDescription\n: Task used by Shell behind the scenes to communicate with the serial port.\n\n\n\n\n\n\n\n\nConnecting to the Serial Console\n\n\nBefore running our new app, we must first connect to the serial console. First make sure the mynewt_arduino_zero repository is set to the develop branch. (Remove once changes have been moved to master). \n\n\n$ cd repos/mynewt_arduino_zero\n$ git checkout develop\n\n\n\n\n\nOpen a new terminal window and list your serial connections to find our Arduino.\n\n\n$\n \nls\n \n/dev/tty\n.\n*\n\n\n\n/dev/tty\n.\nBluetooth-Incoming-Port\n \n/dev/tty\n.\nusbmodem14132\n\n\n\n\n\n\nIn the same window, connect to the serial port using a serial communication program. In this case I\u2019ll be using mincom as it can scroll through output.\n\n\n$\n \nminicom\n \n-D\n \n/dev/tty\n.\nusbmodem14132\n \n-b\n \n115200\n\n\n\n\n\n\nIf you see minicom welcome you, you\u2019re ready to mo
 ve on!\n\n\nOutput Analysis\n\n\nRun our new target, task_sim, and you should see an output similar to this:\n\n\nStarting First Simulation...\n1:     Task B: 0% \n78:     Task B: 1% \n155:     Task B: 2% \n257:     Task B: 3% \n359:     Task B: 4% \n461:     Task B: 5% \n\n\nsnip\n\n\n========== Timer Expired ==========\n\n \n Task A \n\n  Priority: 3\n  Loop count: 162849\n  Cycle count: 16.28\n  Run time: 1.40 sec\n\n \n Task B \n\n  Priority: 2\n  Loop count: 1345852\n  Cycle count: 1.34\n  Run time: 17.0 sec\n\n Total loops: 1508709\n\n20023:   Switching priorities and restarting...\n20111:   Task A looped\n20113:     Task B: 0% \n20191:     Task B: 1% \n20297:   Task A looped\n20356:     Task B: 2% \n20483:   Task A looped\n20545:     Task B: 3% \n20669:   Task A looped\n20734:     Task B: 4% \n20855:   Task A looped\n20923:     Task B: 5% \n\n\nsnip\n\n\n========== Timer Expired ==========\n\n \n Task A \n\n  Priority: 2\n  Loop count: 1080000\n  Cycle count: 108.0\n  Run tim
 e: 9.28 sec\n\n \n Task B \n\n  Priority: 3\n  Loop count: 830356\n  Cycle count: 0.83\n  Run time: 10.72 sec\n\n Total loops: 1910404\n\n40058:\n\n Final Speedup (Sim2 / Sim1): 1.26\n\n\n\n\n\nThe console output reaffirms our previous prediction and makes both the scheduling differences and subsequent efficiency boost far more apparent. Let\u2019s take a look at scheduling differences before we delve into efficiency.\n\n\nIn the first case, where Task B\u2019s priority is higher than that of Task A, we see A get starved by Task B\u2019s long execution time. \nStarvation\n occurs when one task hogs the processor, essentially \u201cstarving\u201d other tasks which also need to run. At the end of the first 20 second simulation period, Task A has only run for 1.4 seconds compared to task B\u2019s 17 second running time \u2013 ouch. As explained before, processes which are expected to run for long periods of time (e.g. network communication, data processing) should be given higher prior
 ities in order to combat starvation.\n\n\nIn the second simulation with priorities swapped, we can see Task B only running during the millisecond delays when Task A is \nsleeping\n. Although having Task B only run during these delays slows its execution time, we benefit from un-starving Task A and using the processor at a higher efficiency.\n\n\nThe bottom line speedup gives us an immediate and clear indication that we have improved our ability to process work (i.e throughput). In our second run, we processed an additional 400,000 loop iterations, equating to a 26% increase in efficiency. On a standard multi-core processor found in every modern PC, a 1.26 speedup would be an ok result to adding multithreading capabilities to a serial program. However, we accomplished this by simply setting priorities on a single core processor \u2013 not bad!\n\n\nNOTE: Usually the the term \u201cspeedup\u201d is used within a parallel programming context and refers to the change in execution time b
 etween a serial and parallel program executing over the same problem. In this case we\u2019re using the term loosely to illustrate the priority change\u2019s effect on scheduling and throughput in our specific context.\n\n\nEfficiency Isn\u2019t Everything\n\n\nUsing the processor during every OS tick isn\u2019t always the best course of action. If we modify Task A\u2019s delay to a tenth of a millisecond and turn off the console output, we can boost our speedup to 1.44. This, however, reduces our ability to process work from Task B who ends up only completing 18% of its work cycle after the second simulation. That would mean, at that rate, Task B would take over a minute to finish one cycle.\n\n\nFeel free to play around with the testing parameters to study the different changes yourself!\n\n\nConclusion\n\n\nMoving forward, tasks are just the tip of the iceberg. The \nscheduler\n, \nevent queues\n, \nsemaphores\n, and \nmutexes\n also add to tasks functionality, increasing our abi
 lity as the developer to control greater numbers of tasks more intricately. For example, when we switch the tasks priority, we have to tell the scheduler that our tasks priorities have changed, allowing us us to use priorities dynamically. When running multiple tasks, logging through either the built-in \nLogs\n module (not covered in this lesson) or through the serial console/shell can be very useful for debugging your application. In the end, the way you manage your tasks depends on the context of your application. You should assign priorities based on execution time, urgency, and frequency, among other things.\n\n\nKeep blinking and happy hacking!", 
+            "title": "Lesson Unit on Tasks and Priority Management"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#core-os-lesson-tasks-and-priority-management", 
+            "text": "Target Platform: Arduino M0 Pro  (or legacy Arduino Zero or Zero Pro, but not Arduino M0)  This lesson is designed to teach core OS concepts and strategies encountered when building applications using Mynewt. Specifically, this lesson will cover tasks, simple multitasking, and priority management running on an Arduino M0 Pro.", 
+            "title": "Core OS Lesson: Tasks and Priority Management"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#prerequisites", 
+            "text": "Before starting, you should read about Mynewt in the  Introduction  section and complete the  QuickStart  guide and the  Blinky  tutorial. Furthermore, it may be helpful to take a peek at the  task documentation  for additional insights.", 
+            "title": "Prerequisites"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#equipment", 
+            "text": "You will need the following equipment:   Arduino M0 Pro (or legacy Arduino Zero or Zero Pro, but not Arduino M0)  Computer with Mynewt installed  USB to Micro USB Cable", 
+            "title": "Equipment"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#build-your-application", 
+            "text": "To save time, we will simply modify the Blinky app as it has the basic task structure already implemented. Follow the  Arduino Zero Blinky tutorial  to create a new project and build your bootloader and application. Finally, build and load the application to your Arduino to verify that everything is in order. Now let\u2019s get started!", 
+            "title": "Build Your Application"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#create-a-new-task", 
+            "text": "The purpose of this section is to give an introduction to the important aspects of tasks and how to properly initialize them. First, let\u2019s define a second task called  work_task  in main.c (located in apps/blinky/src):  struct   os_task   work_task ;  A task is represented by the  os_task   struct which will hold the task\u2019s information (name, state, priority, etc.). A task is made up of two main elements, a task function (also known as a task handler) and a task stack.  Next, let\u2019s take a look at what is required to initialize our new task.", 
+            "title": "Create a New Task"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#task-stack", 
+            "text": "The task stack is an array of type  os_stack_t  which holds the program stack frames. Mynewt gives us the ability to set the stack size for a task giving the application developer room to optimize memory usage. Since we\u2019re not short on memory, our  blinky_stack  and  work_stack  are plenty large for the purpose of this lesson. Notice that the elements in our task stack are of type  os_stack_t  which are generally 32 bits, making our entire stack 1024 Bytes.     #define WORK_STACK_SIZE OS_STACK_ALIGN(256) \n   os_stack_t   work_stack [ WORK_STACK_SIZE ];  Note: The  OS_STACK_ALIGN  macro is used to align the stack based on the hardware architecture.", 
+            "title": "Task Stack"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#task-function", 
+            "text": "The task function is essentially an infinite loop which waits for some \u201cevent\u201d to wake it up. In our Blinky app the task function, named  blinky_task_handler() , is initially called when we call  os_start()  in  main() . In general, the task function is where the majority of work is done by a task. Let\u2019s write a task function for  work_task  called  work_task_handler() :  void  work_task_handler ( void   *arg )\n{\n     struct   os_task   *t ;\n\n     g_led_pin   =   LED_BLINK_PIN ;\n     hal_gpio_init_out ( g_led_pin ,  1 );\n\n     while  ( 1 ) {\n         t   =   os_sched_get_current_task ();\n         assert ( t- t_func   ==   work_task_handler );\n         /* Do work... */ \n    }\n}  The task function is called when the task is initially put into the running  state by the scheduler. We use an infinite loop to ensure that the task function never returns and assert that the current task\u2019s function is correct before doing any work.", 
+            "title": "Task Function"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#task-priority", 
+            "text": "As a preemptive, multitasking RTOS, Mynewt decides which tasks to run based on which has a higher priority; the highest priority being 0 and the lowest 255. Thus, before initializing our task, we must choose a priority defined as a macro variable.  Let\u2019s set the priority of  work_task  to 0, because everyone knows that work is more important than blinking.     #define WORK_TASK_PRIO (0)", 
+            "title": "Task Priority"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#initialization", 
+            "text": "To initialize a new task we use  os_task_init()  which takes a number of arguments including our new task function, stack, and priority. Much like  blinky_task , we\u2019re going to initialize  work_task  inside  init_tasks  to keep our main function clean.  int  init_tasks ( void )\n{\n     /* \u2026 */ \n     os_task_init ( work_task ,  work ,  work_task_handler ,  NULL ,\n             WORK_TASK_PRIO ,  OS_WAIT_FOREVER ,  work_stack ,\n             WORK_STACK_SIZE );\n\n     tasks_initialized   =   1 ;\n     return   0 ;\n}", 
+            "title": "Initialization"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#review", 
+            "text": "Before we run our new app, let\u2019s review what we need in order to create a task:  1)    Define a new task, task stack, and priority  /* My Task */  os_task   mytask  /* My Task Stack */  #define MYTASK_STACK_SIZE OS_STACK_ALIGN(256)  os_stack_t   mytask_stack [ MYTASK_STACK_SIZE ]; /* My Task Priority */  #define MYTASK_PRIO (0)   2)  Define task function  void   mytask_handler ( void   *arg )\n{\n     /* ... */ \n}  3)  Initialize task before calling  os_start()  os_task_init ( mytask ,  mytask ,  mytask_handler ,  NULL , \n             MYTASK_PRIO ,  OS_WAIT_FOREVER ,  mytask_stack ,\n             MYTASK_STACK_SIZE );  And that\u2019s it! Run your application and \u2026  wait, why doesn't our LED blink anymore?", 
+            "title": "Review"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#task-priority-preempting-and-context-switching", 
+            "text": "A preemptive RTOS is one in which a higher priority task that is  ready to run  will preempt (i.e. take the place of) the lower priority task which is  running . When a lower priority task is preempted by a higher priority task, the lower priority task\u2019s context data (stack pointer, registers, etc.) is saved and the new task is switched in.  In our example,  work_task  has a higher priority than  blinky_task  and, because it is never put into a  sleep  state, holds the processor focus on its context. Let\u2019s give  work_task  a delay and some simulated work to keep it busy. Because the delay is measured in os ticks, the actual number of ticks per second is dependent on the board. Therefore, we multiply  OS_TICKS_PER_SEC , which is defined in the MCU, by the number of seconds we wish to delay.  void  work_task_handler ( void   *arg )\n{\n     struct   os_task   *t ;\n\n     g_led_pin   =   LED_BLINK_PIN ;\n     hal_gpio_init_out ( g_led_pin ,  1 );\n\n    
  while  ( 1 ) {\n         t   =   os_sched_get_current_t :ask ();\n         assert ( t- t_func   ==   work_task_handler );\n         /* Do work... */ \n         int   i ;\n         for ( i   =   0 ;  i     1000000 ;  ++i ) {\n             //simulate doing a noticeable amount of work \n             hal_gpio_set ( g_led_pin );\n        }\n         os_time_delay ( 3 *OS_TICKS_PER_SECOND );\n    }\n}  In order to notice the LED changing, modify the time delay in  blinky_task_handler()  to blink at a higher frequency.  os_time_delay ( 100 );  Before we run the app, let\u2019s predict the behavior. With the newest\nadditions to  work_task_handler() , our first action will be to sleep for three seconds. This will allow  blinky_task  to take over the CPU and blink to its heart\u2019s content. After three seconds,  work_task  will wake up and be made  ready to run , causing it to preempt  blinky_task . The LED will then remain lit for a short period while  work_task  loops, then blink again 
 for another three seconds while  work_task  sleeps.   Viola, you should see that our prediction was correct! What would happen when both priorities are the same? Try it out for yourself!", 
+            "title": "Task Priority, Preempting, and Context Switching"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#priority-management-considerations", 
+            "text": "When projects grow in scope, from blinking LEDs into more sophisticated applications, the number of tasks needed increases alongside complexity. It remains important, then, that each of our tasks is capable of doing its work within a reasonable amount of time.  Some tasks, such as the Shell task, execute quickly and require almost instantaneous response. Therefore, the Shell task should be given a high priority. On the other hand, tasks which may be communicating over a network, or processing data, should be given a low priority in order to not hog the CPU.  The diagram below showcases the different scheduling patterns we. would expect from swapping blinky and work tasks priorities.   In the second case where  blinky_task  has a higher priority, the \u201cwork\u201d done by  work_task  would be executed during the millisecond delays in  blinky_task , saving us idle time compared to the first case.", 
+            "title": "Priority Management Considerations"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#comparing-priority-strategies", 
+            "text": "Instead of stepping through a bunch of changes to our blinky app, clone my task lesson application from github and copy an existing target.  Change directory into apps and clone the repository to get our new\nfiles:  $ cd apps\n$ git clone https://github.com/bgiori/mynewt_tasks_lesson.git  Change directory back to your project root and copy  the arduino_blinky target to a new target called task_tgt.  $   newt   target   copy   arduino_blinky   task_tgt   Set a new app location.  $   newt   target   set   task_tgt   app=apps/mynewt_tasks_lesson   Now let\u2019s take a look at our new code. First, notice that we have abandoned blinking, instead choosing to use the  console  and  shell  to follow our tasks through execution.  Additionally, we have a number of different tasks:    Task A  ( a_task ):   Priority : 3 \u2192 2  Description : Task A is supposed to represent a task which frequently does a small amount of work, such as one which rapidly polls a sensor for 
 data. Much like  blinky_task , Task A will loop 10,000 times then wait 1 millisecond. Priority is changed by  timer_task  after the first simulation.     Task B  ( b_task ):   Priority : 2 \u2192 3  Description : Task B is supposed to represent a task which does a large amount of work relatively infrequently, such as one which sends/receives data from the cloud. Like work_task, Task B will loop 1,000,000 times then wait 3 seconds. Priority is changed by timer_task after the first simulation.     Timer Task  ( timer_task ):   Priority : 1  Description : With default settings, Timer Task will wait 20 seconds then print the first simulations data for Task A and B. Timer task will then swap A and B\u2019s priorities and restart the simulation. After the second simulation, timer will again print simulation data then compare the two and calculate a final speedup (simulation2 / simulation1).     Shell Task :   Priority : 0  Description : Task used by Shell behind the scenes to communicate 
 with the serial port.", 
+            "title": "Comparing Priority Strategies"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#connecting-to-the-serial-console", 
+            "text": "Before running our new app, we must first connect to the serial console. First make sure the mynewt_arduino_zero repository is set to the develop branch. (Remove once changes have been moved to master).   $ cd repos/mynewt_arduino_zero\n$ git checkout develop  Open a new terminal window and list your serial connections to find our Arduino.  $   ls   /dev/tty . *  /dev/tty . Bluetooth-Incoming-Port   /dev/tty . usbmodem14132   In the same window, connect to the serial port using a serial communication program. In this case I\u2019ll be using mincom as it can scroll through output.  $   minicom   -D   /dev/tty . usbmodem14132   -b   115200   If you see minicom welcome you, you\u2019re ready to move on!", 
+            "title": "Connecting to the Serial Console"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#output-analysis", 
+            "text": "Run our new target, task_sim, and you should see an output similar to this:  Starting First Simulation...\n1:     Task B: 0% \n78:     Task B: 1% \n155:     Task B: 2% \n257:     Task B: 3% \n359:     Task B: 4% \n461:     Task B: 5%  snip \n\n========== Timer Expired ==========\n\n   Task A  \n  Priority: 3\n  Loop count: 162849\n  Cycle count: 16.28\n  Run time: 1.40 sec\n\n   Task B  \n  Priority: 2\n  Loop count: 1345852\n  Cycle count: 1.34\n  Run time: 17.0 sec\n\n Total loops: 1508709\n\n20023:   Switching priorities and restarting...\n20111:   Task A looped\n20113:     Task B: 0% \n20191:     Task B: 1% \n20297:   Task A looped\n20356:     Task B: 2% \n20483:   Task A looped\n20545:     Task B: 3% \n20669:   Task A looped\n20734:     Task B: 4% \n20855:   Task A looped\n20923:     Task B: 5%  snip \n\n========== Timer Expired ==========\n\n   Task A  \n  Priority: 2\n  Loop count: 1080000\n  Cycle count: 108.0\n  Run time: 9.28 sec\n\n   Task B  \n  Prio
 rity: 3\n  Loop count: 830356\n  Cycle count: 0.83\n  Run time: 10.72 sec\n\n Total loops: 1910404\n\n40058:\n\n Final Speedup (Sim2 / Sim1): 1.26  The console output reaffirms our previous prediction and makes both the scheduling differences and subsequent efficiency boost far more apparent. Let\u2019s take a look at scheduling differences before we delve into efficiency.  In the first case, where Task B\u2019s priority is higher than that of Task A, we see A get starved by Task B\u2019s long execution time.  Starvation  occurs when one task hogs the processor, essentially \u201cstarving\u201d other tasks which also need to run. At the end of the first 20 second simulation period, Task A has only run for 1.4 seconds compared to task B\u2019s 17 second running time \u2013 ouch. As explained before, processes which are expected to run for long periods of time (e.g. network communication, data processing) should be given higher priorities in order to combat starvation.  In the second 
 simulation with priorities swapped, we can see Task B only running during the millisecond delays when Task A is  sleeping . Although having Task B only run during these delays slows its execution time, we benefit from un-starving Task A and using the processor at a higher efficiency.  The bottom line speedup gives us an immediate and clear indication that we have improved our ability to process work (i.e throughput). In our second run, we processed an additional 400,000 loop iterations, equating to a 26% increase in efficiency. On a standard multi-core processor found in every modern PC, a 1.26 speedup would be an ok result to adding multithreading capabilities to a serial program. However, we accomplished this by simply setting priorities on a single core processor \u2013 not bad!  NOTE: Usually the the term \u201cspeedup\u201d is used within a parallel programming context and refers to the change in execution time between a serial and parallel program executing over the same probl
 em. In this case we\u2019re using the term loosely to illustrate the priority change\u2019s effect on scheduling and throughput in our specific context.", 
+            "title": "Output Analysis"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#efficiency-isnt-everything", 
+            "text": "Using the processor during every OS tick isn\u2019t always the best course of action. If we modify Task A\u2019s delay to a tenth of a millisecond and turn off the console output, we can boost our speedup to 1.44. This, however, reduces our ability to process work from Task B who ends up only completing 18% of its work cycle after the second simulation. That would mean, at that rate, Task B would take over a minute to finish one cycle.  Feel free to play around with the testing parameters to study the different changes yourself!", 
+            "title": "Efficiency Isn\u2019t Everything"
+        }, 
+        {
+            "location": "/os/tutorials/tasks_lesson/#conclusion", 
+            "text": "Moving forward, tasks are just the tip of the iceberg. The  scheduler ,  event queues ,  semaphores , and  mutexes  also add to tasks functionality, increasing our ability as the developer to control greater numbers of tasks more intricately. For example, when we switch the tasks priority, we have to tell the scheduler that our tasks priorities have changed, allowing us us to use priorities dynamically. When running multiple tasks, logging through either the built-in  Logs  module (not covered in this lesson) or through the serial console/shell can be very useful for debugging your application. In the end, the way you manage your tasks depends on the context of your application. You should assign priorities based on execution time, urgency, and frequency, among other things.  Keep blinking and happy hacking!", 
+            "title": "Conclusion"
+        }, 
+        {
             "location": "/os/tutorials/unit_test/", 
             "text": "Write a Test Suite for a Package\n\n\nThis document presents a tutorial which guides the reader through writing\na test suite for a Mynewt package (new or existing).\n\n\nIntroduction\n\n\nWriting a test suite involves using the \nlibs/testutil\n\n package within Mynewt core os. The \ntestutil\n library provides the interface to \nthe \nnewt\n command tool and also provides the compile time hooks to include\ntest suites into your code.  Review the \n[\ntestutil\n introduction page ] (../modules/testutil/testutil.md)\nto learn about how the library works.\n\n\nIdentify Your Package\n\n\nIdentify the package for which you are writing a test suite.  For this example\nwe will use \nlibs/json\n.  To create a new package, see \nthis Tutorial\n.\n\n\nModify Pkg.yml\n\n\nEdit the package (\npkg.yml\n) file for your package and add the test dependency\nfor the Mynewt core OS \nlibs/testutil\n.\n\n\npkg\n.\ndeps\n.\nTEST\n:\n   \n-\n \nlibs/testutil\n\n\n\n\n\n\nCreate Yo
 ur Test Suite Template\n\n\nCreate a subdirectory \ntest\n under your package main directory. \nCreate a file pair for your test code and header files within the \ntest\n\ndirectory created above.  Below shows the \nlibs/json\n directory within the \nMynewt core, including the test directory. In this example, we used the \nconvention \ntest_xxx.c/h\n (in this case \ntest_json\n).\n\n\n\u251c\u2500\u2500\n \nMSJSON_COPYING\n\n\n\u251c\u2500\u2500\n \ninclude\n\n\n\u2502\u00a0\u00a0\n \n\u2514\u2500\u2500\n \njson\n\n\n\u2502\u00a0\u00a0\n     \n\u2514\u2500\u2500\n \njson\n.\nh\n\n\n\u251c\u2500\u2500\n \npkg\n.\nyml\n\n\n\u2514\u2500\u2500\n \nsrc\n\n    \n\u251c\u2500\u2500\n \njson_decode\n.\nc\n\n    \n\u251c\u2500\u2500\n \njson_encode\n.\nc\n\n    \n\u2514\u2500\u2500\n \ntest\n\n        \n\u251c\u2500\u2500\n \ntest_json\n.\nc\n\n        \n\u2514\u2500\u2500\n \ntest_json\n.\nh\n\n\n\n\n\n\nCreate Your Test Suite Code\n\n\nEdit the \ntest_json.c\n file and add your test suite 
 definition.  NOTE that \nthe test suite code requires \n#include \ntestutil/testutil.h\n to get the \nMynewt testutil definitions.\n\n\nYour test suite \ntest_json.c\n file contains at a minimum two functions:\n\n\n\n\nA test Suite which is empty for now, but will contain calls to your test\ncases.  \n\n\nA main function which must be \n#ifdef\n'd using \nMYNEWT_SELFTEST\n to ensure\nthat is does not get compiled in when this test suite is run with \ntest suites from other packages \n\n\n\n\nBelow shows the contents of the \ntest_json.c\n file.\n\n\n#include \ntestutil/testutil.h\n\n\n\nTEST_SUITE\n(\ntest_json_suite\n) {\n    \n/* empty for now, add test cases later */\n\n}\n\n\n#ifdef MYNEWT_SELFTEST\n\n\nint\n\n\nmain\n(\nint\n \nargc\n, \nchar\n \n**argv\n)\n{\n    \ntu_config\n.\ntc_print_results\n \n=\n \n1\n;\n    \ntu_init\n();\n    \ntest_json_suite\n();\n    \nreturn\n \ntu_any_failed\n;\n}\n\n#endif\n\n\n\n\n\n\nTry It Out\n\n\nAt this point, you have a working test suite
  with \nno\n tests.\n\nThis will by default pass the test.  Your output will look\nsomething like this.\n\n\nYou can use the \nnewt test\n command to run the unit tests for any package.\n\nJust include the package name.  These unit tests run via the project \n\nunittest\n which is a native project automatically included in the core\nos package.  Below shows some of the test output of this command.\n\n\n$\n \nnewt\n \ntest\n \nlibs/json\n\n\nArchiving\n \nutil\n.\na\n\n\nLinking\n \ntest_json\n\n\nTesting\n \npackage\n \nlibs/json\n\n\nTest\n ...\n/bin/unittest/libs/json/test_json\n \nok!\n\n\n\n\n\n\nCreate a Test\n\n\nTo create a test within your test suite, there are two things to do.\n\n\n\n\nAdd the functions to your test suite\n\n\nImplement the function using the \ntestutil\n macros\n\n\n\n\nFor this tutorial we will create two functions: one to test a simple json\nencode and one to test the decode of this simple message to ensure its \ncoherent.\n\n\nFollow These steps;\n\n\n
 1. Create function prototypes in \ntest_json.h\n for your test functions. \nA macro in \ntestutil.h\n hides the actual prototype, but as of this writing\nthe prototype is \nint test_func(void);\n.  \n\n\n#ifndef TEST_JSON_H\n\n\n#define TEST_JSON_H\n\n\n\nTEST_CASE_DECL\n(\ntest_json_simple_encode\n);\n\nTEST_CASE_DECL\n(\ntest_json_simple_decode\n);\n\n\n#endif /* TEST_JSON_H \n\n\n\n\n\n\n2. create a new file \ntest_json_simple.c\n to define these two functions.  For\nnow you can stub these functions. Below shows the contents of this file. \nThe functions are defined using macros which reference back to the \n\ntestutil\n library so the test can be enumerated and recorded automatically.\n\n\n#include \ntestutil/testutil.h\n\n\n#include \ntest_json.h\n\n\n\nTEST_CASE\n(\ntest_json_simple_encode\n) {\n}\n\n\nTEST_CASE\n(\ntest_json_simple_decode\n) {\n}\n\n#endif /* TEST_JSON_H \n\n\n\n\n\n\n3. Add the tests to your test suite in \ntest_json.c\n as shown below.\n\n\nTEST_SUITE\n(\nt
 est_json_suite\n) {\n    \ntest_json_simple_encode\n();\n    \ntest_json_simple_decode\n();\n}\n\n\n\n\n\nYour test suite should still pass as shown below\n\n\n$newt\n \ntest\n \nlibs/json\n\n\nTesting\n \npackage\n \nlibs/json\n\n\nTest\n ...\n/bin/unittest/libs/json/test_json\n \nok!\n\n\n\n\n\n\nAdd Contents to your Tests\n\n\nAt this point, you can add contents to your test and verify that \nthe test suites pass.  For now, lets just add a simple failure to show\nwhat it would look like when running from Newt.\n\n\n\n\nEdit \ntest_json_simple.c\n and add a \nTEST_ASSERT\n to a test function. The\ntest assert will fail if its argument is \nfalse\n.\n\n\n\n\nTEST_CASE\n(\ntest_json_simple_encode\n) {\n    \nTEST_ASSERT\n(\n0\n);\n}\n\n\n\n\n\nWhen running newt, you will see the test suite fails with something like\nthe message shown below.\n\n\nTesting\n \npackage\n \nlibs/json\n\n[\nFAIL\n] \ntest_json_suite/\n(\nnull\n) \n|test_json_simple\n.\nc\n:\n24\n|\n \nfailed\n \nassertion
 \n: \n0\n\n\nError\n: \nTest\n \ncrashed\n: ..\n/bin/unittest/libs/json/test_json\n\n\nexit\n \nstatus\n \n1\n\n\n\n\n\n\nCongratulations\n\n\nNow you can begin the work of adding your test cases and test.\n\n\nTesting on your target", 
             "title": "Write a Test Suite for a Package"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/STM32F303/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/STM32F303/index.html b/develop/os/tutorials/STM32F303/index.html
index e1b3eb6..a163f54 100644
--- a/develop/os/tutorials/STM32F303/index.html
+++ b/develop/os/tutorials/STM32F303/index.html
@@ -299,6 +299,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/air_quality_sensor/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/air_quality_sensor/index.html b/develop/os/tutorials/air_quality_sensor/index.html
index e56b227..f92ed6d 100644
--- a/develop/os/tutorials/air_quality_sensor/index.html
+++ b/develop/os/tutorials/air_quality_sensor/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/arduino_zero/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/arduino_zero/index.html b/develop/os/tutorials/arduino_zero/index.html
index 1dae280..a1877de 100644
--- a/develop/os/tutorials/arduino_zero/index.html
+++ b/develop/os/tutorials/arduino_zero/index.html
@@ -285,6 +285,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/blehci_project/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/blehci_project/index.html b/develop/os/tutorials/blehci_project/index.html
index 5671356..b46e133 100644
--- a/develop/os/tutorials/blehci_project/index.html
+++ b/develop/os/tutorials/blehci_project/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/bleprph/bleprph-adv/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/bleprph/bleprph-adv/index.html b/develop/os/tutorials/bleprph/bleprph-adv/index.html
index 47cafda..89353db 100644
--- a/develop/os/tutorials/bleprph/bleprph-adv/index.html
+++ b/develop/os/tutorials/bleprph/bleprph-adv/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/bleprph/bleprph-chr-access/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/bleprph/bleprph-chr-access/index.html b/develop/os/tutorials/bleprph/bleprph-chr-access/index.html
index 5b91ab2..f82c3dd 100644
--- a/develop/os/tutorials/bleprph/bleprph-chr-access/index.html
+++ b/develop/os/tutorials/bleprph/bleprph-chr-access/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/bleprph/bleprph-conn/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/bleprph/bleprph-conn/index.html b/develop/os/tutorials/bleprph/bleprph-conn/index.html
index a2f0cc4..0ce679f 100644
--- a/develop/os/tutorials/bleprph/bleprph-conn/index.html
+++ b/develop/os/tutorials/bleprph/bleprph-conn/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/bleprph/bleprph-intro/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/bleprph/bleprph-intro/index.html b/develop/os/tutorials/bleprph/bleprph-intro/index.html
index 19761ed..32932fe 100644
--- a/develop/os/tutorials/bleprph/bleprph-intro/index.html
+++ b/develop/os/tutorials/bleprph/bleprph-intro/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/bleprph/bleprph-svc-reg/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/bleprph/bleprph-svc-reg/index.html b/develop/os/tutorials/bleprph/bleprph-svc-reg/index.html
index 9026cd8..72668b7 100644
--- a/develop/os/tutorials/bleprph/bleprph-svc-reg/index.html
+++ b/develop/os/tutorials/bleprph/bleprph-svc-reg/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/bletiny_project/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/bletiny_project/index.html b/develop/os/tutorials/bletiny_project/index.html
index 1947f92..d1aa10d 100644
--- a/develop/os/tutorials/bletiny_project/index.html
+++ b/develop/os/tutorials/bletiny_project/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/blinky_primo/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/blinky_primo/index.html b/develop/os/tutorials/blinky_primo/index.html
index 7f109f7..373eeb5 100644
--- a/develop/os/tutorials/blinky_primo/index.html
+++ b/develop/os/tutorials/blinky_primo/index.html
@@ -285,6 +285,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/blinky_sram_olimex/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/blinky_sram_olimex/index.html b/develop/os/tutorials/blinky_sram_olimex/index.html
index a8b7d9e..765faa2 100644
--- a/develop/os/tutorials/blinky_sram_olimex/index.html
+++ b/develop/os/tutorials/blinky_sram_olimex/index.html
@@ -285,6 +285,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/event_queue/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/event_queue/index.html b/develop/os/tutorials/event_queue/index.html
index be1ec92..a278ae4 100644
--- a/develop/os/tutorials/event_queue/index.html
+++ b/develop/os/tutorials/event_queue/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/ibeacon/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/ibeacon/index.html b/develop/os/tutorials/ibeacon/index.html
index 521ac31..27fb9fd 100644
--- a/develop/os/tutorials/ibeacon/index.html
+++ b/develop/os/tutorials/ibeacon/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/nRF52/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/nRF52/index.html b/develop/os/tutorials/nRF52/index.html
index a785b6a..7323751 100644
--- a/develop/os/tutorials/nRF52/index.html
+++ b/develop/os/tutorials/nRF52/index.html
@@ -285,6 +285,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/olimex/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/olimex/index.html b/develop/os/tutorials/olimex/index.html
index a4eb216..ab679eb 100644
--- a/develop/os/tutorials/olimex/index.html
+++ b/develop/os/tutorials/olimex/index.html
@@ -285,6 +285,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/pics/task_lesson.png
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/pics/task_lesson.png b/develop/os/tutorials/pics/task_lesson.png
new file mode 100644
index 0000000..16cbcd5
Binary files /dev/null and b/develop/os/tutorials/pics/task_lesson.png differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/pin-wheel-mods/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/pin-wheel-mods/index.html b/develop/os/tutorials/pin-wheel-mods/index.html
index 29323bf..4fc3476 100644
--- a/develop/os/tutorials/pin-wheel-mods/index.html
+++ b/develop/os/tutorials/pin-wheel-mods/index.html
@@ -299,6 +299,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/project-slinky/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/project-slinky/index.html b/develop/os/tutorials/project-slinky/index.html
index 17d9106..9a44dc1 100644
--- a/develop/os/tutorials/project-slinky/index.html
+++ b/develop/os/tutorials/project-slinky/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/project-target-slinky/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/project-target-slinky/index.html b/develop/os/tutorials/project-target-slinky/index.html
index d78b9f9..44af4d5 100644
--- a/develop/os/tutorials/project-target-slinky/index.html
+++ b/develop/os/tutorials/project-target-slinky/index.html
@@ -230,6 +230,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/repo/add_repos/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/repo/add_repos/index.html b/develop/os/tutorials/repo/add_repos/index.html
index 469b83b..e23094d 100644
--- a/develop/os/tutorials/repo/add_repos/index.html
+++ b/develop/os/tutorials/repo/add_repos/index.html
@@ -252,6 +252,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/repo/create_repo/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/repo/create_repo/index.html b/develop/os/tutorials/repo/create_repo/index.html
index c149528..1563b73 100644
--- a/develop/os/tutorials/repo/create_repo/index.html
+++ b/develop/os/tutorials/repo/create_repo/index.html
@@ -252,6 +252,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>
@@ -585,8 +598,8 @@ potential options.</p>
     </li>
     <li class="pull-right">
     
-    <a href=../../unit_test/>
-        Next: Write a Test Suite for a Package
+    <a href=../../tasks_lesson/>
+        Next: Lesson Unit on Tasks and Priority Management
         <span class="fa fa-arrow-right"></span>
     </a>
     

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/b3005c0b/develop/os/tutorials/repo/upgrade_repo/index.html
----------------------------------------------------------------------
diff --git a/develop/os/tutorials/repo/upgrade_repo/index.html b/develop/os/tutorials/repo/upgrade_repo/index.html
index 036040b..86449dd 100644
--- a/develop/os/tutorials/repo/upgrade_repo/index.html
+++ b/develop/os/tutorials/repo/upgrade_repo/index.html
@@ -252,6 +252,19 @@
           
               
                 
+  
+  
+    <li><a href="
+  ../../tasks_lesson/
+">A Sample Lesson</a>
+  
+  
+    </li>
+
+              
+          
+              
+                
     <li >
       <a href="../../unit_test/">Write a Test Suite for a Package</a>
     </li>