blob: 6bb5fbde7e16e3e21723a66b8caf009b88adfa1f [file] [log] [blame]
<!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">
<title>Tasks and Priority Management &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../index.html"/>
<link rel="up" title="OS Fundamentals" href="os_fundamentals.html"/>
<link rel="next" title="Remote Device Management" href="../devmgmt/devmgmt.html"/>
<link rel="prev" title="How to Use Event Queues to Manage Multiple Events" href="event_queue.html"/>
<script src="../../_static/js/modernizr.min.js"></script>
<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="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../_static/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.12.0, Apache NimBLE 1.7.0 </a> released April 4, 2024)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" 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>
<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>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../tutorials.html">Tutorials</a> /
<a href="os_fundamentals.html">OS Fundamentals</a> /
Tasks and Priority Management
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-documentation/edit/master/docs/tutorials/os_fundamentals/tasks_lesson.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_12_0" >
Version: 1.12.0
</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" selected="selected" >
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" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../concepts.html">Concepts</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../tutorials.html">Tutorials</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../blinky/blinky.html">Project Blinky</a></li>
<li class="toctree-l2"><a class="reference internal" href="../repo/add_repos.html">Working with repositories</a></li>
<li class="toctree-l2"><a class="reference internal" href="../slinky/project-slinky.html">Project Slinky for Remote Comms</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ble/ble.html">Bluetooth Low Energy</a></li>
<li class="toctree-l2"><a class="reference internal" href="../lora/lorawanapp.html">LoRa</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="os_fundamentals.html">OS Fundamentals</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="event_queue.html">Events and Event Queues</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Task and Priority Management</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../devmgmt/devmgmt.html">Remote Device Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sensors/sensors.html">Sensors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tooling/tooling.html">Tooling</a></li>
<li class="toctree-l2"><a class="reference internal" href="../other/other.html">Other</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../os/os_user_guide.html">OS User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="alert alert-warning">
<p>
Version 1.6.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>
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="tasks-and-priority-management">
<h1>Tasks and Priority Management<a class="headerlink" href="#tasks-and-priority-management" title="Permalink to this headline"></a></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>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#prerequisites" id="id2">Prerequisites</a></p></li>
<li><p><a class="reference internal" href="#equipment" id="id3">Equipment</a></p></li>
<li><p><a class="reference internal" href="#build-your-application" id="id4">Build Your Application</a></p></li>
<li><p><a class="reference internal" href="#default-main-task" id="id5">Default Main Task</a></p></li>
<li><p><a class="reference internal" href="#create-a-new-task" id="id6">Create a New Task</a></p>
<ul>
<li><p><a class="reference internal" href="#task-stack" id="id7">Task Stack</a></p></li>
<li><p><a class="reference internal" href="#task-function" id="id8">Task Function</a></p></li>
<li><p><a class="reference internal" href="#task-priority" id="id9">Task Priority</a></p></li>
<li><p><a class="reference internal" href="#initialization" id="id10">Initialization</a></p></li>
</ul>
</li>
<li><p><a class="reference internal" href="#task-priority-preempting-and-context-switching" id="id11">Task Priority, Preempting, and Context Switching</a></p>
<ul>
<li><p><a class="reference internal" href="#priority-management-considerations" id="id12">Priority Management Considerations</a></p></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="prerequisites">
<h2><a class="toc-backref" href="#id2">Prerequisites</a><a class="headerlink" href="#prerequisites" title="Permalink to this headline"></a></h2>
<p>Before starting, you should read about Mynewt in the
<a class="reference internal" href="../../index.html"><span class="doc">Introduction</span></a> section and
complete the
<a class="reference internal" href="../../get_started/index.html"><span class="doc">QuickStart</span></a>
guide and the
<a class="reference internal" href="../blinky/arduino_zero.html"><span class="doc">Blinky</span></a>
tutorial. Furthermore, it may be helpful to take a peek at the <a class="reference internal" href="../../os/core_os/task/task.html"><span class="doc">task
documentation</span></a> for
additional insights.</p>
</div>
<div class="section" id="equipment">
<h2><a class="toc-backref" href="#id3">Equipment</a><a class="headerlink" href="#equipment" title="Permalink to this headline"></a></h2>
<p>You will need the following equipment:</p>
<ul class="simple">
<li><p>Arduino M0 Pro (or legacy Arduino Zero or Zero Pro, but not Arduino
M0)</p></li>
<li><p>Computer with Mynewt installed</p></li>
<li><p>USB to Micro USB Cable</p></li>
</ul>
</div>
<div class="section" id="build-your-application">
<h2><a class="toc-backref" href="#id4">Build Your Application</a><a class="headerlink" href="#build-your-application" title="Permalink to this headline"></a></h2>
<p>To save time, we will simply modify the Blinky application. We’ll add
the Task Management code to the Blinky application. Follow the <a class="reference internal" href="../blinky/arduino_zero.html"><span class="doc">Arduino
Zero Blinky
tutorial</span></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>
</div>
<div class="section" id="default-main-task">
<h2><a class="toc-backref" href="#id5">Default Main Task</a><a class="headerlink" href="#default-main-task" title="Permalink to this headline"></a></h2>
<p>During Mynewt system startup, Mynewt creates a default main task and
executes the application <code class="docutils literal notranslate"><span class="pre">main()</span></code> function in the context of this
task. The main task priority defaults to 127 and can be configured with
the <code class="docutils literal notranslate"><span class="pre">OS_MAIN_TASK_PRIO</span></code> system configuration setting.</p>
<p>The blinky application only has the <code class="docutils literal notranslate"><span class="pre">main</span></code> task. The <code class="docutils literal notranslate"><span class="pre">main()</span></code>
function executes an infinite loop that toggles the led and sleeps for
one second.</p>
</div>
<div class="section" id="create-a-new-task">
<h2><a class="toc-backref" href="#id6">Create a New Task</a><a class="headerlink" href="#create-a-new-task" title="Permalink to this headline"></a></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 class="docutils literal notranslate"><span class="pre">work_task</span></code> in main.c (located in
apps/blinky/src):</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">os_task</span><span class="w"> </span><span class="n">work_task</span><span class="p">;</span>
</pre></div>
</div>
<p>A task is represented by the
<span class="xref std std-doc">os_task</span>
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>
<div class="section" id="task-stack">
<h3><a class="toc-backref" href="#id7">Task Stack</a><a class="headerlink" href="#task-stack" title="Permalink to this headline"></a></h3>
<p>The task stack is an array of type <code class="docutils literal notranslate"><span class="pre">os_stack_t</span></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 class="docutils literal notranslate"><span class="pre">work_stack</span></code> is plenty
large for the purpose of this lesson. Notice that the elements in our
task stack are of type <code class="docutils literal notranslate"><span class="pre">os_stack_t</span></code> which are generally 32 bits,
making our entire stack 1024 Bytes.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define WORK_STACK_SIZE OS_STACK_ALIGN(256)</span>
</pre></div>
</div>
<p>Note: The <code class="docutils literal notranslate"><span class="pre">OS_STACK_ALIGN</span></code> macro is used to align the stack based on
the hardware architecture.</p>
</div>
<div class="section" id="task-function">
<h3><a class="toc-backref" href="#id8">Task Function</a><a class="headerlink" href="#task-function" title="Permalink to this headline"></a></h3>
<p>A task function is essentially an infinite loop that waits for some
“event” to wake it up. In general, the task function is where the
majority of work is done by a task. Let’s write a task function for
<code class="docutils literal notranslate"><span class="pre">work_task</span></code> called <code class="docutils literal notranslate"><span class="pre">work_task_handler()</span></code>:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span>
<span class="nf">work_task_handler</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">os_task</span><span class="w"> </span><span class="o">*</span><span class="n">t</span><span class="p">;</span>
<span class="w"> </span><span class="n">g_led_pin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LED_BLINK_PIN</span><span class="p">;</span>
<span class="w"> </span><span class="n">hal_gpio_init_out</span><span class="p">(</span><span class="n">g_led_pin</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_sched_get_current_task</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">t</span><span class="o">-&gt;</span><span class="n">t_func</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">work_task_handler</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Do work... */</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</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>
</div>
<div class="section" id="task-priority">
<h3><a class="toc-backref" href="#id9">Task Priority</a><a class="headerlink" href="#task-priority" title="Permalink to this headline"></a></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 class="docutils literal notranslate"><span class="pre">work_task</span></code> to 0, because everyone knows
that work is more important than blinking.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define WORK_TASK_PRIO (0)</span>
</pre></div>
</div>
</div>
<div class="section" id="initialization">
<h3><a class="toc-backref" href="#id10">Initialization</a><a class="headerlink" href="#initialization" title="Permalink to this headline"></a></h3>
<p>To initialize a new task we use <code class="docutils literal notranslate"><span class="pre">os_task_init()</span></code>
which takes a number of arguments including our new task function,
stack, and priority.</p>
<p>Add the <code class="docutils literal notranslate"><span class="pre">init_tasks()</span></code> function to initialize <code class="docutils literal notranslate"><span class="pre">work_task</span></code> to keep
our main function clean.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span>
<span class="nf">init_tasks</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="cm">/* … */</span>
<span class="w"> </span><span class="n">os_stack_t</span><span class="w"> </span><span class="o">*</span><span class="n">work_stack</span><span class="p">;</span>
<span class="w"> </span><span class="n">work_stack</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">os_stack_t</span><span class="p">)</span><span class="o">*</span><span class="n">WORK_STACK_SIZE</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">work_stack</span><span class="p">);</span>
<span class="w"> </span><span class="n">os_task_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">work_task</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;work&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">work_task_handler</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span>
<span class="w"> </span><span class="n">WORK_TASK_PRIO</span><span class="p">,</span><span class="w"> </span><span class="n">OS_WAIT_FOREVER</span><span class="p">,</span><span class="w"> </span><span class="n">work_stack</span><span class="p">,</span>
<span class="w"> </span><span class="n">WORK_STACK_SIZE</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Add the call to <code class="docutils literal notranslate"><span class="pre">init_tasks()</span></code> in <code class="docutils literal notranslate"><span class="pre">main()</span></code> before the <code class="docutils literal notranslate"><span class="pre">while</span></code>
loop:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span>
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="p">...</span>
<span class="w"> </span><span class="cm">/* Initialize the work task */</span>
<span class="w"> </span><span class="n">init_tasks</span><span class="p">();</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">...</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>And that’s it! Now run your application using the newt run command.</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>newt<span class="w"> </span>run<span class="w"> </span>arduino_blinky<span class="w"> </span><span class="m">0</span>.0.0
</pre></div>
</div>
<p>When GDB appears press C then Enter to continue and … <em>wait, why
doesn’t our LED blink anymore?</em></p>
<div class="section" id="review">
<h4>Review<a class="headerlink" href="#review" title="Permalink to this headline"></a></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="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/* My Task */</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">os_task</span><span class="w"> </span><span class="n">mytask</span>
<span class="cm">/* My Task Stack */</span>
<span class="cp">#define MYTASK_STACK_SIZE OS_STACK_ALIGN(256)</span>
<span class="n">os_stack_t</span><span class="w"> </span><span class="n">mytask_stack</span><span class="p">[</span><span class="n">MYTASK_STACK_SIZE</span><span class="p">];</span>
<span class="cm">/* My Task Priority */</span>
<span class="cp">#define MYTASK_PRIO (0)</span>
</pre></div>
</div>
<p><strong>2)</strong> Define task function:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span>
<span class="nf">mytask_handler</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* ... */</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p><strong>3)</strong> Initialize the task:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">os_task_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mytask</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;mytask&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">mytask_handler</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span>
<span class="w"> </span><span class="n">MYTASK_PRIO</span><span class="p">,</span><span class="w"> </span><span class="n">OS_WAIT_FOREVER</span><span class="p">,</span><span class="w"> </span><span class="n">mytask_stack</span><span class="p">,</span>
<span class="w"> </span><span class="n">MYTASK_STACK_SIZE</span><span class="p">);</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="task-priority-preempting-and-context-switching">
<h2><a class="toc-backref" href="#id11">Task Priority, Preempting, and Context Switching</a><a class="headerlink" href="#task-priority-preempting-and-context-switching" title="Permalink to this headline"></a></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 class="docutils literal notranslate"><span class="pre">work_task</span></code> (priority 0) has a higher priority than
the <code class="docutils literal notranslate"><span class="pre">main</span></code> task (priority 127). Since <code class="docutils literal notranslate"><span class="pre">work_task</span></code> is never put into
a <em>sleep</em> state, it holds the processor focus on its context.</p>
<p>Let’s give <code class="docutils literal notranslate"><span class="pre">work_task</span></code> a delay and some simulated work to keep it
busy. The delay is measured in os ticks and the actual number of ticks
per second is dependent on the board. We multiply <code class="docutils literal notranslate"><span class="pre">OS_TICKS_PER_SEC</span></code>,
which is defined in the MCU, by the number of seconds we wish to delay.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span>
<span class="nf">work_task_handler</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">os_task</span><span class="w"> </span><span class="o">*</span><span class="n">t</span><span class="p">;</span>
<span class="w"> </span><span class="n">g_led_pin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LED_BLINK_PIN</span><span class="p">;</span>
<span class="w"> </span><span class="n">hal_gpio_init_out</span><span class="p">(</span><span class="n">g_led_pin</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_sched_get_current_t</span><span class="o">:</span><span class="n">ask</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">t</span><span class="o">-&gt;</span><span class="n">t_func</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">work_task_handler</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Do work... */</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1000000</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* Simulate doing a noticeable amount of work */</span>
<span class="w"> </span><span class="n">hal_gpio_write</span><span class="p">(</span><span class="n">g_led_pin</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">os_time_delay</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">OS_TICKS_PER_SEC</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In order to notice the LED changing, modify the time delay in
<code class="docutils literal notranslate"><span class="pre">main()</span></code> to blink at a higher frequency.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">os_time_delay</span><span class="p">(</span><span class="n">OS_TICKS_PER_SEC</span><span class="o">/</span><span class="mi">10</span><span class="p">);</span>
</pre></div>
</div>
<p>Before we run the app, let’s predict the behavior. With the newest
additions to <code class="docutils literal notranslate"><span class="pre">work_task_handler()</span></code>, our first action will be to sleep
for three seconds. This allows the <code class="docutils literal notranslate"><span class="pre">main</span></code> task, running <code class="docutils literal notranslate"><span class="pre">main()</span></code>, to
take over the CPU and blink to its heart’s content. After three seconds,
<code class="docutils literal notranslate"><span class="pre">work_task</span></code> will wake up and be made <em>ready to run</em>. This causes it to
preempt the <code class="docutils literal notranslate"><span class="pre">main</span></code> task. The LED will then remain lit for a short
period while <code class="docutils literal notranslate"><span class="pre">work_task</span></code> loops, then blink again for another three
seconds while <code class="docutils literal notranslate"><span class="pre">work_task</span></code> sleeps.</p>
<p>You should see that our prediction was correct!</p>
<div class="section" id="priority-management-considerations">
<h3><a class="toc-backref" href="#id12">Priority Management Considerations</a><a class="headerlink" href="#priority-management-considerations" title="Permalink to this headline"></a></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 shows the different scheduling patterns we would
expect when we set the <code class="docutils literal notranslate"><span class="pre">work_task</span></code> priority higher and lower than the
<code class="docutils literal notranslate"><span class="pre">main</span></code> task priority.</p>
<div class="figure align-default" id="id1">
<img alt="Task Scheduling" src="../../_images/task_lesson.png" />
<p class="caption"><span class="caption-text">Task Scheduling</span><a class="headerlink" href="#id1" title="Permalink to this image"></a></p>
</div>
<p>In the second case where the <code class="docutils literal notranslate"><span class="pre">main</span></code> task has a higher priority,
<code class="docutils literal notranslate"><span class="pre">work_task</span></code> runs and executes “work” when the <code class="docutils literal notranslate"><span class="pre">main</span></code> task sleeps,
saving us idle time compared to the first case.</p>
<p><strong>Note:</strong> Defining the same priority for two tasks fires an assert in
<code class="docutils literal notranslate"><span class="pre">os_task_init()</span></code> and must be avoided. Priority 127 is reserved for main
task, 255 for idle task.</p>
</div>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="../devmgmt/devmgmt.html" class="btn btn-neutral float-right" title="Remote Device Management" accesskey="n">Next: Remote Device Management <span class="fa fa-arrow-circle-right"></span></a>
<a href="event_queue.html" class="btn btn-neutral" title="How to Use Event Queues to Manage Multiple Events" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: How to Use Event Queues to Manage Multiple Events</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<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>
<a href="">
<img src="../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../_static/js/main.js"></script>
</body>
</html>