| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| |
| |
| <!-- This is broken by doc revisioning. |
| --> |
| <link rel="shortcut icon" href="../../../img/favicon.ico"> |
| |
| <title>Tasks lesson - Apache Mynewt</title> |
| |
| <link href="../../../css/bootstrap-3.0.3.min.css" rel="stylesheet"> |
| <link rel="stylesheet" href="../../../css/highlight.css"> |
| <link href="../../../css/base.css" rel="stylesheet"> |
| <link href="../../../css/custom.css" rel="stylesheet"> |
| <link href="../../../css/v2.css" rel="stylesheet"> |
| <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet"> |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> |
| |
| <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> |
| <!--[if lt IE 9]> |
| <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |
| <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> |
| <![endif]--> |
| |
| |
| <script> |
| (function(i, s, o, g, r, a, m) { |
| i["GoogleAnalyticsObject"] = r; |
| (i[r] = |
| i[r] || |
| function() { |
| (i[r].q = i[r].q || []).push(arguments); |
| }), |
| (i[r].l = 1 * new Date()); |
| (a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]); |
| a.async = 1; |
| a.src = g; |
| m.parentNode.insertBefore(a, m); |
| })(window, document, "script", "//www.google-analytics.com/analytics.js", "ga"); |
| |
| ga("create", "UA-72162311-1", "auto"); |
| ga("send", "pageview"); |
| </script> |
| |
| </head> |
| |
| |
| <body class="Tasks lesson"> |
| |
| |
| <div class="container"> |
| <div class="row v2-main-banner"> |
| <a class="logo-cell" href="/"> |
| <img class="logo" src="/img/logo.png"> |
| </a> |
| <div class="tagline-cell"> |
| <h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4> |
| </div> |
| <div class="news-cell"> |
| <div class="well"> |
| <h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released (September 7, 2023) |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| |
| |
| |
| |
| |
| |
| <nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation"> |
| <div class="container"> |
| <!-- Collapsed navigation --> |
| <div class="navbar-header"> |
| <!-- Expander button --> |
| <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| |
| </div> |
| |
| <!-- Expanded navigation --> |
| <div class="navbar-collapse collapse"> |
| <!-- Main navigation --> |
| <ul class="nav navbar-nav navbar-right"> |
| <li |
| class="" |
| > |
| <a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a> |
| </li> |
| <li |
| class="important" |
| > |
| <a href="/quick-start/">Quick Start</a> |
| </li> |
| <li |
| class="" |
| > |
| <a href="/about/">About</a> |
| </li> |
| <li |
| class="" |
| > |
| <a href="/talks/">Talks</a> |
| </li> |
| <li |
| class="active" |
| > |
| <a href="/documentation/">Documentation</a> |
| </li> |
| <li |
| class="" |
| > |
| <a href="/download/">Download</a> |
| </li> |
| <li |
| class="" |
| > |
| <a href="/community/">Community</a> |
| </li> |
| <li |
| class="" |
| > |
| <a href="/events/">Events</a> |
| </li> |
| </ul> |
| |
| </div> |
| </div> |
| </nav> |
| |
| |
| |
| <div class="container"> |
| |
| <div class="row"> |
| <div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary"> |
| <div class="top"> |
| <div role="search"> |
| <form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get"> |
| <div class="form-group"> |
| <input type="text" name="q" class="form-control" placeholder="Search documentation" /> |
| </div> |
| </form> |
| </div> |
| </div> |
| <ul class="toc-nav"> |
| <li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value"> |
| <option value="/latest"> |
| Version: master |
| </option> |
| <option value="/v1_11_0/" > |
| Version: 1.11.0 |
| </option> |
| <option value="/v1_10_0/" > |
| Version: 1.10.0 |
| </option> |
| <option value="/v1_9_0/" > |
| Version: 1.9.0 |
| </option> |
| <option value="/v1_8_0/" > |
| Version: 1.8.0 |
| </option> |
| <option value="/v1_7_0/" > |
| Version: 1.7.0 |
| </option> |
| <option value="/v1_6_0/" > |
| Version: 1.6.0 |
| </option> |
| <option value="/v1_5_0/" > |
| Version: 1.5.0 |
| </option> |
| <option value="/v1_4_0/" > |
| Version: 1.4.0 |
| </option> |
| <option value="/v1_3_0/os/introduction" > |
| Version: 1.3.0 |
| </option> |
| <option value="/v1_2_0/os/introduction" > |
| Version: 1.2.0 |
| </option> |
| <option value="/v1_1_0/os/introduction" > |
| Version: 1.1.0 |
| </option> |
| <option value="/v1_0_0/os/introduction" > |
| Version: 1.0.0 |
| </option> |
| <option value="/v0_9_0/os/introduction" selected="selected" > |
| Version: 0.9.0 |
| </option> |
| </select></li> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <li ><a href="../../introduction/">Mynewt Documentation</a> |
| |
| |
| </li> |
| |
| |
| |
| |
| |
| |
| |
| <li><a href=" |
| ../../../faq/how_to_edit_docs/ |
| ">Appendix</a> |
| |
| |
| </li> |
| |
| |
| |
| </ul> |
| </div></div> |
| |
| <div class="col-md-9" role="main"> |
| <div class="doc-header"> |
| <div role="navigation" aria-label="breadcrumbs navigation"> |
| <ul class="wy-breadcrumbs"> |
| <li><a href="/documentation/">Docs</a></li> |
| |
| |
| |
| <li>» Tasks lesson</li> |
| |
| |
| |
| </ul> |
| </div> |
| </div> |
| |
| |
| |
| |
| <div class="alert alert-warning"> |
| <p> |
| Version 0.9.0 is not the most recent version of the Apache Mynewt |
| documentation. Click <a href="/latest">here</a> to read the latest |
| version. |
| </p> |
| </div> |
| |
| |
| |
| |
| |
| <h1 id="core-os-lesson-tasks-and-priority-management">Core OS Lesson: Tasks and Priority Management</h1> |
| <p><strong>Target Platform: Arduino M0 Pro</strong> (or legacy Arduino Zero or Zero Pro, but not Arduino M0)</p> |
| <p>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.</p> |
| <h2 id="prerequisites">Prerequisites</h2> |
| <p>Before starting, you should read about Mynewt in the <a href="http://mynewt.apache.org/os/introduction/"><em>Introduction</em></a> |
| section and complete the <a href="http://mynewt.apache.org/os/get_started/get_started/"><em>QuickStart</em></a> |
| guide and the <a href="http://mynewt.apache.org/os/tutorials/arduino_zero/"><em>Blinky</em></a> tutorial. |
| Furthermore, it may be helpful to take a peek at the <a href="http://mynewt.apache.org/os/core_os/task/task/"><em>task documentation</em></a> |
| for additional insights.</p> |
| <h2 id="equipment">Equipment</h2> |
| <p>You will need the following equipment:</p> |
| <ul> |
| <li>Arduino M0 Pro (or legacy Arduino Zero or Zero Pro, but not Arduino M0)</li> |
| <li>Computer with Mynewt installed</li> |
| <li>USB to Micro USB Cable</li> |
| </ul> |
| <h2 id="build-your-application">Build Your Application</h2> |
| <p>To save time, we will simply modify the Blinky app. We'll add the Task Management code to |
| the Blinky app. Follow the <a href="http://mynewt.apache.org/os/tutorials/arduino_zero/"><em>Arduino Zero Blinky tutorial</em></a> |
| 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’s get started!</p> |
| <h2 id="create-a-new-task">Create a New Task</h2> |
| <p>The purpose of this section is to give an introduction to the important aspects of tasks |
| and how to properly initialize them. First, let’s define a second task called <code>work_task</code> |
| in main.c (located in apps/blinky/src):</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">work_task</span>; |
| </code></pre></div> |
| |
| <p>A task is represented by the <a href="http://mynewt.apache.org/os/core_os/task/task/#data-structures"><em>os_task</em></a><br /> |
| struct which will hold the task’s 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.</p> |
| <p>Next, let’s take a look at what is required to initialize our new task.</p> |
| <h3 id="task-stack">Task Stack</h3> |
| <p>The task stack is an array of type <code>os_stack_t</code> 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’re not short on memory, our <code>blinky_stack</code> and <code>work_stack</code> are plenty large |
| for the purpose of this lesson. Notice that the elements in our task stack are of type <code>os_stack_t</code> |
| which are generally 32 bits, making our entire stack 1024 Bytes.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> <span style="color: #633820">#define WORK_STACK_SIZE OS_STACK_ALIGN(256)</span> |
| <span style="color: #000000">os_stack_t</span> <span style="color: #000000">work_stack</span>[<span style="color: #000000">WORK_STACK_SIZE</span>]; |
| </code></pre></div> |
| |
| <p>Note: The <code>OS_STACK_ALIGN</code> macro is used to align the stack based on the hardware architecture.</p> |
| <h3 id="task-function">Task Function</h3> |
| <p>The task function is essentially an infinite loop which waits for some “event” to wake it up. In our |
| Blinky app the task function, named <code>blinky_task_handler()</code>, is initially called when we call <code>os_start()</code> |
| in <code>main()</code>. In general, the task function is where the majority of work is done by a task. Let’s write |
| a task function for <code>work_task</code> called <code>work_task_handler()</code>:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">void</span> |
| <span style="color: #000000">work_task_handler</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>) |
| { |
| <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">*t</span>; |
| |
| <span style="color: #000000">g_led_pin</span> <span style="color: #000000">=</span> <span style="color: #000000">LED_BLINK_PIN</span>; |
| <span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">g_led_pin</span>, <span style="color: #1C01CE">1</span>); |
| |
| <span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) { |
| <span style="color: #000000">t</span> <span style="color: #000000">=</span> <span style="color: #000000">os_sched_get_current_task</span>(); |
| <span style="color: #000000">assert</span>(<span style="color: #000000">t->t_func</span> <span style="color: #000000">==</span> <span style="color: #000000">work_task_handler</span>); |
| <span style="color: #177500">/* Do work... */</span> |
| } |
| } |
| </code></pre></div> |
| |
| <p>The task function is called when the task is initially put into the <em>running</em> state by the scheduler. |
| We use an infinite loop to ensure that the task function never returns. Our assertion that the current |
| task's handler is the same as our task handler is for illustration purposes only and does not need to |
| be in most task functions.</p> |
| <h3 id="task-priority">Task Priority</h3> |
| <p>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.</p> |
| <p>Let’s set the priority of <code>work_task</code> to 0, because everyone knows that work is more important than blinking.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> <span style="color: #633820">#define WORK_TASK_PRIO (0)</span> |
| </code></pre></div> |
| |
| <h3 id="initialization">Initialization</h3> |
| <p>To initialize a new task we use <a href="http://mynewt.apache.org/os/core_os/task/os_task_init/"><em>os_task_init()</em></a> |
| which takes a number of arguments including our new task function, stack, and priority. Much like <code>blinky_task</code>, |
| we’re going to initialize <code>work_task</code> inside <code>init_tasks</code> to keep our main function clean.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">int</span> |
| <span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>) |
| { |
| <span style="color: #177500">/* … */</span> |
| <span style="color: #000000">os_task_init</span>(<span style="color: #000000">&work_task</span>, <span style="color: #C41A16">"work"</span>, <span style="color: #000000">work_task_handler</span>, <span style="color: #A90D91">NULL</span>, |
| <span style="color: #000000">WORK_TASK_PRIO</span>, <span style="color: #000000">OS_WAIT_FOREVER</span>, <span style="color: #000000">work_stack</span>, |
| <span style="color: #000000">WORK_STACK_SIZE</span>); |
| |
| <span style="color: #000000">tasks_initialized</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">1</span>; |
| <span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>; |
| } |
| </code></pre></div> |
| |
| <p>And that’s it! Now run your application using the newt run command.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt run arduino_blinky 0.0.0 |
| </code></pre></div> |
| |
| <p>When GDB appears press C then Enter to continue and … <em>wait, why doesn't our LED blink anymore?</em></p> |
| <h4 id="review">Review</h4> |
| <p>Before we run our new app, let’s review what we need in order to create a task. This is a general case for a new task called mytask:</p> |
| <p><strong>1)</strong> Define a new task, task stack, and priority:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* My Task */</span> |
| <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">mytask</span> |
| <span style="color: #177500">/* My Task Stack */</span> |
| <span style="color: #633820">#define MYTASK_STACK_SIZE OS_STACK_ALIGN(256)</span> |
| <span style="color: #000000">os_stack_t</span> <span style="color: #000000">mytask_stack</span>[<span style="color: #000000">MYTASK_STACK_SIZE</span>]; |
| <span style="color: #177500">/* My Task Priority */</span> |
| <span style="color: #633820">#define MYTASK_PRIO (0)</span> |
| </code></pre></div> |
| |
| <p><strong>2)</strong> Define task function:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">void</span> |
| <span style="color: #000000">mytask_handler</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>) |
| { |
| <span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) { |
| <span style="color: #177500">/* ... */</span> |
| } |
| } |
| </code></pre></div> |
| |
| <p><strong>3)</strong> Initialize task before calling <code>os_start()</code>:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">os_task_init</span>(<span style="color: #000000">&mytask</span>, <span style="color: #C41A16">"mytask"</span>, <span style="color: #000000">mytask_handler</span>, <span style="color: #A90D91">NULL</span>, |
| <span style="color: #000000">MYTASK_PRIO</span>, <span style="color: #000000">OS_WAIT_FOREVER</span>, <span style="color: #000000">mytask_stack</span>, |
| <span style="color: #000000">MYTASK_STACK_SIZE</span>); |
| </code></pre></div> |
| |
| <h2 id="task-priority-preempting-and-context-switching">Task Priority, Preempting, and Context Switching</h2> |
| <p>A preemptive RTOS is one in which a higher priority task that is <em>ready to run</em> will preempt (i.e. take the |
| place of) the lower priority task which is <em>running</em>. When a lower priority task is preempted by a higher |
| priority task, the lower priority task’s context data (stack pointer, registers, etc.) is saved and the new |
| task is switched in.</p> |
| <p>In our example, <code>work_task</code> has a higher priority than <code>blinky_task</code> and, because it is never put into a |
| <em>sleep</em> state, holds the processor focus on its context. Let’s give <code>work_task</code> 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 <code>OS_TICKS_PER_SEC</code>, which is defined in the MCU, by the |
| number of seconds we wish to delay.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">void</span> |
| <span style="color: #000000">work_task_handler</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>) |
| { |
| <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">*t</span>; |
| |
| <span style="color: #000000">g_led_pin</span> <span style="color: #000000">=</span> <span style="color: #000000">LED_BLINK_PIN</span>; |
| <span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">g_led_pin</span>, <span style="color: #1C01CE">1</span>); |
| |
| <span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) { |
| <span style="color: #000000">t</span> <span style="color: #000000">=</span> <span style="color: #000000">os_sched_get_current_t:ask</span>(); |
| <span style="color: #000000">assert</span>(<span style="color: #000000">t->t_func</span> <span style="color: #000000">==</span> <span style="color: #000000">work_task_handler</span>); |
| <span style="color: #177500">/* Do work... */</span> |
| <span style="color: #A90D91">int</span> <span style="color: #000000">i</span>; |
| <span style="color: #A90D91">for</span>(<span style="color: #000000">i</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">0</span>; <span style="color: #000000">i</span> <span style="color: #000000"><</span> <span style="color: #1C01CE">1000000</span>; <span style="color: #000000">++i</span>) { |
| <span style="color: #177500">/* Simulate doing a noticeable amount of work */</span> |
| <span style="color: #000000">hal_gpio_set</span>(<span style="color: #000000">g_led_pin</span>); |
| } |
| <span style="color: #000000">os_time_delay</span>(<span style="color: #1C01CE">3</span><span style="color: #000000">*OS_TICKS_PER_SECOND</span>); |
| } |
| } |
| </code></pre></div> |
| |
| <p>In order to notice the LED changing, modify the time delay in <code>blinky_task_handler()</code> to blink at a higher frequency.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">os_time_delay</span>(<span style="color: #000000">OS_TICKS_PER_SEC/</span><span style="color: #1C01CE">10</span>); |
| </code></pre></div> |
| |
| <p>Before we run the app, let’s predict the behavior. With the newest additions to <code>work_task_handler()</code>, |
| our first action will be to sleep for three seconds. This will allow <code>blinky_task</code> to take over the CPU |
| and blink to its heart’s content. After three seconds, <code>work_task</code> will wake up and be made <em>ready to run</em>, |
| causing it to preempt <code>blinky_task</code>. The LED will then remain lit for a short period while <code>work_task</code> |
| loops, then blink again for another three seconds while <code>work_task</code> sleeps. </p> |
| <p>Voila, you should see that our prediction was correct! </p> |
| <h3 id="priority-management-considerations">Priority Management Considerations</h3> |
| <p>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.</p> |
| <p>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.</p> |
| <p>The diagram below showcases the different scheduling patterns we. would expect from swapping blinky and |
| work tasks priorities.</p> |
| <p><img alt="Task Scheduling" src="pics/task_lesson.png" /></p> |
| <p>In the second case where <code>blinky_task</code> has a higher priority, the “work” done by <code>work_task</code> would be |
| executed during the millisecond delays in <code>blinky_task</code>, saving us idle time compared to the first case.</p> |
| <p><strong>Note:</strong> Defining the same priority for two tasks leads to somewhat undefined behavior and should be avoided.</p> |
| <h2 id="comparing-priority-strategies">Comparing Priority Strategies</h2> |
| <p>Instead of stepping through a bunch of changes to our blinky app, clone my task lesson application from |
| github and copy an existing target.</p> |
| <p>Change directory into apps and clone the repository to get our new |
| files:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ cd apps |
| $ git clone https://github.com/bgiori/mynewt_tasks_lesson.git |
| </code></pre></div> |
| |
| <p>Change directory back to your project root and copy the arduino_blinky target to a new target called task_tgt.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">$</span> <span style="color: #000000">newt</span> <span style="color: #000000">target</span> <span style="color: #000000">copy</span> <span style="color: #000000">arduino_blinky</span> <span style="color: #000000">task_tgt</span> |
| </code></pre></div> |
| |
| <p>Set a new app location.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">$</span> <span style="color: #000000">newt</span> <span style="color: #000000">target</span> <span style="color: #000000">set</span> <span style="color: #000000">task_tgt</span> <span style="color: #000000">app=apps/mynewt_tasks_lesson</span> |
| </code></pre></div> |
| |
| <p>Now let’s take a look at our new code. First, notice that we have abandoned blinking, instead choosing t |
| o use the <a href="http://mynewt.apache.org/latest/os/modules/console/console/"><em>console</em></a> and <a href="http://mynewt.apache.org/latest/os/modules/shell/shell/"><em>shell</em></a> |
| to follow our tasks through execution.</p> |
| <p>Additionally, we have a number of different tasks:</p> |
| <ul> |
| <li> |
| <p><strong>Task A</strong> (<code>a_task</code>):</p> |
| <ul> |
| <li><strong>Priority</strong>: 3 → 2</li> |
| <li><strong>Description</strong>: 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 <code>blinky_task</code>, Task A will |
| loop 10,000 times then wait 1 millisecond. Priority is changed by <code>timer_task</code> after the first simulation.</li> |
| </ul> |
| </li> |
| <li> |
| <p><strong>Task B</strong> (<code>b_task</code>):</p> |
| <ul> |
| <li><strong>Priority</strong>: 2 → 3</li> |
| <li><strong>Description</strong>: 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.</li> |
| </ul> |
| </li> |
| <li> |
| <p><strong>Timer Task</strong> (<code>timer_task</code>):</p> |
| <ul> |
| <li><strong>Priority</strong>: 1</li> |
| <li><strong>Description</strong>: 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’s 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).</li> |
| </ul> |
| </li> |
| <li> |
| <p><strong>Shell Task</strong>:</p> |
| <ul> |
| <li><strong>Priority</strong>: 0</li> |
| <li><strong>Description</strong>: Task used by Shell behind the scenes to communicate with the serial port.</li> |
| </ul> |
| </li> |
| </ul> |
| <h3 id="connecting-to-the-serial-console">Connecting to the Serial Console</h3> |
| <p>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). </p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ cd repos/mynewt_arduino_zero |
| $ git checkout develop |
| </code></pre></div> |
| |
| <p>Open a new terminal window and list your serial connections to find our Arduino.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">$</span> <span style="color: #000000">ls</span> <span style="color: #000000">/dev/tty</span>.<span style="color: #000000">*</span> |
| |
| <span style="color: #000000">/dev/tty</span>.<span style="color: #000000">Bluetooth-Incoming-Port</span> <span style="color: #000000">/dev/tty</span>.<span style="color: #000000">usbmodem14132</span> |
| </code></pre></div> |
| |
| <p>In the same window, connect to the serial port using a serial communication program. |
| In this case I’ll be using mincom as it can scroll through output.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">$</span> <span style="color: #000000">minicom</span> <span style="color: #000000">-D</span> <span style="color: #000000">/dev/tty</span>.<span style="color: #000000">usbmodem14132</span> <span style="color: #000000">-b</span> <span style="color: #1C01CE">115200</span> |
| </code></pre></div> |
| |
| <p>If you see minicom welcome you, you’re ready to move on!</p> |
| <h3 id="output-analysis">Output Analysis</h3> |
| <p>Run our new target, task_tgt, and you should see an output similar to this:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>Starting First Simulation... |
| 1: Task B: 0% |
| 78: Task B: 1% |
| 155: Task B: 2% |
| 257: Task B: 3% |
| 359: Task B: 4% |
| 461: Task B: 5% |
| |
| <snip> |
| |
| ========== Timer Expired ========== |
| |
| >>> Task A <<< |
| Priority: 3 |
| Loop count: 162849 |
| Cycle count: 16.28 |
| Run time: 1.40 sec |
| |
| >>> Task B <<< |
| Priority: 2 |
| Loop count: 1345852 |
| Cycle count: 1.34 |
| Run time: 17.0 sec |
| |
| Total loops: 1508709 |
| |
| 20023: Switching priorities and restarting... |
| 20111: Task A looped |
| 20113: Task B: 0% |
| 20191: Task B: 1% |
| 20297: Task A looped |
| 20356: Task B: 2% |
| 20483: Task A looped |
| 20545: Task B: 3% |
| 20669: Task A looped |
| 20734: Task B: 4% |
| 20855: Task A looped |
| 20923: Task B: 5% |
| |
| <snip> |
| |
| ========== Timer Expired ========== |
| |
| >>> Task A <<< |
| Priority: 2 |
| Loop count: 1080000 |
| Cycle count: 108.0 |
| Run time: 9.28 sec |
| |
| >>> Task B <<< |
| Priority: 3 |
| Loop count: 830356 |
| Cycle count: 0.83 |
| Run time: 10.72 sec |
| |
| Total loops: 1910404 |
| |
| 40058: |
| |
| Final Speedup (Sim2 / Sim1): 1.26 |
| </code></pre></div> |
| |
| <p>The console output reaffirms our previous prediction and makes both the scheduling differences |
| and subsequent efficiency boost far more apparent. Let’s take a look at scheduling differences |
| before we delve into efficiency.</p> |
| <p>In the first case, where Task B’s priority is higher than that of Task A, we see A get starved |
| by Task B’s long execution time. <strong>Starvation</strong> occurs when one task hogs the processor, essentially |
| “starving” 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’s 17 second running time – 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.</p> |
| <p>In the second simulation with priorities swapped, we can see Task B only running during the |
| millisecond delays when Task A is <em>sleeping</em>. 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.</p> |
| <p>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 – not bad!</p> |
| <p>NOTE: Usually the the term “speedup” 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 |
| problem. In this case we’re using the term loosely to illustrate the priority change’s effect |
| on scheduling and throughput in our specific context.</p> |
| <h3 id="efficiency-isnt-everything">Efficiency Isn’t Everything</h3> |
| <p>Using the processor during every OS tick isn’t always the best course of action. If we modify |
| Task A’s 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.</p> |
| <p>Feel free to play around with the testing parameters to study the different changes yourself!</p> |
| <h2 id="conclusion">Conclusion</h2> |
| <p>Moving forward, tasks are just the tip of the iceberg. The <a href="http://mynewt.apache.org/latest/os/core_os/context_switch/context_switch/"><em>scheduler</em></a>, |
| <a href="http://mynewt.apache.org/latest/os/core_os/event_queue/event_queue/"><em>event queues</em></a>, |
| <a href="http://mynewt.apache.org/latest/os/core_os/semaphore/semaphore/"><em>semaphores</em></a>, and |
| <a href="http://mynewt.apache.org/latest/os/core_os/mutex/mutex/"><em>mutexes</em></a> 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 <a href="http://mynewt.apache.org/latest/os/modules/logs/logs/"><em>Logs</em></a> 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.</p> |
| <p>Keep blinking and happy hacking!</p> |
| |
| <div class="row"> |
| |
| |
| |
| |
| <ul class="nav nav-pills" style="margin-bottom: 10px"> |
| <li> |
| |
| </li> |
| <li class="pull-right"> |
| |
| </li> |
| </ul> |
| </div> |
| <footer class="row"> |
| <div class="col-xs-12"> |
| |
| <p class="copyright">Apache Mynewt (incubating) is available under Apache License, version 2.0.</p> |
| |
| </div> |
| <div class="col-xs-12"> |
| <div class="logos"> |
| <a href="https://www.apache.org/"> |
| <img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache"> |
| </a> |
| <p> |
| Copyright © 2015-2021 The Apache Software Foundation.<br> |
| <small class="footnote"> |
| Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt |
| project logo are either registered trademarks or trademarks of the Apache |
| Software Foundation in the United States and other countries. |
| </small> |
| </p> |
| <a href=""> |
| <img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" /> |
| </a> |
| </div> |
| </div> |
| <a href="https://www.apache.org/licenses/"> |
| <button class="button-footer-asf"> |
| License |
| </button> |
| </a> |
| <a href="https://www.apache.org/foundation/sponsorship.html"> |
| <button class="button-footer-asf"> |
| Sponsorship |
| </button> |
| </a> |
| <a href="https://www.apache.org/foundation/thanks.html"> |
| <button class="button-footer-asf"> |
| Thanks |
| </button> |
| </a> |
| <a href="https://www.apache.org/security/"> |
| <button class="button-footer-asf"> |
| Security |
| </button> |
| </a> |
| <a href="https://apache.org/events/current-event"> |
| <button class="button-footer-asf"> |
| ASF Events |
| </button> |
| </a> |
| </footer> |
| </div> |
| </div> |
| |
| |
| </div> |
| |
| <script src="../../../js/jquery-1.10.2.min.js"></script> |
| <script src="../../../js/bootstrap-3.0.3.min.js"></script> |
| <script src="../../../js/highlight.pack.js"></script> |
| <script src="../../../js/base.js"></script> |
| <script src="../../../js/custom.js"></script> |
| <script src="search/main.js"></script> |
| |
| </body> |
| </html> |