2 Commits f1ee95d4fc ... e01c1b971a

Author SHA1 Message Date
  Pat Beirne e01c1b971a remove .html file and move the main link out of gogs...into nginx 2 weeks ago
  Pat Beirne f1ee95d4fc Main page fixup 2 weeks ago
4 changed files with 293 additions and 1800 deletions
  1. 0 1775
      CooperativeMultitasking.html
  2. 18 24
      CooperativeMultitasking.md
  3. 1 1
      README.md
  4. 274 0
      pandoc.css

+ 0 - 1775
CooperativeMultitasking.html

@@ -1,1775 +0,0 @@
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
-<head>
-  <meta charset="utf-8" />
-  <meta name="generator" content="pandoc" />
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
-  <meta name="author" content="Pat Beirne" />
-  <title>Cooperative Multitasking</title>
-  <style>
-    code{white-space: pre-wrap;}
-    span.smallcaps{font-variant: small-caps;}
-    div.columns{display: flex; gap: min(4vw, 1.5em);}
-    div.column{flex: auto; overflow-x: auto;}
-    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
-    /* The extra [class] is a hack that increases specificity enough to
-       override a similar rule in reveal.js */
-    ul.task-list[class]{list-style: none;}
-    ul.task-list li input[type="checkbox"] {
-      font-size: inherit;
-      width: 0.8em;
-      margin: 0 0.8em 0.2em -1.6em;
-      vertical-align: middle;
-    }
-    .display.math{display: block; text-align: center; margin: 0.5rem auto;}
-    /* CSS for syntax highlighting */
-    pre > code.sourceCode { white-space: pre; position: relative; }
-    pre > code.sourceCode > span { line-height: 1.25; }
-    pre > code.sourceCode > span:empty { height: 1.2em; }
-    .sourceCode { overflow: visible; }
-    code.sourceCode > span { color: inherit; text-decoration: inherit; }
-    div.sourceCode { margin: 1em 0; }
-    pre.sourceCode { margin: 0; }
-    @media screen {
-    div.sourceCode { overflow: auto; }
-    }
-    @media print {
-    pre > code.sourceCode { white-space: pre-wrap; }
-    pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
-    }
-    pre.numberSource code
-      { counter-reset: source-line 0; }
-    pre.numberSource code > span
-      { position: relative; left: -4em; counter-increment: source-line; }
-    pre.numberSource code > span > a:first-child::before
-      { content: counter(source-line);
-        position: relative; left: -1em; text-align: right; vertical-align: baseline;
-        border: none; display: inline-block;
-        -webkit-touch-callout: none; -webkit-user-select: none;
-        -khtml-user-select: none; -moz-user-select: none;
-        -ms-user-select: none; user-select: none;
-        padding: 0 4px; width: 4em;
-        color: #aaaaaa;
-      }
-    pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
-    div.sourceCode
-      {   }
-    @media screen {
-    pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
-    }
-    code span.al { color: #ff0000; font-weight: bold; } /* Alert */
-    code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
-    code span.at { color: #7d9029; } /* Attribute */
-    code span.bn { color: #40a070; } /* BaseN */
-    code span.bu { color: #008000; } /* BuiltIn */
-    code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
-    code span.ch { color: #4070a0; } /* Char */
-    code span.cn { color: #880000; } /* Constant */
-    code span.co { color: #60a0b0; font-style: italic; } /* Comment */
-    code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
-    code span.do { color: #ba2121; font-style: italic; } /* Documentation */
-    code span.dt { color: #902000; } /* DataType */
-    code span.dv { color: #40a070; } /* DecVal */
-    code span.er { color: #ff0000; font-weight: bold; } /* Error */
-    code span.ex { } /* Extension */
-    code span.fl { color: #40a070; } /* Float */
-    code span.fu { color: #06287e; } /* Function */
-    code span.im { color: #008000; font-weight: bold; } /* Import */
-    code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
-    code span.kw { color: #007020; font-weight: bold; } /* Keyword */
-    code span.op { color: #666666; } /* Operator */
-    code span.ot { color: #007020; } /* Other */
-    code span.pp { color: #bc7a00; } /* Preprocessor */
-    code span.sc { color: #4070a0; } /* SpecialChar */
-    code span.ss { color: #bb6688; } /* SpecialString */
-    code span.st { color: #4070a0; } /* String */
-    code span.va { color: #19177c; } /* Variable */
-    code span.vs { color: #4070a0; } /* VerbatimString */
-    code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
-  </style>
-  <link rel="stylesheet" href="pandoc.css" />
-</head>
-<body>
-<header id="title-block-header">
-<h1 class="title">Cooperative Multitasking</h1>
-<p class="author">Pat Beirne</p>
-<p class="date">2025/01/15</p>
-</header>
-<nav id="TOC" role="doc-toc">
-<ul>
-<li><a href="#part-1-cooperative-multitasking"
-id="toc-part-1-cooperative-multitasking">Part 1: Cooperative
-Multitasking</a>
-<ul>
-<li><a href="#intro" id="toc-intro">Intro</a>
-<ul>
-<li><a href="#abstract" id="toc-abstract">Abstract</a></li>
-<li><a href="#audience" id="toc-audience">Audience</a></li>
-</ul></li>
-<li><a href="#the-problem" id="toc-the-problem">The Problem</a></li>
-<li><a href="#first-page" id="toc-first-page">First Page</a></li>
-<li><a href="#interrupts" id="toc-interrupts">Interrupts</a></li>
-<li><a href="#events" id="toc-events">Events</a></li>
-<li><a href="#newevent" id="toc-newevent">newEvent()</a></li>
-<li><a href="#dispatch" id="toc-dispatch">Dispatch</a></li>
-<li><a href="#tasks" id="toc-tasks">Tasks</a></li>
-<li><a href="#state-machine" id="toc-state-machine">State
-Machine</a></li>
-<li><a href="#another-state-machine"
-id="toc-another-state-machine">Another State Machine</a></li>
-<li><a href="#dispatcher-details" id="toc-dispatcher-details">Dispatcher
-Details</a></li>
-<li><a href="#final-implementation" id="toc-final-implementation">Final
-Implementation</a></li>
-</ul></li>
-<li><a href="#part-2" id="toc-part-2">Part 2</a>
-<ul>
-<li><a href="#variations" id="toc-variations">Variations</a></li>
-<li><a href="#working-with-arduino"
-id="toc-working-with-arduino">Working with Arduino</a></li>
-<li><a href="#tasks-1" id="toc-tasks-1">Tasks</a></li>
-<li><a href="#state-machine-examples"
-id="toc-state-machine-examples">State Machine Examples</a>
-<ul>
-<li><a href="#car-window" id="toc-car-window">Car Window</a></li>
-<li><a href="#fridge-door" id="toc-fridge-door">Fridge Door</a></li>
-<li><a href="#door-opener" id="toc-door-opener">Door Opener</a></li>
-<li><a href="#beer-vat" id="toc-beer-vat">Beer Vat</a></li>
-<li><a href="#vending-machine" id="toc-vending-machine">Vending
-Machine</a></li>
-</ul></li>
-<li><a href="#events-1" id="toc-events-1">Events</a></li>
-<li><a href="#timers" id="toc-timers">Timers</a></li>
-<li><a href="#real-code" id="toc-real-code">Real Code</a></li>
-<li><a href="#substates" id="toc-substates">Substates</a></li>
-<li><a href="#state-machine-initialization"
-id="toc-state-machine-initialization">State Machine
-Initialization</a></li>
-<li><a href="#messages" id="toc-messages">Messages</a>
-<ul>
-<li><a href="#postmessage" id="toc-postmessage">PostMessage</a></li>
-<li><a href="#sendmessage" id="toc-sendmessage">SendMessage</a></li>
-<li><a href="#usage" id="toc-usage">Usage</a></li>
-</ul></li>
-<li><a href="#ideas-for-tasks" id="toc-ideas-for-tasks">Ideas for
-Tasks</a></li>
-<li><a href="#more-state-machines" id="toc-more-state-machines">More
-State Machines</a>
-<ul>
-<li><a href="#radio-tuner" id="toc-radio-tuner">Radio Tuner</a></li>
-</ul></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="part-1-cooperative-multitasking">Part 1: Cooperative
-Multitasking</h1>
-<!-- ## Introduction -->
-<p>Small microcontrollers are often required to handle several tasks,
-sometimes with overlapping phases. This paper will lead you through the
-creation of a small <strong><em>operating system</em></strong> which can
-be implemented on a tiny microcontroller, without the fancy time-slicing
-that is offered by sophisticated operating systems like <a
-href="https://linux.org">Linux</a> and <a
-href="https://freertos.org">FreeRTos</a>.</p>
-<p>The core of <em>this</em> technique is covered in <a
-href="#part-1-cooperative-multitasking">Part 1</a> of this paper. If you
-just want to see how it all comes together, jump to <a
-href="#final-implementation">Final Implementaion</a>.</p>
-<p><a href="#part-2">Part 2</a> contains enhancements and variations,
-probably useful reading if you decide to adopt this programming
-technique in your projects.</p>
-<h2 id="intro">Intro</h2>
-<h3 id="abstract">Abstract</h3>
-<p>This paper will take you through the creation of a tiny <em>operating
-system</em> that can be implemented on a small microcontroller.</p>
-<h3 id="audience">Audience</h3>
-<p>These techniques can be applied by anyone with experience in
-<strong><em>C</em></strong>, <strong><em>Python</em></strong> or any
-modern computer language. It helps to have a passing knowledge of how to
-connect a transducer (button, LED, buzzer, etc) to a
-microcontroller.</p>
-<blockquote>
-<p>The <strong><em>Reality Check</em></strong> dropdowns in this article
-provide extra, often practical supplementary reading.</p>
-</blockquote>
-<details>
-<summary>
-Reality Check
-</summary>
-<p>The technique described here is also called <strong><em>event driven
-programming</em></strong>.</p>
-<p>This technique was used in the original Window (1995), including some
-of the system calls:
-<code>sendMessage(), postMessage() and setTimer()</code>.</p>
-<p>This event-driven technique is applicable to a whole host of small
-microcontrollers, including</p>
-<ul>
-<li>MSP430</li>
-<li>Cortex M0, M0+ (SAM, STM32, PY32, Cypress, Kinetis, HT32, XMC,
-LPC81x)</li>
-<li>AtMega, AtTiny</li>
-<li>8051 (SiliconLabs, Nuvoton, HT85)</li>
-<li>RL78 (Renesas)</li>
-<li>Pic 12/14/16</li>
-<li>Risc (ch32v)</li>
-<li>STM8</li>
-</ul>
-<p><em>Some of the really tiny ones don’t have enough stack space to
-implement these techniques (Puolop PB150, Padauk PxS15x, Bojuxing BJ8P,
-Yspring MDT1x, EastSoft HR7P, Holtek Ht68.)</em></p>
-<img src="blb.jpg" alt="Here" /> is a typical board hosting 12 buttons,
-12 RGB LEDs, all hosted by an STM32. Every light and button can be
-controlled separately and simultaneously, using the technique described
-in this paper.
-</details>
-<h2 id="the-problem">The Problem</h2>
-<p>Let’s suppose we want to flash an LED at 1 flash/2 sec, and
-independently, respond to a push button by operating a different LED for
-1.5 seconds. Both operations must operate separately. How do we
-structure the code for the microcontroller to make this happen?</p>
-<h2 id="first-page">First Page</h2>
-<p>Let’s look an a pseudocode overview of what we want to do:</p>
-<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> initialize<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  setup_hardware<span class="op">();</span></span>
-<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  setup_interrupts<span class="op">();</span></span>
-<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>INTERRUPT <span class="dt">void</span> irq<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  create_event<span class="op">();</span></span>
-<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>  acknowledge_interrupt<span class="op">();</span></span>
-<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  initialize<span class="op">();</span></span>
-<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span><span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>      flashLedTask<span class="op">(</span>event<span class="op">);</span></span>
-<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>      respondToButtonTask<span class="op">(</span>event<span class="op">);</span></span>
-<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>That’s about it.</p>
-<p>Of course, we will need to write the code for
-<code>setup_hardware()</code> and <code>setup_interrupts()</code>. And
-<code>flashLedTask()</code> and <code>respondToButtonTask()</code>. And
-create the <em>magic</em> that allows <code>event</code> information to
-flow. Don’t worry, it will all be laid out in the following pages.</p>
-<p>If you’re concerned with complexity, feel free to jump ahead to the
-<a href="#final-implementation">final implementation</a> page to see
-real, tested, code.</p>
-<p>Between here and there, I’ll walk you step-by-step through building
-the structure and implementation.</p>
-<p>This paper continues after that though, to show you how to expand
-upon a build as the project-definition changes. There are also several
-examples of state machines, and some discussion of practical matters,
-refactoring and project structure.</p>
-<h2 id="interrupts">Interrupts</h2>
-<p>In order to have a responsive system, it would make sense to use the
-<em>interrupt</em> capabilities of these small micrcontrollers.</p>
-<p>In the task described, we need to respond to a button press. So let’s
-connect the button to an input pin and enable it to repsond to a button
-press with interrupt code.</p>
-<p>We also need to keep track of time…..so let’s hook up a system timer
-to another interrupt.</p>
-<p>Each interrupt causes the execution of <em>interrupt handler</em>
-code. For this project, it might look somthing like this:</p>
-<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>EVT_NONE<span class="op">,</span> EVT_TICK<span class="op">,</span> EVT_BUTTON<span class="op">};</span></span>
-<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>INTERRUPT timer_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_TICK<span class="op">);</span></span>
-<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>INTERRUPT button_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_BUTTON<span class="op">);</span>  <span class="co">// see notes about button bounce and acknowledgement</span></span>
-<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>The interrupt handlers are both very simple. They just create a
-unique <em>event</em> and let the system know about it. Next, let’s talk
-about <em>events</em>.</p>
-<details>
-<summary>
-Reality check
-</summary>
-<p>In some microcontrollers, interrupts must be <em>acknowledged</em>.
-Sometimes that means setting a hardware flag to indicate to the device
-that you’re ready for another interrupt of the same type. And in some
-cases, there’s no need to ack. Specifically, the SYS_TICK interrupt in
-the ARM Cortex processors does <em>not</em> need an ack, so the above
-code example for <code>timer_isr()</code> is complete.</p>
-<p>When a pushbutton or switch is connected to a microcontroller, the
-first bit of activity will cause the interrupt and execute the
-<code>button_isr()</code> code. However, real buttons produce about
-5msec of <em>bounce</em> and this will cause subsequent interrupts
-unless they are somehow filtered out. There are lots of ways to handle
-<em>bounce</em>, and I’ll let you read about that
-[elsewhere]](#debouncing). Most techniques boil down to either ignoring
-subsequent interrupts (from the same button) for about 5 msec, or
-disabling that specific interrupt until the 5msec has passed.</p>
-<p>As a general rule, <em>input</em> pins should be observed either by
-interrupt service routine (ISR), or scanned periodically by the timer
-ISR. <em>Outputs</em> should be controlled in the task code, which we’ll
-see below.</p>
-</details>
-<h2 id="events">Events</h2>
-<p>An <em>event</em> in this context is a small bit of information that
-appears asynchronously in the system. Implemented, it can be a
-<em>byte</em>, or an <em>int</em> or an even larger structure. But in
-these small microcontrollers, let’s use a <em>byte</em>.</p>
-<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="dt">volatile</span> uint8 event<span class="op">;</span></span></code></pre></div>
-<p>These <em>events</em> will be created in interrupt level of the code,
-and processed at the main level. We use the <code>event</code> object to
-send information between these levels, so we have to mark it <a
-href="https://en.wikipedia.org/wiki/Volatile_(computer_programming)"><code>volatile</code></a>.</p>
-<p>In this paper, the word <em>message</em> and <em>event</em> are
-equivalent. <em>Message</em> has the sense of “a bit of communication
-from another part of the program” and <em>event</em> has the sense of
-“something external just happened”. At this point in the design, they
-both mean the same thing.</p>
-<p>By convention, let’s use <em>zero</em> to indicate the absence of an
-event/message, and <em>non-zero</em> to represent an event/message.</p>
-<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">volatile</span> uint8 event<span class="op">;</span></span>
-<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>EVT_NONE<span class="op">,</span> EVT_TICK<span class="op">,</span> EVT_BUTTON<span class="op">};</span> <span class="co">// 0,1,2</span></span></code></pre></div>
-<details>
-<summary>
-Reality check
-</summary>
-<hr>
-For this project, let’s suppose the timer ticks happen every 10ms (100
-per second).
-<hr>
-</details>
-<p>So now we start to get an idea of what kind of information the
-<em>interrupt handler</em> code generates. Now let’s look at how that
-information gets sent to the rest of the code:
-<code>newEvent()</code>.</p>
-<h2 id="newevent">newEvent()</h2>
-<p>Here’s a block diagram of the message flow <img
-src="dispatch1.jpg" /></p>
-<p>How do we send the information (events/messages) from the interrupt
-service routine to the <code>main()</code> code? We used shared
-memory.</p>
-<p>One way would be to have a global <code>volatile uint8</code>
-location into which we drop the <em>event</em> information. But having
-only one socket for that would be a bit naive; what happens if a timer
-tick and a button press happen very close in time? What happens if the
-timer tick events start to stack up?</p>
-<p>It makes more sense to have an array:
-<code>volatile uint8 events[NUM_EVENTS]</code> where NUM_EVENTS is on
-the order of 5..10. That would give us 50-100msec to catch up in case
-there’s a pileup of events/messages.</p>
-<p>At the beginning, before anything happens, we need to make sure the
-<code>events[]</code> is full of zeros (EVT_NONE), indicating that it’s
-empty.</p>
-<p>The <code>newEvent(evt)</code> routine simply adds the
-<code>evt</code> to the array <code>events[]</code>.</p>
-<p>Something like this might work:</p>
-<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span>uint8r evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">static</span> <span class="dt">unsigned</span> uint8 nextEvent<span class="op">;</span></span>
-<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  events<span class="op">[</span>nextEvent<span class="op">++]</span> <span class="op">=</span> evt<span class="op">;</span></span>
-<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>nextEvent <span class="op">==</span> NUM_EVENTS<span class="op">)</span></span>
-<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    nextEvent <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<details>
-<summary>
-Reality check
-</summary>
-<p>There is a problem with the above code. What happens if a
-<code>key_isr()</code> is running, and is halfway through its call to
-<code>newEvent()</code> when a <code>timer_isr()</code> happens, and
-reenters the <code>newEvent()</code> routine. This will get really
-messed up. So we need to wrap <em>this particular</em> code in a
-critical section.</p>
-<p>Here’s a more realistic version:</p>
-<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span><span class="dt">char</span> evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">char</span> nextEvent<span class="op">;</span>   <span class="co">// keep track of where we are in queue</span></span>
-<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  disable_irq<span class="op">();</span>                    <span class="co">// critical section</span></span>
-<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  events<span class="op">[</span>nextEvent<span class="op">++]</span> <span class="op">=</span> evt<span class="op">;</span>        <span class="co">// insert event into queue</span></span>
-<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>nextEvent <span class="op">==</span> NUM_EVENTS<span class="op">)</span>      <span class="co">// loop back to the start of queue</span></span>
-<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    nextEvent <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  enable_irq<span class="op">();</span>           <span class="co">// end critical section, probably &lt;100us of blockage</span></span>
-<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-</details>
-<p>In the next section, we’ll show how the <code>main()</code> code
-pulls the events out of the array, and leaves an EVT_NONE in its
-place.</p>
-<h2 id="dispatch">Dispatch</h2>
-<p>The <code>main()</code> code can simply watch the
-<code>events[]</code> to see when an entry goes non-zero (!=EVT_NONE).
-When that happens, <code>main()</code> will pull out the
-<em>event/message</em> from the array, and call the task subroutines. In
-this case, <code>flashLedTask()</code> and
-<code>respondToButtonTask()</code>.</p>
-<p>To see the real code for the dispatcher, <a
-href="#dispatcher-details">jump ahead</a>.</p>
-<details>
-<summary>
-Terminology
-</summary>
-<p>The <code>main()</code> code illustrated here calls the tasks as
-subroutines, sending each one a copy of the event number.</p>
-<p>As I mentioned earlier, <em>events</em> can also be refered to as
-<em>messages</em>. We can also refer to this process “sending a message
-to the task”</p>
-<p>So, for this paper, these are equivalent</p>
-<ul>
-<li>calling a task subroutine with the event information</li>
-<li>sending a message to a task</li>
-</ul>
-</details>
-<figure>
-<img src="dispatch2.jpg" alt="Call task routines with event" />
-<figcaption aria-hidden="true">Call task routines with
-event</figcaption>
-</figure>
-<details>
-<summary>
-Reality check
-</summary>
-<p>It may seem wasteful to send <em>all</em> events to <em>all</em>
-tasks. Probably some tasks don’t care about certain classes of events.
-But classifying, sorting and filtering the events takes real time, and
-code space, and probably isn’t worth it for these small
-microcontrollers.</p>
-<p>More sophisticated event systems do, in fact, filter and sort events.
-For example, Windows only sends <code>MOUSE_MOVE</code> events to the
-code belonging to the window over which the mouse is travelling. All the
-other windows don’t get the event, speeding up the whole system.</p>
-</details>
-<h2 id="tasks">Tasks</h2>
-<p>In this environment, the code that impliments a <em>task</em> is
-simply a subroutine that accepts an <em>event/message</em>.</p>
-<div class="sourceCode" id="cb7"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> taskCode<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">...</span> process the event information <span class="op">...</span></span>
-<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>The subroutine should be designed to flow-through as quickly as
-possible, without any pauses/waits/delays.</p>
-<p>If the problem that you’re trying to solve involves the passage of
-time, or any delay, then you must break down the actions into individual
-items, and build a <a href="#state-machine">state machine</a>.</p>
-<h2 id="state-machine">State Machine</h2>
-<p>A <em>state machine</em> in this environment is a subroutine which
-can be called many times, and it remembers in which <em>state</em> it
-was left from the previous call. Some invocations of this subroutine may
-cause it to change state, which can be represented in a net diagram.</p>
-<p>Here’s a state diagram for the task which reacts to a button press by
-flashing an LED.</p>
-<figure>
-<img src="rtb_state.png" alt="simple state diagram" />
-<figcaption aria-hidden="true">simple state diagram</figcaption>
-</figure>
-<p>How does the <em>state code</em> remember what state it’s in between
-invocations? We can use a <code>static</code> variable. A
-<code>static</code> is stored in main memory (<em>not on the
-stack</em>), persists between calls and is initialized to zero.</p>
-<p>The above diagram can be implemented in this code:</p>
-<div class="sourceCode" id="cb8"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>RTB_IDLE<span class="op">,</span> RTB_ON<span class="op">};</span>          <span class="co">// RTB_IDLE=0, RTB_ON=1</span></span>
-<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8  rtbState      <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint16 rtbTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span>  uint16 TIMER_LIMIT   <span class="op">=</span> <span class="dv">150</span><span class="op">;</span></span>
-<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> respondToButtonTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>rtbState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>        rtbTimerCount <span class="op">=</span> TIMER_LIMIT<span class="op">;</span></span>
-<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> ON<span class="op">);</span></span>
-<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_ON<span class="op">:</span></span>
-<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>rtbTimerCount <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>Each time this routine is called, it checks the <em>event</em> that
-it was given, and sometimes processes it. And sometimes it changes
-state.</p>
-<p>Here’s a few things to notice:</p>
-<ul>
-<li>The code <em>flows through</em>. It does not stop or wait for
-anything.</li>
-<li>Each arrow in the net diagram corresponds to a phrase in the code.
-The <em>tail</em> of the arrow corresponds to an <code>if</code>
-statement</li>
-<li>The code ignores <em>events</em> that are not relevant.</li>
-</ul>
-<details>
-<summary>
-Reality check
-</summary>
-<p>The <em>state</em> variable must be <code>static</code> or in the
-global memory space. <em>NEVER put a state variable on the stack!</em>
-i.e. as a local variable.</p>
-The tick counter could equally well count up from zero to threshold. See
-the discussion about <a href="#timers-as-a-resource">shared timers</a>
-</details>
-<h2 id="another-state-machine">Another State Machine</h2>
-<p>The other task of this project simply flashes the LED on and off.</p>
-<p><img src="led_state_simple.png" /></p>
-<p>The code for this might be:</p>
-<div class="sourceCode" id="cb9"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>LED_ON<span class="op">,</span> LED_OFF<span class="op">};</span></span>
-<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8 ledState       <span class="op">=</span> LED_OFF<span class="op">;</span></span>
-<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint16 ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span>  uint16 LED_ON_TIME   <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
-<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span>  uint16 LED_OFF_TIME  <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
-<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> ledTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>ledState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> LED_OFF<span class="op">:</span></span>
-<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>ledTimerCount <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> ON<span class="op">);</span></span>
-<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>          ledTimerCount <span class="op">=</span> LED_ON_TIME<span class="op">;</span></span>
-<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>          ledState <span class="op">=</span> LED_ON<span class="op">;</span></span>
-<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> LED_ON<span class="op">:</span></span>
-<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>ledTimerCount <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>          ledTimerCount <span class="op">=</span> LED_OFF_TIME<span class="op">;</span></span>
-<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a>          ledState <span class="op">=</span> LED_OFF<span class="op">;</span></span>
-<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<details>
-<summary>
-Discussion
-</summary>
-<p>Perhaps a more accurate state diagram might be:</p>
-<p><img src="led_state.png" /></p>
-<p>As you build the code from the diagram, I <em>strongly</em> suggest
-that you use a <code>switch(currentState) ....case STATE_1</code>
-approach to the task routine. If you try and code it with multiple
-<code>if(currentState==STATE_1)</code>, you will find yourself in a
-tangle of spaghetti; and if you forget a critical <code>else</code>,
-nothing will work as you expect.</p>
-<div class="sourceCode" id="cb10"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>state<span class="op">==</span><span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>event <span class="op">=</span> EVT_1<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    P3OUT <span class="op">=</span> <span class="dv">27</span><span class="op">;</span> <span class="co">// turn on some hardware</span></span>
-<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    state <span class="op">=</span> <span class="dv">2</span><span class="op">;</span>  <span class="co">// and change state</span></span>
-<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> </span>
-<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>state<span class="op">==</span><span class="dv">2</span><span class="op">)</span> <span class="op">{</span> <span class="co">// &lt;&lt;&lt;----- BAD BAD</span></span>
-<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  P3OUT <span class="op">=</span> <span class="dv">14</span><span class="op">;</span></span>
-<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>  state <span class="op">=</span> <span class="dv">3</span><span class="op">;</span>    <span class="co">// &lt;&lt;&lt;--- dont&#39; change state twice in the same event</span></span>
-<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span></code></pre></div>
-<p>rather</p>
-<div class="sourceCode" id="cb11"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="cf">switch</span><span class="op">(</span>state<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="dv">1</span><span class="op">:</span></span>
-<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>event <span class="op">=</span> EVT_1<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>      P3OUT <span class="op">=</span> <span class="dv">27</span><span class="op">;</span>   <span class="co">// turn on some hardware</span></span>
-<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>      state <span class="op">=</span> <span class="dv">2</span><span class="op">;</span></span>
-<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="dv">2</span><span class="op">:</span></span>
-<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>    P3OUT <span class="op">=</span> <span class="dv">14</span><span class="op">;</span></span>
-<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    state <span class="op">=</span> <span class="dv">3</span><span class="op">;</span></span>
-<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">...</span></span>
-<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>As a general rule, try to avoid changing states more than once per
-event; this kind of discipline will help with debugging a complex
-project.</p>
-</details>
-<h2 id="dispatcher-details">Dispatcher Details</h2>
-<p>The last piece of the puzzle is the <code>main()</code> code which
-observes the <code>events[]</code> array and calls the tasks.</p>
-<p>The <code>events[]</code> array is designed so that a 0 means ‘no
-event’, and the non-zero events are dropped into the array in order…so
-pulling them out is pretty straight forward.</p>
-<div class="sourceCode" id="cb12"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main<span class="op">()</span> <span class="op">{</span></span>
-<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  initialize<span class="op">();</span></span>
-<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span><span class="op">(</span><span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i<span class="op">;</span></span>
-<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>i<span class="op">=</span><span class="dv">0</span><span class="op">;</span> i<span class="op">&lt;</span>NUM_EVENTS<span class="op">;</span> i<span class="op">++)</span> <span class="op">{</span></span>
-<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">while</span> <span class="op">(</span>events<span class="op">[</span>i<span class="op">]==</span>EVT_NONE<span class="op">)</span></span>
-<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">{}</span></span>
-<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>      ledTask<span class="op">(</span>events<span class="op">[</span>i<span class="op">]);</span></span>
-<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>      respondToButtonTask<span class="op">(</span>events<span class="op">[</span>i<span class="op">]);</span></span>
-<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>      events<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> EVT_NONE<span class="op">;</span></span>
-<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>Each non-zero event is “sent” to each task…..by means of a subroutine
-call. Once all the tasks have been invoked, the <code>event</code> is
-thrown away and its slot in the array is set to zero.</p>
-<details>
-<summary>
-Reality check
-</summary>
-<p>The <code>main()</code> code above needs to run with interrupts
-enabled.</p>
-<p>There’s lots of ways to structure the ‘wait for event’ loop. For
-example, when you detect that the <code>events[]</code> array is empty,
-you could power-down the microcontroller. In most microprocessors, an
-interrupt will wake the CPU again, and deliver a non-zero event into the
-array, so you might as well power-down while you’re waiting.</p>
-</details>
-<h2 id="final-implementation">Final Implementation</h2>
-<p>Let’s put all of the above together, for an SMT32F Cortex M0, in
-<em>C</em> code.</p>
-<div class="sourceCode" id="cb13"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="co">/***** declarations ****/</span></span>
-<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#define NUM_EVENTS </span><span class="dv">10</span></span>
-<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="dt">volatile</span> uint8 events<span class="op">[</span>NUM_EVENTS<span class="op">];</span></span>
-<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span>uint8 e<span class="op">);</span></span>
-<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> ledTask<span class="op">(</span>uint8 evt<span class="op">);</span></span>
-<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> respondToButtonTask<span class="op">(</span>uint8 evt<span class="op">);</span></span>
-<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a><span class="co">/********** interrupts **************/</span></span>
-<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> timer_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_TICK<span class="op">);</span></span>
-<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>  <span class="co">// this interrupt is auto-ack&#39;d</span></span>
-<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> button_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_BUTTON<span class="op">);</span></span>
-<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>  EXTI<span class="op">-&gt;</span>PR <span class="op">|=</span> KEY_IRQ_ACK_MASK<span class="op">;</span>    <span class="co">// the hardware requires that we acknowledge </span></span>
-<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a><span class="co">/** newEvent</span></span>
-<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a><span class="co"> * add the event to the event queue</span></span>
-<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a><span class="co"> * wrapped in critical section</span></span>
-<span id="cb13-24"><a href="#cb13-24" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span></span>
-<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">the</span><span class="co"> event</span></span>
-<span id="cb13-26"><a href="#cb13-26" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
-<span id="cb13-27"><a href="#cb13-27" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span>uint8 e<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-28"><a href="#cb13-28" aria-hidden="true" tabindex="-1"></a>  <span class="dt">static</span> uint8 nextEvent<span class="op">;</span></span>
-<span id="cb13-29"><a href="#cb13-29" aria-hidden="true" tabindex="-1"></a>  dint<span class="op">();</span> <span class="co">// critical section</span></span>
-<span id="cb13-30"><a href="#cb13-30" aria-hidden="true" tabindex="-1"></a>  events<span class="op">[</span>nextEvent<span class="op">++]</span> <span class="op">=</span> e<span class="op">;</span></span>
-<span id="cb13-31"><a href="#cb13-31" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>nextEvent<span class="op">==</span>NUM_EVENTS<span class="op">)</span></span>
-<span id="cb13-32"><a href="#cb13-32" aria-hidden="true" tabindex="-1"></a>    nextEvent <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb13-33"><a href="#cb13-33" aria-hidden="true" tabindex="-1"></a>  eint<span class="op">();</span></span>
-<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a><span class="co">/****** main() and dispatcher *********/</span></span>
-<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a>  eint<span class="op">();</span></span>
-<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a>  <span class="co">// dispatcher loop</span></span>
-<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span><span class="op">(</span><span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> j<span class="op">;</span></span>
-<span id="cb13-44"><a href="#cb13-44" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>j<span class="op">=</span><span class="dv">0</span><span class="op">;</span> j<span class="op">&lt;</span>NUM_EVENTS<span class="op">;</span> j<span class="op">++)</span> <span class="op">{</span></span>
-<span id="cb13-45"><a href="#cb13-45" aria-hidden="true" tabindex="-1"></a>       <span class="cf">while</span> <span class="op">(</span>events<span class="op">[</span>j<span class="op">]==</span>EVT_NONE<span class="op">)</span></span>
-<span id="cb13-46"><a href="#cb13-46" aria-hidden="true" tabindex="-1"></a>         <span class="op">{}</span></span>
-<span id="cb13-47"><a href="#cb13-47" aria-hidden="true" tabindex="-1"></a>       ledTask<span class="op">(</span>events<span class="op">[</span>j<span class="op">]);</span></span>
-<span id="cb13-48"><a href="#cb13-48" aria-hidden="true" tabindex="-1"></a>       respondToButtonTask<span class="op">(</span>events<span class="op">[</span>j<span class="op">]);</span></span>
-<span id="cb13-49"><a href="#cb13-49" aria-hidden="true" tabindex="-1"></a>       events<span class="op">[</span>j<span class="op">]</span> <span class="op">=</span> EVT_NONE<span class="op">;</span></span>
-<span id="cb13-50"><a href="#cb13-50" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb13-51"><a href="#cb13-51" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb13-52"><a href="#cb13-52" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb13-53"><a href="#cb13-53" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-54"><a href="#cb13-54" aria-hidden="true" tabindex="-1"></a><span class="co">/*********** task code, with states ************/</span></span>
-<span id="cb13-55"><a href="#cb13-55" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>LED_ON<span class="op">,</span> LED_OFF<span class="op">};</span></span>
-<span id="cb13-56"><a href="#cb13-56" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>RTB_IDLE<span class="op">,</span> RTB_ON<span class="op">};</span>    <span class="co">// states</span></span>
-<span id="cb13-57"><a href="#cb13-57" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8  rtbState      <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb13-58"><a href="#cb13-58" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint16 rtbTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb13-59"><a href="#cb13-59" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span>  uint16 LED_ON_TIME   <span class="op">=</span> <span class="dv">150</span><span class="op">;</span></span>
-<span id="cb13-60"><a href="#cb13-60" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-61"><a href="#cb13-61" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> respondToButtonTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-62"><a href="#cb13-62" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>rtbState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-63"><a href="#cb13-63" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb13-64"><a href="#cb13-64" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-65"><a href="#cb13-65" aria-hidden="true" tabindex="-1"></a>        rtbTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb13-66"><a href="#cb13-66" aria-hidden="true" tabindex="-1"></a>        rtbState      <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb13-67"><a href="#cb13-67" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb13-68"><a href="#cb13-68" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb13-69"><a href="#cb13-69" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb13-70"><a href="#cb13-70" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_ON<span class="op">:</span></span>
-<span id="cb13-71"><a href="#cb13-71" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-72"><a href="#cb13-72" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(++</span>rtbTimerCount <span class="op">&gt;</span> LED_ON_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-73"><a href="#cb13-73" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb13-74"><a href="#cb13-74" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb13-75"><a href="#cb13-75" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb13-76"><a href="#cb13-76" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb13-77"><a href="#cb13-77" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb13-78"><a href="#cb13-78" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb13-79"><a href="#cb13-79" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb13-80"><a href="#cb13-80" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-81"><a href="#cb13-81" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span>  uint16 LED_ON_TIME   <span class="op">=</span> <span class="dv">150</span><span class="op">;</span></span>
-<span id="cb13-82"><a href="#cb13-82" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span>  uint16 LED_OFF_TIME  <span class="op">=</span> <span class="dv">50</span><span class="op">;</span></span>
-<span id="cb13-83"><a href="#cb13-83" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8 ledState       <span class="op">=</span> LED_OFF<span class="op">;</span></span>
-<span id="cb13-84"><a href="#cb13-84" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint16 ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb13-85"><a href="#cb13-85" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb13-86"><a href="#cb13-86" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> ledTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-87"><a href="#cb13-87" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>ledState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-88"><a href="#cb13-88" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> LED_OFF<span class="op">:</span></span>
-<span id="cb13-89"><a href="#cb13-89" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-90"><a href="#cb13-90" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(++</span>ledTimerCount <span class="op">&gt;</span> LED_OFF_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-91"><a href="#cb13-91" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED2<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb13-92"><a href="#cb13-92" aria-hidden="true" tabindex="-1"></a>          ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb13-93"><a href="#cb13-93" aria-hidden="true" tabindex="-1"></a>          ledState      <span class="op">=</span> LED_ON<span class="op">;</span></span>
-<span id="cb13-94"><a href="#cb13-94" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb13-95"><a href="#cb13-95" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb13-96"><a href="#cb13-96" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb13-97"><a href="#cb13-97" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> LED_ON<span class="op">:</span></span>
-<span id="cb13-98"><a href="#cb13-98" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-99"><a href="#cb13-99" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(++</span>ledTimerCount <span class="op">&gt;</span> LED_ON_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb13-100"><a href="#cb13-100" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED2<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb13-101"><a href="#cb13-101" aria-hidden="true" tabindex="-1"></a>          ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb13-102"><a href="#cb13-102" aria-hidden="true" tabindex="-1"></a>          ledState      <span class="op">=</span> LED_OFF<span class="op">;</span></span>
-<span id="cb13-103"><a href="#cb13-103" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb13-104"><a href="#cb13-104" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb13-105"><a href="#cb13-105" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb13-106"><a href="#cb13-106" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb13-107"><a href="#cb13-107" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>This is the end of the main presentation. With the above techniques,
-you can make a tiny microprocessor appear to multitask.</p>
-<p>For further tips, read the next section. The interesting topics
-are:</p>
-<ul>
-<li><a href="#state-machine-examples">more state code examples</a>
-<ul>
-<li>with implementation</li>
-</ul></li>
-<li><a href="#state-machine-initialization">how to initialize a state
-machine</a></li>
-<li><a href="#messages">inter-task communication</a></li>
-<li><a href="#timers">unified timers</a></li>
-</ul>
-<details>
-<summary>
-Reality Check
-</summary>
-<p>What’s missing from this code sample is the initialization of the
-hardware……..some kind of <code>setup()</code> routine. I left it out
-because it’s going to vary so much between processors, and only
-distracts from the point of this paper. If you want a detailed, tested
-copy of this code, see <a href="build/demo.c">here</a></p>
-The above example only shows 2 tasks, so all the formal structure may
-seem a bit silly. But once you have the infrastructure in place, you can
-easily handle <em>dozens</em> of tasks, even on sub-$1 processors.
-</details>
-<h1 id="part-2">Part 2</h1>
-<h2 id="variations">Variations</h2>
-<style>
-.imageleft {float: left;}
-.imageright {float: right;}
-</style>
-<p>Now that the infrastructure is in place, it’s easy to expand or
-modify the code for changes in the project definition.</p>
-<p>For example, suppose we want the <code>respondToButtonTask()</code>
-to restart the LED timer on each key press:</p>
-<p><img src="rtb_state_2.png" class="imageleft" /></p>
-<div class="sourceCode" id="cb14"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> rtbTask<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>rtbState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>        rtbTimer <span class="op">=</span> RTB_TIMEOUT<span class="op">;</span></span>
-<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_ON<span class="op">:</span></span>
-<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span> </span>
-<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>        rtbTimer <span class="op">=</span> RTB_TIMEOUT<span class="op">;</span></span>
-<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>rtbTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb14-20"><a href="#cb14-20" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb14-21"><a href="#cb14-21" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb14-22"><a href="#cb14-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<hr>
-<p>Or have a 2nd press of the button cause the LED to extinguish
-early:</p>
-<p><img src="rtb_state_3.png" class="imageleft" /></p>
-<div class="sourceCode" id="cb15"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> rtbTask<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>rtbState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>        rtbTimer <span class="op">=</span> RTB_TIMEOUT<span class="op">;</span></span>
-<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_ON<span class="op">:</span></span>
-<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span> </span>
-<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>rtbTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<hr>
-<p>How about have the button start a flash sequence, and a 2nd press
-stops it: (see also <a href="#substates">substates</a>)</p>
-<p><img src="rtb_state_4.png" class="imageright" /></p>
-<div class="sourceCode" id="cb16"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> rtbTask<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>rtbState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>        rtbTimer <span class="op">=</span> RTB_TIMEOUT<span class="op">;</span></span>
-<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_ON<span class="op">:</span></span>
-<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span> </span>
-<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>rtbTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>          rtbTimer <span class="op">=</span> RTB_FLASH_TIME<span class="op">;</span></span>
-<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_OFF<span class="op">;</span></span>
-<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_OFF<span class="op">:</span></span>
-<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span> </span>
-<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb16-27"><a href="#cb16-27" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb16-28"><a href="#cb16-28" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-29"><a href="#cb16-29" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>rtbTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb16-30"><a href="#cb16-30" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb16-31"><a href="#cb16-31" aria-hidden="true" tabindex="-1"></a>          rtbTimer <span class="op">=</span> RTB_FLASH_TIME<span class="op">;</span></span>
-<span id="cb16-32"><a href="#cb16-32" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb16-33"><a href="#cb16-33" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb16-34"><a href="#cb16-34" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb16-35"><a href="#cb16-35" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb16-36"><a href="#cb16-36" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb16-37"><a href="#cb16-37" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<hr>
-<p>Each of these diagrams corresponds to trivial changes in the state
-code.</p>
-<h2 id="working-with-arduino">Working with Arduino</h2>
-<p>If you’re from the Arduino world, you have no doubt seen the
-similarity between this OS plan and the Arduino infrastructure.</p>
-<div class="sourceCode" id="cb17"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>setup<span class="op">()</span> </span>
-<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">{}</span>    <span class="co">// initialize and start up the devices and services</span></span>
-<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>loop<span class="op">()</span></span>
-<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">{}</span>    <span class="co">// code for continuous operation</span></span></code></pre></div>
-<p>You can certainly merge this paper’s operating system into the
-Arduino architecture:</p>
-<div class="sourceCode" id="cb18"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="dt">char</span> events<span class="op">[];</span></span>
-<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>interrupt_service_routines<span class="op">()</span> <span class="op">{</span></span>
-<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>evt<span class="op">);</span> <span class="co">// insert events/messages into events[]</span></span>
-<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>   </span>
-<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> nextEvent<span class="op">;</span></span>
-<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span><span class="dt">char</span> evt<span class="op">)</span> </span>
-<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">{}</span> <span class="co">// same as above; put evt into the events[]</span></span>
-<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>setup<span class="op">()</span></span>
-<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">{}</span></span>
-<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>loop<span class="op">()</span> <span class="op">{</span></span>
-<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>  <span class="dt">static</span> <span class="dt">int</span> nextTaskEvent<span class="op">;</span></span>
-<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>events<span class="op">[</span>nextTaskEvent<span class="op">]!=</span>EVT_NONE<span class="op">)</span> <span class="op">{</span>        <span class="co">// check for non-zero events[],</span></span>
-<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>    task1<span class="op">(</span>events<span class="op">[</span>nextTaskEvent<span class="op">]);</span>     <span class="co">// and call the task routines</span></span>
-<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>    task2<span class="op">(</span>events<span class="op">[</span>nextTaskEvent<span class="op">]);</span></span>
-<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a>    events<span class="op">[</span>nextTaskEvent<span class="op">)</span> <span class="op">=</span> EVT_NONE<span class="op">;</span> <span class="co">// free the slot, fill with 0</span></span>
-<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(++</span>nextTaskEvent <span class="op">&gt;</span> NUM_EVENTS<span class="op">)</span></span>
-<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a>      nextTaskEvent <span class="op">=</span> <span class="dv">0</span><span class="op">;</span>              <span class="co">// and loop through the array</span></span>
-<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>  </span>
-<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> task1<span class="op">(</span><span class="dt">char</span> evt<span class="op">)</span> <span class="op">{}</span></span>
-<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> task2<span class="op">(</span><span class="dt">char</span> evt<span class="op">)</span> <span class="op">{}</span></span>
-<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a>    </span></code></pre></div>
-<h2 id="tasks-1">Tasks</h2>
-<p>The fundamental guideline for tasks is that <em>they do not
-stop</em>. Control flows through and out the bottom, returning to the
-dispatcher quickly.</p>
-<details>
-<summary>
-Reality Check
-</summary>
-<p>In practical terms, if you have a timer tick that runs at every 10ms,
-and about 5 tasks, then if you can keep each task under 2ms, you won’t
-lose any events.</p>
-<p>If a task occasionally runs into the 10’s of msec, the event queue
-will handle buffering the events until they can be processed.</p>
-Under no circumstances should a task take more than 100msec. Use a new
-state, and return from the tast. Process the new state later.
-<hr>
-</details>
-<h2 id="state-machine-examples">State Machine Examples</h2>
-<h3 id="car-window">Car Window</h3>
-<p>Suppose we want to control the power window on a car? For this
-problem, we have an up/down button, a motor to drive the window up or
-down, and a motor-overload sensor to detect when the motor is straining.
-So the buttons &amp; overload sensor are inputs, and the motor drive is
-outputs.</p>
-<p>When the user presses the “up” button, we should start the motor
-moving upward. When the overload sensor detects a strain, then either
-the window is all the way up….or it has encountered a finger or hand; in
-either case, we need to turn the motor drive off.</p>
-<p>Here’s a possible state diagram. <img src="window_state.png"
-alt="window motor control" /></p>
-<p>And here’s the matching code. Note the correspondence between the
-diagram and the code: arrows leaving a state correspond to an
-<code>if()</code> phrase.</p>
-<div class="sourceCode" id="cb19"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>WINDOW_IDLE<span class="op">,</span> WINDOW_UP<span class="op">,</span> WINDOW_DOWN<span class="op">};</span></span>
-<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8 windowState <span class="op">=</span> WINDOW_IDLE<span class="op">;</span></span>
-<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> windowTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>windowState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> WINDOW_IDLE<span class="op">:</span></span>
-<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_BUTTON_UP<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>MOTOR<span class="op">,</span> UP<span class="op">);</span></span>
-<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>        windowState <span class="op">=</span> WINDOW_UP<span class="op">;</span></span>
-<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_BUTTON_DOWN<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>MOTOR<span class="op">,</span> DOWN<span class="op">);</span></span>
-<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a>        windowState <span class="op">=</span> WINDOW_DOWN<span class="op">;</span></span>
-<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb19-16"><a href="#cb19-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> WINDOW_UP<span class="op">:</span></span>
-<span id="cb19-17"><a href="#cb19-17" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_MOTOR_SENSE <span class="op">||</span> </span>
-<span id="cb19-18"><a href="#cb19-18" aria-hidden="true" tabindex="-1"></a>          evt <span class="op">==</span> EVT_BUTTON_RELEASE<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb19-19"><a href="#cb19-19" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>MOTOR<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb19-20"><a href="#cb19-20" aria-hidden="true" tabindex="-1"></a>        windowState <span class="op">=</span> WINDOW_IDLE<span class="op">;</span></span>
-<span id="cb19-21"><a href="#cb19-21" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb19-22"><a href="#cb19-22" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb19-23"><a href="#cb19-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> WINDOW_DOWN<span class="op">:</span></span>
-<span id="cb19-24"><a href="#cb19-24" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_MOTOR_SENSE <span class="op">||</span> </span>
-<span id="cb19-25"><a href="#cb19-25" aria-hidden="true" tabindex="-1"></a>          evt <span class="op">==</span> EVT_BUTTON_RELEASE<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb19-26"><a href="#cb19-26" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>MOTOR<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb19-27"><a href="#cb19-27" aria-hidden="true" tabindex="-1"></a>        windowState <span class="op">=</span> WINDOW_IDLE<span class="op">;</span></span>
-<span id="cb19-28"><a href="#cb19-28" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb19-29"><a href="#cb19-29" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb19-30"><a href="#cb19-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>Now, suppose the problem definition is changed: if the user presses
-the “up” button, the motor should only operate while the button is
-pressed; stop on release. But if the user presses the “up” button a
-second time within 1 second of the first release, the motor should drive
-the window all the way up (auto-close).</p>
-<p>Here is a possible state diagram. Notice the significant re-use of
-code from the previous version.</p>
-<figure>
-<img src="window_complex.png"
-alt="window control with auto open/close, (_ma) motor activated (_ms) motor stopped" />
-<figcaption aria-hidden="true">window control with auto open/close,
-(_ma) motor activated (_ms) motor stopped</figcaption>
-</figure>
-<details>
-<summary>
-Reality Check
-</summary>
-<p>This is such a simple task, with only a few I/O pins involved. In
-theory, a cheap microcontroller could control a dozen windows, each
-appearing to operate independantly.</p>
-<p>In the code, one wouldn’t need to create a dozen tasks……just create
-an index into the same code and invoke it in a way that makes it appear
-as an independent task:</p>
-<pre><code>void main(void) {
-  eint();
-  while(1) {
-    for (i=0; i&lt;NUM_EVENTS; i++) {
-      while (events[i]==EVT_NONE)
-        {}
-      taskWindow(events[i],0);
-      taskWindow(events[i],1);
-      // ...
-      taskWindow(events[i],NUM_WINDOWS-1);
-      events[i] = EVT_NONE;
-    }
-  }
-}
-
-// window management task
-int windowState[NUM_WINDOWS];
-void taskWindow(char event, int windowIndex) {
-  // find the state from the windowState[windowIndex] 
-  // run through the state machine
-  // any I/O will require an array of I/O addresses, use &#39;windowIndex&#39;
-
-  switch(windowState[windowIndex]) {
-    case WS_IDLE:
-      ...
-      ...
-  }
-}</code></pre>
-</details>
-<h3 id="fridge-door">Fridge Door</h3>
-<p>A simple state machine can control the interior light of a fridge.
-Here’s the use-case:</p>
-<p>The problem has one input (door open) and two outputs (light and
-audible alarm). If the door is open, turn on the light and start a timer
-for 90 seconds. If the door is still open at the end of the 90 seconds,
-start an audible alarm. If the door closes, stop the timer and turn off
-the light and alarm. And if the door closes during the 90 seconds, turn
-off the light.</p>
-<p>Here is the state diagram.</p>
-<p><img src="fridge_state.png" /></p>
-<p>And here is the corresponding code.</p>
-<div class="sourceCode" id="cb21"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>FRIDGE_CLOSED<span class="op">,</span> FRIDGE_OPEN<span class="op">,</span> FRIDGE_BEEPING<span class="op">};</span></span>
-<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>uint8  fridgeState<span class="op">;</span></span>
-<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>uint16 fridgeTimer<span class="op">;</span></span>
-<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 FRIDGE_OPEN_LIMIT <span class="op">=</span> <span class="dv">9000</span><span class="op">;</span> <span class="co">// 90 seconds at 10msec tick</span></span>
-<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> fridgeTask<span class="op">(</span><span class="dt">char</span> event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>fridgeState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_CLOSED<span class="op">:</span></span>
-<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_OPEN<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>        set_io<span class="op">(</span>LIGHT<span class="op">,</span> ON<span class="op">);</span></span>
-<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>        fridgeTimer <span class="op">=</span> FRIDGE_OPEN_LIMIT<span class="op">;</span></span>
-<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>        fridgeState <span class="op">=</span> FRIDGE_OPEN<span class="op">;</span></span>
-<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_OPEN<span class="op">:</span></span>
-<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_CLOSE<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a>        set_io<span class="op">(</span>LIGHT<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb21-17"><a href="#cb21-17" aria-hidden="true" tabindex="-1"></a>        fridgeState <span class="op">=</span> FRIDGE_CLOSED<span class="op">;</span></span>
-<span id="cb21-18"><a href="#cb21-18" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb21-19"><a href="#cb21-19" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-20"><a href="#cb21-20" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>fridgeTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-21"><a href="#cb21-21" aria-hidden="true" tabindex="-1"></a>          set_io<span class="op">(</span>ALARM<span class="op">,</span> ON<span class="op">);</span></span>
-<span id="cb21-22"><a href="#cb21-22" aria-hidden="true" tabindex="-1"></a>          fridgeState <span class="op">=</span> FRIDGE_BEEPING<span class="op">;</span></span>
-<span id="cb21-23"><a href="#cb21-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb21-24"><a href="#cb21-24" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb21-25"><a href="#cb21-25" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb21-26"><a href="#cb21-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_BEEPING<span class="op">:</span></span>
-<span id="cb21-27"><a href="#cb21-27" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_CLOSE<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb21-28"><a href="#cb21-28" aria-hidden="true" tabindex="-1"></a>        set_io<span class="op">(</span>ALARM<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb21-29"><a href="#cb21-29" aria-hidden="true" tabindex="-1"></a>        set_io<span class="op">(</span>LIGHT<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb21-30"><a href="#cb21-30" aria-hidden="true" tabindex="-1"></a>        fridgeState <span class="op">=</span> FRIDGE_CLOSED<span class="op">;</span></span>
-<span id="cb21-31"><a href="#cb21-31" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb21-32"><a href="#cb21-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb21-33"><a href="#cb21-33" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb21-34"><a href="#cb21-34" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<h4 id="refactor-for-changestate">Refactor for
-<code>changeState()</code></h4>
-<p>Notice on the state diagram, the arrows heads and tails cluster, and
-similar actions happen for multiple arrows. Perhaps we should write a
-function that just deals with all the actions required when leaving or
-entering a state. Then the task code would only have to manage the
-<em>arrows</em> of the state diagram. Like this:</p>
-<div class="sourceCode" id="cb22"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="co">// this outer code deals with the arrows on the state diagram</span></span>
-<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> fridgeTask<span class="op">(</span><span class="dt">char</span> event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span> <span class="op">(</span>fridgeState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_CLOSED<span class="op">:</span></span>
-<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_OPEN<span class="op">)</span> changeFridgeState<span class="op">(</span>FRIDGE_OPEN<span class="op">);</span></span>
-<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_OPEN<span class="op">:</span></span>
-<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_CLOSE<span class="op">)</span> changeFridgeState<span class="op">(</span>FRIDGE_CLOSED<span class="op">);</span></span>
-<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_FRIDGE_TIMEOUT<span class="op">)</span> changeFridgeState<span class="op">(</span>FRIDGE_BEEPING<span class="op">);</span></span>
-<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_BEEPING<span class="op">:</span></span>
-<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_CLOSE<span class="op">)</span> changeFridgeState<span class="op">(</span>FRIDGE_CLOSED<span class="op">);</span></span>
-<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>while the inner code deals with the actions required for
-<em>entry</em> and <em>exit</em> from each state</p>
-<div class="sourceCode" id="cb23"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> changeFridgeState<span class="op">(</span><span class="dt">char</span> newState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">static</span> <span class="dt">char</span> oldState <span class="op">=</span> FRIDGE_CLOSED<span class="op">;</span></span>
-<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">// do all the state-leaving actions</span></span>
-<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>oldState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_CLOSED<span class="op">:</span></span>
-<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>      set_io<span class="op">(</span>LIGHT<span class="op">,</span> ON<span class="op">);</span></span>
-<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>      setTimer<span class="op">(</span>FRIDGE_TIMER<span class="op">,</span> FRIDGE_OPEN_LIMIT<span class="op">);</span></span>
-<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_OPEN<span class="op">:</span></span>
-<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_BEEPING<span class="op">:</span></span>
-<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a>      set_io<span class="op">(</span>ALARM<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a>  <span class="co">// change state</span></span>
-<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a>  fridgeState <span class="op">=</span> oldState <span class="op">=</span> newState<span class="op">;</span></span>
-<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a>  <span class="co">// and do the state-entry code</span></span>
-<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>newState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_CLOSED<span class="op">:</span></span>
-<span id="cb23-20"><a href="#cb23-20" aria-hidden="true" tabindex="-1"></a>      set_io<span class="op">(</span>LIGHT<span class="op">,</span> OFF<span class="op">);</span></span>
-<span id="cb23-21"><a href="#cb23-21" aria-hidden="true" tabindex="-1"></a>      setTimer<span class="op">(</span>FRIDGE_TIMER<span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
-<span id="cb23-22"><a href="#cb23-22" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb23-23"><a href="#cb23-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_OPEN<span class="op">:</span></span>
-<span id="cb23-24"><a href="#cb23-24" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb23-25"><a href="#cb23-25" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FRIDGE_BEEPING<span class="op">:</span></span>
-<span id="cb23-26"><a href="#cb23-26" aria-hidden="true" tabindex="-1"></a>      set_io<span class="op">(</span>ALARM<span class="op">,</span> ON<span class="op">);</span></span>
-<span id="cb23-27"><a href="#cb23-27" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb23-28"><a href="#cb23-28" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb23-29"><a href="#cb23-29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<h3 id="door-opener">Door Opener</h3>
-<p>Suppose we have a power lock on a door, using a solenoid, and an RFID
-tag detector on the “outside” and a push button on the “inside”. There
-is also a WiFi connection to a server, by which we report door openings.
-When the RFID tag sends us a message, it will contain a serial number.
-If the number matches a known record, then operate the door-opener
-solenoid for 4 seconds. If the “inside” button is pushed, operate the
-door-opener for 4 seconds; if the “inside” button is pressed during the
-4 seconds, restart the 4 second timer.</p>
-<p>After the door is locked, send a report to the master control via the
-WiFi.</p>
-<p>Here’s the state diagram:</p>
-<figure>
-<img src="door.png" alt="RFID operated door lock" />
-<figcaption aria-hidden="true">RFID operated door lock</figcaption>
-</figure>
-<p>I use <code>EVT_</code> type events to indicate that they originate
-in hardware, probably at the interrupt level; and <code>MSG_</code> type
-events to indicate they come from a software source, perhaps a sibling
-task.</p>
-<p>Suppose now that the serial number needs to be verified by a central
-service. So when an RFID tag is detected, send a request to the master
-control and wait for an ACK or NAK response. In the case of an ACK, open
-the door solenoid for 4 seconds. The rest of the problem is as stated
-above.</p>
-<p>Here’s the modified state diagram:</p>
-<figure>
-<img src="door2.png" alt="RFID operated door, with remove key verify" />
-<figcaption aria-hidden="true">RFID operated door, with remove key
-verify</figcaption>
-</figure>
-<h3 id="beer-vat">Beer Vat</h3>
-<p>Suppose we have to move a servo motor to lift the lid from a brewing
-vat, to release excess pressure.</p>
-<p>Inputs: pressure valve, manual operation button Outputs: servo, LED,
-beeper</p>
-<p>If high pressure is detected, flash the LED for 10 seconds, then
-operate the beeper for 5 seconds, then operate servo; hold it open for 5
-seconds and return the servo, LED and beeper to idle.</p>
-<p>If the manual operation button is pressed, go directly to “operate
-servo” as above. <img src="beer_vat.png"
-alt="state machine for beer vat pressure release valve" /></p>
-<p>If the manual button is pressed while the lid is open, close
-immediately.</p>
-<h3 id="vending-machine">Vending Machine</h3>
-<p>When idle, wait for payment tap. If selection button is pressed
-before payment, display cost to inform the user for 3 seconds.</p>
-<p>After payment tap, request the user select item.</p>
-<p>Operate dispense motor.</p>
-<p>Wait for object to be removed from output bin.</p>
-<figure>
-<img src="vending.png" alt="states for vending machine" />
-<figcaption aria-hidden="true">states for vending machine</figcaption>
-</figure>
-<h2 id="events-1">Events</h2>
-<p>In all the above, events were implemented as a simple
-<code>unsigned char</code>, allowing 255 different event types.</p>
-<p>There’s no reason we couldn’t use an <code>unsigned short</code> or
-even an <code>int</code>. Further, a 16 bit event number could be
-designed to be 8 bits of event type, and 8 bits of supplementary event
-information:</p>
-<div class="sourceCode" id="cb24"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typedef</span> <span class="kw">struct</span> Event <span class="op">{</span></span>
-<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">unsigned</span> <span class="dt">char</span> type<span class="op">;</span></span>
-<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">unsigned</span> <span class="dt">char</span> info<span class="op">;</span></span>
-<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> Event<span class="op">;</span></span>
-<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>Event e <span class="op">=</span> <span class="op">{</span>MSG_KEYPRESS<span class="op">,</span> KEY_A<span class="op">};</span></span></code></pre></div>
-<p>In the old Windows system, <em>events/messages</em> were realized as
-a 16 bit number, with an extra 32 bit number glued to it for extra
-information.</p>
-<div class="sourceCode" id="cb25"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typedef</span> <span class="kw">struct</span> MSG <span class="op">{</span></span>
-<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  UINT   message<span class="op">;</span></span>
-<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>  LPARAM lParam<span class="op">;</span></span>
-<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span>    <span class="co">// some extra detail removed</span></span></code></pre></div>
-For example, <code>WM_CHAR=0x0102</code> indicates that a key was
-pressed, with the extra 32bit <code>lParam</code> carrying the
-information about <em>which</em> key.
-<hr>
-<h2 id="timers">Timers</h2>
-<p>The simplest state timer is made with a static variable associated
-with the state code.</p>
-<p>To start the timer, simply initialize the static variable. On timer
-ticks, decrement (or increment if you prefer) this variable until it
-hits a limit, and then make a state change.</p>
-<p>For instance, to create a timer that waits 100 timer ticks, you could
-use:</p>
-<div class="sourceCode" id="cb26"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> state<span class="op">;</span></span>
-<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> stateTimer<span class="op">;</span></span>
-<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> stateCode<span class="op">(</span><span class="dt">char</span> event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>state<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE_IDLE<span class="op">:</span></span>
-<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">=</span> EVENT_TRIGGER<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a>        stateTimer <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
-<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>        state <span class="op">=</span> STATE_DELAY<span class="op">;</span></span>
-<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE_DELAY<span class="op">:</span></span>
-<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">=</span> EVENT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>stateTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a>          <span class="co">// the timer is finished</span></span>
-<span id="cb26-15"><a href="#cb26-15" aria-hidden="true" tabindex="-1"></a>          state <span class="op">=</span> STATE_NEXT<span class="op">;</span></span>
-<span id="cb26-16"><a href="#cb26-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb26-17"><a href="#cb26-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb26-18"><a href="#cb26-18" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb26-19"><a href="#cb26-19" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ....</span></span>
-<span id="cb26-20"><a href="#cb26-20" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb26-21"><a href="#cb26-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb26-22"><a href="#cb26-22" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-23"><a href="#cb26-23" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-24"><a href="#cb26-24" aria-hidden="true" tabindex="-1"></a>In the above example<span class="op">,</span> you could equally well have set the timer to start at zero</span>
-<span id="cb26-25"><a href="#cb26-25" aria-hidden="true" tabindex="-1"></a>and increment until it hits the desired limit <span class="op">(</span><span class="dv">100</span> in this <span class="cf">case</span><span class="op">).</span></span>
-<span id="cb26-26"><a href="#cb26-26" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-27"><a href="#cb26-27" aria-hidden="true" tabindex="-1"></a>In a moderate sized project<span class="op">,</span> timers like this will proliferate throughout the code<span class="op">,</span></span>
-<span id="cb26-28"><a href="#cb26-28" aria-hidden="true" tabindex="-1"></a>making it awkward to read<span class="op">.</span> One solution to this is to centralize the timers<span class="op">.</span></span>
-<span id="cb26-29"><a href="#cb26-29" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-30"><a href="#cb26-30" aria-hidden="true" tabindex="-1"></a>In all the above examples<span class="op">,</span> the `timer_irq<span class="op">()</span>` code is trivial<span class="op">,</span> just `newEvent<span class="op">(</span>EVT_TICK<span class="op">)</span>`<span class="op">.</span></span>
-<span id="cb26-31"><a href="#cb26-31" aria-hidden="true" tabindex="-1"></a>Suppose we add code to the `timer_irq<span class="op">()</span>` so that it can process timer counting on</span>
-<span id="cb26-32"><a href="#cb26-32" aria-hidden="true" tabindex="-1"></a>behalf of the tasks<span class="op">......</span></span>
-<span id="cb26-33"><a href="#cb26-33" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-34"><a href="#cb26-34" aria-hidden="true" tabindex="-1"></a><span class="pp">#</span><span class="er">## Timers as a Resource</span></span>
-<span id="cb26-35"><a href="#cb26-35" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-36"><a href="#cb26-36" aria-hidden="true" tabindex="-1"></a>Let<span class="ch">&#39;s</span><span class="er"> create a centralized service called `setTimer(timer_index, timer_count)`. </span></span>
-<span id="cb26-37"><a href="#cb26-37" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-38"><a href="#cb26-38" aria-hidden="true" tabindex="-1"></a>A task can call this service with a unique `timer_index` and a requested count<span class="op">.</span> The</span>
-<span id="cb26-39"><a href="#cb26-39" aria-hidden="true" tabindex="-1"></a>`timer_irq<span class="op">()</span>` will then count out the ticks on behalf of the task<span class="op">,</span> and when the tick</span>
-<span id="cb26-40"><a href="#cb26-40" aria-hidden="true" tabindex="-1"></a>count is finished<span class="op">,</span> the `timer_irq<span class="op">()</span>` code can generate a unique event<span class="op">,</span> perhaps</span>
-<span id="cb26-41"><a href="#cb26-41" aria-hidden="true" tabindex="-1"></a>`EVT_TIMER_n`<span class="op">.</span> </span>
-<span id="cb26-42"><a href="#cb26-42" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-43"><a href="#cb26-43" aria-hidden="true" tabindex="-1"></a>So the state code can then look something like this<span class="op">:</span></span>
-<span id="cb26-44"><a href="#cb26-44" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb26-45"><a href="#cb26-45" aria-hidden="true" tabindex="-1"></a>```C</span>
-<span id="cb26-46"><a href="#cb26-46" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> state<span class="op">;</span></span>
-<span id="cb26-47"><a href="#cb26-47" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> stateCode<span class="op">(</span><span class="dt">char</span> event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-48"><a href="#cb26-48" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>state<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-49"><a href="#cb26-49" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE_IDLE<span class="op">:</span></span>
-<span id="cb26-50"><a href="#cb26-50" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">=</span> EVENT_TRIGGER<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-51"><a href="#cb26-51" aria-hidden="true" tabindex="-1"></a>        setTimer<span class="op">(</span>TIMER_1<span class="op">,</span><span class="dv">100</span><span class="op">);</span></span>
-<span id="cb26-52"><a href="#cb26-52" aria-hidden="true" tabindex="-1"></a>        state <span class="op">=</span> STATE_DELAY<span class="op">;</span></span>
-<span id="cb26-53"><a href="#cb26-53" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb26-54"><a href="#cb26-54" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb26-55"><a href="#cb26-55" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE_DELAY<span class="op">:</span></span>
-<span id="cb26-56"><a href="#cb26-56" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">=</span> EVENT_TIMER_1<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb26-57"><a href="#cb26-57" aria-hidden="true" tabindex="-1"></a>          <span class="co">// the timer is finished</span></span>
-<span id="cb26-58"><a href="#cb26-58" aria-hidden="true" tabindex="-1"></a>          state <span class="op">=</span> STATE_NEXT<span class="op">;</span></span>
-<span id="cb26-59"><a href="#cb26-59" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb26-60"><a href="#cb26-60" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb26-61"><a href="#cb26-61" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb26-62"><a href="#cb26-62" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ....</span></span>
-<span id="cb26-63"><a href="#cb26-63" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb26-64"><a href="#cb26-64" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>This makes the state code much simpler to read, hiding all the
-increments/decrements and limit testing.</p>
-<p>The overhead for this ends up in the <code>timer_irq()</code> code,
-and might look something like this:</p>
-<div class="sourceCode" id="cb27"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">int</span> timers<span class="op">[</span>NUM_TIMERS<span class="op">];</span></span>
-<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#define EVT_TIMER_OFFSET </span><span class="dv">100</span></span>
-<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>EVENT_TIMER_1<span class="op">=</span>EVT_TIMER_OFFSET<span class="op">,</span> EVENT_TIMER_2<span class="op">,</span> EVENT_TIMER_3<span class="op">};</span> <span class="co">// 100, 101...</span></span>
-<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>TIMER_1<span class="op">,</span> TIMER_2<span class="op">,</span> TIMER_3<span class="op">};</span>   <span class="co">// 0,1,2,....</span></span>
-<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> timer_irq<span class="op">()</span> <span class="op">{</span></span>
-<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_TICK<span class="op">);</span>           <span class="co">// the main tick, fires every time</span></span>
-<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span>i<span class="op">=</span><span class="dv">0</span><span class="op">;</span> i<span class="op">&lt;</span>NUM_TIMERS<span class="op">)</span> <span class="op">{</span>     <span class="co">// the system timers, fires on completion</span></span>
-<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>timers<span class="op">[</span>i<span class="op">]&gt;</span><span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(--</span>timers<span class="op">[</span>i<span class="op">]==</span><span class="dv">0</span><span class="op">)</span></span>
-<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>        newEvent<span class="op">(</span>i <span class="op">+</span> EVT_TIMER_OFFSET<span class="op">);</span></span>
-<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb27-14"><a href="#cb27-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb27-15"><a href="#cb27-15" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb27-16"><a href="#cb27-16" aria-hidden="true" tabindex="-1"></a><span class="co">/* common service, available to all tasks */</span></span>
-<span id="cb27-17"><a href="#cb27-17" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> setTimer<span class="op">(</span><span class="dt">int</span> timerIndex<span class="op">,</span> <span class="dt">unsigned</span> <span class="dt">int</span> timerCount<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb27-18"><a href="#cb27-18" aria-hidden="true" tabindex="-1"></a>  timers<span class="op">[</span>timerIndex<span class="op">]</span> <span class="op">=</span> timerCount<span class="op">;</span></span>
-<span id="cb27-19"><a href="#cb27-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<details>
-<summary>
-Reality Check
-</summary>
-<p>On a typical microcontroller running at 24MHz, with 5 timers, this
-adds about 2 microseconds of extra time to the <code>timer_irq()</code>
-code, which typically runs every 10 or 100msec. It considerably
-simplifies the task code, makes it more legible and probably reduces
-bugs that may appear by duplication of code.</p>
-<p>Another possible design for timers is to have the main
-<code>timer_isr()</code> increment a global atomic
-<code>voloatile int timer</code> variable, and the tasks can observe
-this timer and set a target based on that.</p>
-<div class="sourceCode" id="cb28"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="dt">volatile</span> <span class="dt">int</span> timer<span class="op">;</span>         <span class="co">// on most microcontrollers, access to an int</span></span>
-<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>                            <span class="co">// will be atomic</span></span>
-<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>INTERRUPT timer_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>  timer<span class="op">++;</span></span>
-<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_TICK<span class="op">);</span></span>
-<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a><span class="co">// .... state code ...</span></span>
-<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> targetTime<span class="op">;</span></span>
-<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> stateCode<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>state<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE1<span class="op">:</span></span>
-<span id="cb28-13"><a href="#cb28-13" aria-hidden="true" tabindex="-1"></a>      <span class="co">//..... set a target</span></span>
-<span id="cb28-14"><a href="#cb28-14" aria-hidden="true" tabindex="-1"></a>      targetTimer <span class="op">=</span> time <span class="op">+</span> DELAY_TIME<span class="op">;</span></span>
-<span id="cb28-15"><a href="#cb28-15" aria-hidden="true" tabindex="-1"></a>      state <span class="op">=</span> state2<span class="op">;</span></span>
-<span id="cb28-16"><a href="#cb28-16" aria-hidden="true" tabindex="-1"></a>      <span class="co">//.....</span></span>
-<span id="cb28-17"><a href="#cb28-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE2<span class="op">:</span></span>
-<span id="cb28-18"><a href="#cb28-18" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb28-19"><a href="#cb28-19" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>time <span class="op">==</span> targetTimer<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb28-20"><a href="#cb28-20" aria-hidden="true" tabindex="-1"></a>          <span class="co">//.... we&#39;ve waited long enough</span></span>
-<span id="cb28-21"><a href="#cb28-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb28-22"><a href="#cb28-22" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb28-23"><a href="#cb28-23" aria-hidden="true" tabindex="-1"></a>    <span class="co">//...</span></span>
-<span id="cb28-24"><a href="#cb28-24" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb28-25"><a href="#cb28-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-</details>
-<h2 id="real-code">Real Code</h2>
-<p>Here is an example of a complete and tested project on a small
-STM32F030 board. Open all the little arrows to see the complete
-code.</p>
-<details>
-<summary>
-board specific defines
-</summary>
-<div class="sourceCode" id="cb29"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;stm32f030.h&quot;</span></span>
-<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a><span class="co">/****** project hardware ******/</span></span>
-<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a><span class="co">// on this demo board, there is a push button on PB13 and</span></span>
-<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a><span class="co">// an LED on PA4 and PF5</span></span>
-<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a><span class="pp">#define LED  </span><span class="bn">0x10</span><span class="pp"> </span><span class="co">// port A bit 4  these LED are LOW=lit-up</span></span>
-<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a><span class="pp">#define LED2 </span><span class="bn">0x50020</span><span class="pp"> </span><span class="co">// port F bit 5</span></span>
-<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a>GPIO_TypeDef <span class="op">*</span> GROUP<span class="op">[]</span> <span class="op">=</span> <span class="op">{</span>GPIOA<span class="op">,</span> GPIOB<span class="op">,</span> GPIOC<span class="op">,</span> GPIOD<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> GPIOF<span class="op">};</span>  <span class="co">// 0,0x10000,0x20000, etc</span></span>
-<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> gpio_set<span class="op">(</span>uint32 bitPosition<span class="op">,</span> <span class="dt">bool</span> value<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a>  vu32<span class="op">*</span> group <span class="op">=</span> <span class="op">&amp;((</span>GROUP<span class="op">[</span>bitPosition <span class="op">&gt;&gt;</span> <span class="dv">16</span><span class="op">])-&gt;</span>ODR<span class="op">);</span></span>
-<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a>  bitPosition <span class="op">&amp;=</span> <span class="bn">0xFFFF</span><span class="op">;</span></span>
-<span id="cb29-13"><a href="#cb29-13" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>value<span class="op">)</span></span>
-<span id="cb29-14"><a href="#cb29-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>group <span class="op">|=</span> bitPosition<span class="op">;</span></span>
-<span id="cb29-15"><a href="#cb29-15" aria-hidden="true" tabindex="-1"></a>  <span class="cf">else</span></span>
-<span id="cb29-16"><a href="#cb29-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>group <span class="op">&amp;=</span> <span class="op">~</span>bitPosition<span class="op">;</span></span>
-<span id="cb29-17"><a href="#cb29-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-</details>
-<div class="sourceCode" id="cb30"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="co">/***** events ****/</span></span>
-<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#define NUM_EVENTS </span><span class="dv">10</span></span>
-<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a><span class="dt">volatile</span> uint8 events<span class="op">[</span>NUM_EVENTS<span class="op">];</span></span>
-<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span> EVT_NONE<span class="op">,</span></span>
-<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>      EVT_TICK<span class="op">,</span></span>
-<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>      EVT_BUTTON<span class="op">};</span></span>
-<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span>uint8 e<span class="op">);</span></span>
-<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a><span class="co">/********** tasks ***********/</span></span>
-<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> ledTask<span class="op">(</span>uint8 evt<span class="op">);</span></span>
-<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> respondToButtonTask<span class="op">(</span>uint8 evt<span class="op">);</span></span>
-<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a><span class="co">/********** interrupts **************/</span></span>
-<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a><span class="dt">volatile</span> uint32 tick<span class="op">;</span>   <span class="co">// increasing at 100 ticks/sec</span></span>
-<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>                        <span class="co">// takes a year to roll-over</span></span>
-<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> timer_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a>  tick<span class="op">++;</span></span>
-<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_TICK<span class="op">);</span></span>
-<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a>  <span class="co">// this interrupt is auto-ack&#39;d</span></span>
-<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb30-22"><a href="#cb30-22" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb30-23"><a href="#cb30-23" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> button_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb30-24"><a href="#cb30-24" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_BUTTON<span class="op">);</span></span>
-<span id="cb30-25"><a href="#cb30-25" aria-hidden="true" tabindex="-1"></a>  EXTI<span class="op">-&gt;</span>PR <span class="op">|=</span> <span class="bn">0x3001</span><span class="op">;</span>    <span class="co">// ack it </span></span>
-<span id="cb30-26"><a href="#cb30-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb30-27"><a href="#cb30-27" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb30-28"><a href="#cb30-28" aria-hidden="true" tabindex="-1"></a><span class="co">/** newEvent</span></span>
-<span id="cb30-29"><a href="#cb30-29" aria-hidden="true" tabindex="-1"></a><span class="co"> * add the event to the event queue</span></span>
-<span id="cb30-30"><a href="#cb30-30" aria-hidden="true" tabindex="-1"></a><span class="co"> * wrapped in critical section</span></span>
-<span id="cb30-31"><a href="#cb30-31" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span></span>
-<span id="cb30-32"><a href="#cb30-32" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">the</span><span class="co"> event</span></span>
-<span id="cb30-33"><a href="#cb30-33" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
-<span id="cb30-34"><a href="#cb30-34" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> newEvent<span class="op">(</span><span class="dt">char</span> e<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb30-35"><a href="#cb30-35" aria-hidden="true" tabindex="-1"></a>        <span class="dt">static</span> uint nextEvent<span class="op">;</span></span>
-<span id="cb30-36"><a href="#cb30-36" aria-hidden="true" tabindex="-1"></a>        dint<span class="op">();</span> <span class="co">// critical section</span></span>
-<span id="cb30-37"><a href="#cb30-37" aria-hidden="true" tabindex="-1"></a>        events<span class="op">[</span>nextEvent<span class="op">++]</span> <span class="op">=</span> e<span class="op">;</span></span>
-<span id="cb30-38"><a href="#cb30-38" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>nextEvent<span class="op">==</span>NUM_EVENTS<span class="op">)</span></span>
-<span id="cb30-39"><a href="#cb30-39" aria-hidden="true" tabindex="-1"></a>                nextEvent <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb30-40"><a href="#cb30-40" aria-hidden="true" tabindex="-1"></a>        eint<span class="op">();</span></span>
-<span id="cb30-41"><a href="#cb30-41" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-</details>
-<details>
-<summary>
-hardware initialization
-</summary>
-<div class="sourceCode" id="cb31"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="co">/***** init ******/</span></span>
-<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="co">/* called by newlib startup */</span></span>
-<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> _init<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// startup code</span></span>
-<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>  <span class="co">// use default clocks</span></span>
-<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">// turn on all the GPIO&#39;s</span></span>
-<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>  RCC<span class="op">-&gt;</span>AHBENR  <span class="op">=</span> <span class="bn">0x005e0014</span><span class="op">;</span></span>
-<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>  <span class="co">// enable SysCfg</span></span>
-<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>  RCC<span class="op">-&gt;</span>APB2ENR <span class="op">=</span> <span class="bn">0x00004801</span><span class="op">;</span></span>
-<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a>  <span class="co">// enable the two LEDs as outputs</span></span>
-<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a>  GPIOA<span class="op">-&gt;</span>MODER <span class="op">=</span> <span class="op">(</span>GPIOA<span class="op">-&gt;</span>MODER <span class="op">&amp;</span> <span class="bn">0xFFFFFCFF</span><span class="op">)</span> <span class="op">|</span> <span class="bn">0x00000100</span><span class="op">;</span> <span class="co">// port A bit 4</span></span>
-<span id="cb31-15"><a href="#cb31-15" aria-hidden="true" tabindex="-1"></a>  GPIOF<span class="op">-&gt;</span>MODER <span class="op">=</span> <span class="op">(</span>GPIOF<span class="op">-&gt;</span>MODER <span class="op">&amp;</span> <span class="bn">0xFFFFF3FF</span><span class="op">)</span> <span class="op">|</span> <span class="bn">0x00000400</span><span class="op">;</span> <span class="co">// port F bit 5</span></span>
-<span id="cb31-16"><a href="#cb31-16" aria-hidden="true" tabindex="-1"></a>  <span class="co">// and the push button as input + pulldown</span></span>
-<span id="cb31-17"><a href="#cb31-17" aria-hidden="true" tabindex="-1"></a>  GPIOB<span class="op">-&gt;</span>PUPDR <span class="op">=</span> <span class="op">(</span>GPIOB<span class="op">-&gt;</span>PUPDR <span class="op">&amp;</span> <span class="bn">0xF3FFFFFF</span><span class="op">)</span> <span class="op">|</span> <span class="bn">0x08000000</span><span class="op">;</span> <span class="co">// pulldown on 13</span></span>
-<span id="cb31-18"><a href="#cb31-18" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb31-19"><a href="#cb31-19" aria-hidden="true" tabindex="-1"></a>  <span class="co">// keep the clocking system simple: just use the 8MHz HSI everywhere</span></span>
-<span id="cb31-20"><a href="#cb31-20" aria-hidden="true" tabindex="-1"></a>  SysTick<span class="op">-&gt;</span>LOAD <span class="op">=</span> <span class="dv">10000</span><span class="op">;</span>                <span class="co">// 10 msec</span></span>
-<span id="cb31-21"><a href="#cb31-21" aria-hidden="true" tabindex="-1"></a>  SysTick<span class="op">-&gt;</span>VAL  <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb31-22"><a href="#cb31-22" aria-hidden="true" tabindex="-1"></a>  SysTick<span class="op">-&gt;</span>CTRL <span class="op">=</span> <span class="dv">3</span><span class="op">;</span>                    <span class="co">// count at 1usec, use interrupts</span></span>
-<span id="cb31-23"><a href="#cb31-23" aria-hidden="true" tabindex="-1"></a> </span>
-<span id="cb31-24"><a href="#cb31-24" aria-hidden="true" tabindex="-1"></a>  <span class="co">/* to configure an interrupt on the stm32f0xx,</span></span>
-<span id="cb31-25"><a href="#cb31-25" aria-hidden="true" tabindex="-1"></a><span class="co">    - enable the EXTI-&gt;IMR for the pin</span></span>
-<span id="cb31-26"><a href="#cb31-26" aria-hidden="true" tabindex="-1"></a><span class="co">    - set EXTI-&gt;RTSR for select rising edge</span></span>
-<span id="cb31-27"><a href="#cb31-27" aria-hidden="true" tabindex="-1"></a><span class="co">    - set the SYSCFG-&gt;EXTICRx pin to route it </span></span>
-<span id="cb31-28"><a href="#cb31-28" aria-hidden="true" tabindex="-1"></a><span class="co">    - enable the gating bit in the NVIC register </span></span>
-<span id="cb31-29"><a href="#cb31-29" aria-hidden="true" tabindex="-1"></a><span class="co">    - don&#39;t forget to ack each interrupt at EXTI-&gt;PR</span></span>
-<span id="cb31-30"><a href="#cb31-30" aria-hidden="true" tabindex="-1"></a><span class="co">  */</span></span>
-<span id="cb31-31"><a href="#cb31-31" aria-hidden="true" tabindex="-1"></a>  EXTI<span class="op">-&gt;</span>IMR         <span class="op">=</span> <span class="bn">0x2000</span><span class="op">;</span>        <span class="co">// enable interrupt from line 13</span></span>
-<span id="cb31-32"><a href="#cb31-32" aria-hidden="true" tabindex="-1"></a>  EXTI<span class="op">-&gt;</span>RTSR        <span class="op">=</span> <span class="bn">0x2000</span><span class="op">;</span>        <span class="co">// interrupt on rising edge</span></span>
-<span id="cb31-33"><a href="#cb31-33" aria-hidden="true" tabindex="-1"></a>  SYSCFG<span class="op">-&gt;</span>EXTICR<span class="op">[</span><span class="dv">3</span><span class="op">]</span> <span class="op">=</span> <span class="bn">0x0010</span><span class="op">;</span>   <span class="co">// select prot B for exti-13</span></span>
-<span id="cb31-34"><a href="#cb31-34" aria-hidden="true" tabindex="-1"></a>  NVIC<span class="op">-&gt;</span>ISER<span class="op">[</span><span class="dv">0</span><span class="op">]</span>     <span class="op">=</span> <span class="bn">0x00E1</span><span class="op">;</span>        <span class="co">// enable in NVIC: gpio &amp; watchdog</span></span>
-<span id="cb31-35"><a href="#cb31-35" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-</details>
-<div class="sourceCode" id="cb32"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>  eint<span class="op">();</span></span>
-<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>  <span class="co">// dispatcher loop</span></span>
-<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span><span class="op">(</span><span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> j<span class="op">;</span></span>
-<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>j<span class="op">=</span><span class="dv">0</span><span class="op">;</span> j<span class="op">&lt;</span>NUM_EVENTS<span class="op">;</span> j<span class="op">++)</span> <span class="op">{</span></span>
-<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>       <span class="cf">while</span> <span class="op">(</span>events<span class="op">[</span>j<span class="op">]==</span>EVT_NONE<span class="op">)</span></span>
-<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>         <span class="op">{}</span></span>
-<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>       ledTask<span class="op">(</span>events<span class="op">[</span>j<span class="op">]);</span></span>
-<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>       respondToButtonTask<span class="op">(</span>events<span class="op">[</span>j<span class="op">]);</span></span>
-<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a>       events<span class="op">[</span>j<span class="op">]</span> <span class="op">=</span> EVT_NONE<span class="op">;</span></span>
-<span id="cb32-14"><a href="#cb32-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb32-15"><a href="#cb32-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb32-16"><a href="#cb32-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb32-17"><a href="#cb32-17" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb32-18"><a href="#cb32-18" aria-hidden="true" tabindex="-1"></a><span class="co">/*********** task code, with states ************/</span></span>
-<span id="cb32-19"><a href="#cb32-19" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>LED_ON<span class="op">,</span> LED_OFF<span class="op">};</span></span>
-<span id="cb32-20"><a href="#cb32-20" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>RTB_IDLE<span class="op">,</span> RTB_ON<span class="op">};</span>    <span class="co">// states</span></span>
-<span id="cb32-21"><a href="#cb32-21" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8 rtbState           <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb32-22"><a href="#cb32-22" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint16 rtbTimerCount     <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb32-23"><a href="#cb32-23" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 BUTTON_LED_ON_TIME <span class="op">=</span> <span class="dv">150</span><span class="op">;</span></span>
-<span id="cb32-24"><a href="#cb32-24" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb32-25"><a href="#cb32-25" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> respondToButtonTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-26"><a href="#cb32-26" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>rtbState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-27"><a href="#cb32-27" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb32-28"><a href="#cb32-28" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-29"><a href="#cb32-29" aria-hidden="true" tabindex="-1"></a>        rtbState      <span class="op">=</span> RTB_ON<span class="op">;</span></span>
-<span id="cb32-30"><a href="#cb32-30" aria-hidden="true" tabindex="-1"></a>        rtbTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb32-31"><a href="#cb32-31" aria-hidden="true" tabindex="-1"></a>        gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb32-32"><a href="#cb32-32" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb32-33"><a href="#cb32-33" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb32-34"><a href="#cb32-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_ON<span class="op">:</span></span>
-<span id="cb32-35"><a href="#cb32-35" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-36"><a href="#cb32-36" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(++</span>rtbTimerCount <span class="op">&gt;</span> BUTTON_LED_ON_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-37"><a href="#cb32-37" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb32-38"><a href="#cb32-38" aria-hidden="true" tabindex="-1"></a>          rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb32-39"><a href="#cb32-39" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb32-40"><a href="#cb32-40" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb32-41"><a href="#cb32-41" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb32-42"><a href="#cb32-42" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb32-43"><a href="#cb32-43" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb32-44"><a href="#cb32-44" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb32-45"><a href="#cb32-45" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 LED_ON_TIME  <span class="op">=</span> <span class="dv">150</span><span class="op">;</span></span>
-<span id="cb32-46"><a href="#cb32-46" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 LED_OFF_TIME <span class="op">=</span> <span class="dv">50</span><span class="op">;</span></span>
-<span id="cb32-47"><a href="#cb32-47" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint8 ledState       <span class="op">=</span> LED_OFF<span class="op">;</span></span>
-<span id="cb32-48"><a href="#cb32-48" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> uint16 ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb32-49"><a href="#cb32-49" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb32-50"><a href="#cb32-50" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> ledTask<span class="op">(</span>uint8 evt<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-51"><a href="#cb32-51" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>ledState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-52"><a href="#cb32-52" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> LED_OFF<span class="op">:</span></span>
-<span id="cb32-53"><a href="#cb32-53" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-54"><a href="#cb32-54" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(++</span>ledTimerCount <span class="op">&gt;</span> LED_OFF_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-55"><a href="#cb32-55" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED2<span class="op">,</span> LED_ON<span class="op">);</span></span>
-<span id="cb32-56"><a href="#cb32-56" aria-hidden="true" tabindex="-1"></a>          ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb32-57"><a href="#cb32-57" aria-hidden="true" tabindex="-1"></a>          ledState      <span class="op">=</span> LED_ON<span class="op">;</span></span>
-<span id="cb32-58"><a href="#cb32-58" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb32-59"><a href="#cb32-59" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb32-60"><a href="#cb32-60" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb32-61"><a href="#cb32-61" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> LED_ON<span class="op">:</span></span>
-<span id="cb32-62"><a href="#cb32-62" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>evt <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-63"><a href="#cb32-63" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(++</span>ledTimerCount <span class="op">&gt;</span> LED_ON_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb32-64"><a href="#cb32-64" aria-hidden="true" tabindex="-1"></a>          gpio_set<span class="op">(</span>LED2<span class="op">,</span> LED_OFF<span class="op">);</span></span>
-<span id="cb32-65"><a href="#cb32-65" aria-hidden="true" tabindex="-1"></a>          ledTimerCount <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb32-66"><a href="#cb32-66" aria-hidden="true" tabindex="-1"></a>          ledState      <span class="op">=</span> LED_OFF<span class="op">;</span></span>
-<span id="cb32-67"><a href="#cb32-67" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb32-68"><a href="#cb32-68" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb32-69"><a href="#cb32-69" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb32-70"><a href="#cb32-70" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb32-71"><a href="#cb32-71" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<details>
-<summary>
-vector table
-</summary>
-<div class="sourceCode" id="cb33"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="co">/* vector table */</span></span>
-<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#define STACK_TOP </span><span class="bn">0x20002000</span></span>
-<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> default_isr<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{}</span></span>
-<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="kw">extern</span> <span class="dt">void</span> _start<span class="op">(</span><span class="dt">void</span><span class="op">);</span></span>
-<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="op">(*</span>myvectors<span class="op">[])(</span><span class="dt">void</span><span class="op">)</span> __attribute__ <span class="op">((</span>section<span class="op">(</span><span class="st">&quot;.vectors&quot;</span><span class="op">)))=</span> <span class="op">{</span></span>
-<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="dt">void</span><span class="op">(*)(</span><span class="dt">void</span><span class="op">))</span> STACK_TOP<span class="op">,</span>     <span class="co">// stack pointer</span></span>
-<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a>    _start<span class="op">,</span>        <span class="co">// code entry point</span></span>
-<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a>    default_isr<span class="op">,</span>   <span class="co">// handle non-maskable interrupts</span></span>
-<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a>    default_isr<span class="op">,</span> <span class="co">// handle hard faults</span></span>
-<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 10...1f */</span></span>
-<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 20...2f */</span></span>
-<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>timer_isr<span class="op">,</span>        <span class="co">/* 30...3f */</span></span>
-<span id="cb33-14"><a href="#cb33-14" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span></span>
-<span id="cb33-15"><a href="#cb33-15" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span>button_isr<span class="op">,</span>button_isr<span class="op">,</span>button_isr<span class="op">,</span> <span class="co">/* 50...5f */</span></span>
-<span id="cb33-16"><a href="#cb33-16" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 60...6f */</span></span>
-<span id="cb33-17"><a href="#cb33-17" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 70...7f */</span></span>
-<span id="cb33-18"><a href="#cb33-18" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 80...8f */</span></span>
-<span id="cb33-19"><a href="#cb33-19" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 90...9f */</span></span>
-<span id="cb33-20"><a href="#cb33-20" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* a0...af */</span></span>
-<span id="cb33-21"><a href="#cb33-21" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* b0...bf */</span></span>
-<span id="cb33-22"><a href="#cb33-22" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* c0...cf */</span></span>
-<span id="cb33-23"><a href="#cb33-23" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* d0...df */</span></span>
-<span id="cb33-24"><a href="#cb33-24" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* e0...ef */</span></span>
-<span id="cb33-25"><a href="#cb33-25" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* f0...ff */</span></span>
-<span id="cb33-26"><a href="#cb33-26" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span>                <span class="co">/* 100.10f */</span></span>
-<span id="cb33-27"><a href="#cb33-27" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span>                 <span class="co">/* 110.11f */</span></span>
-<span id="cb33-28"><a href="#cb33-28" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
-</details>
-<h2 id="substates">Substates</h2>
-<p>For things like flashing LED’s, you could create two states, and
-toggle between them, like this:</p>
-<p><img src="rtb_state_4.png" /></p>
-<hr>
-<p>Or, you could simply have an internal (static, not-on-the-stack)
-variable which can keep track of the LED toggle. The state diagram then
-simplifies:</p>
-<div class="sourceCode" id="cb34"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>uint8 rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span>              <span class="co">// major state, RTB_IDLE/RTB_FLASHING</span></span>
-<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>uint8 rtbSubState <span class="op">=</span> RTB_FLASH_OFF<span class="op">;</span>      <span class="co">// minor state, toggles LED on/off</span></span></code></pre></div>
-<p>Alternatively, you could use the <em>timer counter</em> variable, and
-make changes at the half-way point through the count. This simplifies
-the substate design to this:</p>
-<p><img src="rtb_state_5.png" class="imageright" /></p>
-<div class="sourceCode" id="cb35"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 FLASH_CYCLE_TIME <span class="dv">150</span><span class="op">;</span></span>
-<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 FLASH_ON_TIME <span class="dv">40</span><span class="op">;</span></span>
-<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>uint8 rtbState <span class="op">=</span> STATE_IDLE<span class="op">;</span></span>
-<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> rtbTaskCode<span class="op">(</span><span class="dt">char</span> event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">static</span> uint16 flashCount<span class="op">=</span><span class="dv">0</span><span class="op">;</span></span>
-<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>taskState<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> RTB_IDLE<span class="op">:</span></span>
-<span id="cb35-9"><a href="#cb35-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-10"><a href="#cb35-10" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> STATE_FLASHING<span class="op">;</span></span>
-<span id="cb35-11"><a href="#cb35-11" aria-hidden="true" tabindex="-1"></a>        flashCount <span class="op">=</span> FLASH_CYCLE_TIME<span class="op">;</span></span>
-<span id="cb35-12"><a href="#cb35-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb35-13"><a href="#cb35-13" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb35-14"><a href="#cb35-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> STATE_FLASHING<span class="op">:</span></span>
-<span id="cb35-15"><a href="#cb35-15" aria-hidden="true" tabindex="-1"></a>      <span class="co">// count down flashCount, toggle LED halfway through</span></span>
-<span id="cb35-16"><a href="#cb35-16" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-17"><a href="#cb35-17" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>flashCount <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-18"><a href="#cb35-18" aria-hidden="true" tabindex="-1"></a>          setLED<span class="op">(</span>OFF<span class="op">);</span></span>
-<span id="cb35-19"><a href="#cb35-19" aria-hidden="true" tabindex="-1"></a>          flashCount <span class="op">=</span> FLASH_CYCLE_TIME<span class="op">;</span></span>
-<span id="cb35-20"><a href="#cb35-20" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>flashCount <span class="op">==</span> FLASH_ON_TIME<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-21"><a href="#cb35-21" aria-hidden="true" tabindex="-1"></a>          setLED<span class="op">(</span>ON<span class="op">);</span></span>
-<span id="cb35-22"><a href="#cb35-22" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
-<span id="cb35-23"><a href="#cb35-23" aria-hidden="true" tabindex="-1"></a>      <span class="co">// ... make sure to turn LED off when leaving this state</span></span>
-<span id="cb35-24"><a href="#cb35-24" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_BUTTON<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb35-25"><a href="#cb35-25" aria-hidden="true" tabindex="-1"></a>        setLED<span class="op">(</span>OFF<span class="op">);</span></span>
-<span id="cb35-26"><a href="#cb35-26" aria-hidden="true" tabindex="-1"></a>        rtbState <span class="op">=</span> RTB_IDLE<span class="op">;</span></span>
-<span id="cb35-27"><a href="#cb35-27" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span> </span>
-<span id="cb35-28"><a href="#cb35-28" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb35-29"><a href="#cb35-29" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
-<span id="cb35-30"><a href="#cb35-30" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb35-31"><a href="#cb35-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<h2 id="state-machine-initialization">State Machine Initialization</h2>
-<p>Notice that there’s no initialization of states in this code. It
-<em>would</em> be very handy if we knew when to initialize all the
-lights and buzzers and match up the various states. Perhaps the
-<code>main()</code> code could add a single event into the event queue
-at power-up, perhaps <code>EVT_INIT</code>. It might be added like
-this:</p>
-<div class="sourceCode" id="cb36"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>  newEvent<span class="op">(</span>EVT_INIT<span class="op">);</span>  <span class="co">// early, before interrupts, so we know it&#39;s first in line</span></span>
-<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>  eint<span class="op">();</span></span>
-<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span><span class="op">(</span><span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
-<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">...</span> dispatcher code <span class="op">...</span></span>
-<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>Then, in the state code, you can catch that event and set up whatever
-might be required</p>
-<div class="sourceCode" id="cb37"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a>uint8 myState<span class="op">;</span></span>
-<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> stateCode<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>event<span class="op">==</span>EVT_INIT<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ... do setup code</span></span>
-<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>    myState <span class="op">=</span> FIRST_STATE<span class="op">;</span></span>
-<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span><span class="op">;</span></span>
-<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ... regular state machine code</span></span>
-<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<h2 id="messages">Messages</h2>
-<p>Now that we have an event/dispatcher system, we can also also use it
-to send information asychronously between tasks. For example, if a
-keyboard processing task needs to inform its siblings, it can create
-<em>messages</em> which can be injected into the event queue.</p>
-<p>Notice the change of terminology, where <em>message</em> indicates
-that the entry was created by code procesing, rather than an
-interrupt.</p>
-<h3 id="postmessage">PostMessage</h3>
-<p>We need a service routine to add messages to the event queue:
-<code>postMessage()</code>. This call is very smimilar
-<code>newEvent()</code> which should only be called from interrupts.</p>
-<figure>
-<img src="postMessage.png"
-alt="cd-eject task uses postMessage() to broadcast a message" />
-<figcaption aria-hidden="true">cd-eject task uses postMessage() to
-broadcast a message</figcaption>
-</figure>
-<div class="sourceCode" id="cb38"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> postMessage<span class="op">(</span>uint8 message<span class="op">);</span></span></code></pre></div>
-<p>Notice that <code>postMessage</code> can’t return any information,
-because it’s not processed immediately; the <em>message</em> is added to
-the <em>event queue</em> to be processed at a later time.</p>
-<details>
-<summary>
-Reality Check
-</summary>
-In this tiny system, <code>postMessage()</code> is exactly the same as
-<code>newEvent()</code>. The reason that I use different names is that
-some more sophisticated operating systems require that these two
-functions are <em>not</em> identical.
-</details>
-<h3 id="sendmessage">SendMessage</h3>
-<p>In some cases we may want the sibling task to process the information
-immediately. This means:</p>
-<ul>
-<li>we can be assured that the sibling task has fully processed the
-information</li>
-<li>does not involve the dispatcher; but does require extra room on the
-stack</li>
-<li>we <em>could</em> get a return value from the sibling task; since
-it’s implemented as a subroutine, it’s allowed to return a value</li>
-</ul>
-<figure>
-<img src="sendMessage.png"
-alt="cd-eject task uses sendMessage() to call a sibling task" />
-<figcaption aria-hidden="true">cd-eject task uses sendMessage() to call
-a sibling task</figcaption>
-</figure>
-<p>This of course means that the prototype for task functions would
-change from</p>
-<div class="sourceCode" id="cb39"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> taskCode<span class="op">(</span>uint8 event<span class="op">);</span></span>
-<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>to</span>
-<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>uint8 taskCode<span class="op">(</span>uint8 event<span class="op">);</span></span></code></pre></div>
-<p>The service routine to send a message like this would look like:</p>
-<div class="sourceCode" id="cb40"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a>uint8 SendMessage<span class="op">(</span>int8 taskPointer<span class="op">(</span>uint8<span class="op">),</span> uint8 message<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> taskPointer<span class="op">(</span>message<span class="op">);</span></span>
-<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<h3 id="usage">Usage</h3>
-<p>Why might one want to send a <em>message</em> between tasks?</p>
-<p>Suppose you have a rotary encoder, which sends quadrant signals,
-which need to be interpreted as <em>clockwise</em> and <em>counter
-clockwise</em>. You could have one task devoted to determining the
-direction of the knob (and <a href="#debouncing">debouncing</a>), and
-have it send clean EVT_CW and EVT_CCW <em>messages</em> to its sibgling
-tasks.</p>
-<p>Another possible use of <em>messages</em> is to create alternate
-souces of input. For example, a device which has a temperature set by
-“up/down” buttons on a front panel could receive the same controls from
-an infra-red remote, or even a serial port (perhaps for testing).</p>
-<p>And why <code>sendMessage()</code>? Perhaps you need to have a
-sibling task change states, or process information <em>before</em> you
-continue in your task. Imagine there is a slave WiFi chip that needs to
-be powered up <em>before</em> you send it a request….you could use
-<code>sendMessage()</code> to activate the power, and then continue,
-knowing that your peripheral is available.</p>
-<h2 id="ideas-for-tasks">Ideas for Tasks</h2>
-<p>I taught this coding technique at the college level, and a typical
-end-of-term assignment was to code up a simulated automobile
-entertainment system, which included about 6-10 concurrent tasks:</p>
-<ul>
-<li>task blue light to show bluetooth connectivity</li>
-<li>volume up/down sense and display</li>
-<li>radio channel select buttons
-<ul>
-<li>step single freq, or high-speed scan</li>
-</ul></li>
-<li>power on/off management</li>
-<li>remote control of volume/radio-select from the steering wheel (uart
-link)</li>
-<li>backlight for night-time viewing (auto sense from a light
-sensor)</li>
-<li>service-required LED, flashing</li>
-<li>a beeper to confirm keypresses (30ms) and alarm (700ms/100ms)</li>
-<li>a clock up/down set button
-<ul>
-<li>3 buttons: “set min/hr” and “+” and “-”</li>
-</ul></li>
-</ul>
-<p>Each list item above corresponds to one task. My students were able
-to code this up with about 35k of source, which compiles to about 8k of
-code and 256B of RAM (on an STM32)</p>
-<h2 id="more-state-machines">More State Machines</h2>
-<h3 id="radio-tuner">Radio Tuner</h3>
-<p>Suppose we have a <code>+</code> and <code>-</code> button for tuning
-a radio. A press of either will move the radio frequency by one step. If
-the button is held for more than 0.5 seconds, the radio should change to
-a rapid scroll through all available frequencies.</p>
-<p>Suppose we have events coming at 100msec, and that the radio
-frequencies are 88.7 up to 107.9, with steps at 0.1. And finally,
-suppose there are 5 available events:</p>
-<div class="sourceCode" id="cb41"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>EVT_NONE<span class="op">,</span> EVT_TICK<span class="op">,</span> EVT_UP_PRESS<span class="op">,</span> EVT_UP_RELEASE<span class="op">,</span> EVT_DN_PRESS<span class="op">,</span> EVT_DN_RELEASE<span class="op">};</span></span></code></pre></div>
-<figure>
-<img src="radio_tuner.png" alt="state machine for radio tuner" />
-<figcaption aria-hidden="true">state machine for radio
-tuner</figcaption>
-</figure>
-<div class="sourceCode" id="cb42"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> <span class="dt">float</span> MIN_FREQ<span class="op">=</span><span class="fl">88.7</span><span class="op">,</span> MAX_FREQ<span class="op">=</span><span class="fl">107.9</span><span class="op">,</span> INC_FREQ<span class="op">=</span><span class="dv">0</span><span class="er">.1</span><span class="op">;</span></span>
-<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a><span class="dt">float</span> radioFreq <span class="op">=</span> MIN_FREQ<span class="op">;</span></span>
-<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a>uint16 radioTimer <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
-<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a><span class="dt">const</span> uint16 radioTimeout <span class="op">=</span> <span class="dv">5</span><span class="op">;</span>  <span class="co">// 0.5 seconds</span></span>
-<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> <span class="op">{</span>IDLE<span class="op">,</span> FREQ_UP<span class="op">,</span> FREQ_UP_FAST<span class="op">,</span> FREQ_DN<span class="op">,</span> FREQ_DN_FAST<span class="op">};</span></span>
-<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a>uint8 state <span class="op">=</span> IDLE<span class="op">;</span></span>
-<span id="cb42-8"><a href="#cb42-8" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> radioTask<span class="op">(</span>uint8 event<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb42-9"><a href="#cb42-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span><span class="op">(</span>state<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb42-10"><a href="#cb42-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> IDLE<span class="op">:</span></span>
-<span id="cb42-11"><a href="#cb42-11" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_UP_PRESS<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb42-12"><a href="#cb42-12" aria-hidden="true" tabindex="-1"></a>        radioFreq <span class="op">+=</span> INC_FREQ<span class="op">;</span></span>
-<span id="cb42-13"><a href="#cb42-13" aria-hidden="true" tabindex="-1"></a>        checkRadioFreq<span class="op">();</span></span>
-<span id="cb42-14"><a href="#cb42-14" aria-hidden="true" tabindex="-1"></a>        radioTimer <span class="op">=</span> radioTimeout<span class="op">;</span></span>
-<span id="cb42-15"><a href="#cb42-15" aria-hidden="true" tabindex="-1"></a>        state <span class="op">=</span> FREQ_UP<span class="op">;</span></span>
-<span id="cb42-16"><a href="#cb42-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb42-17"><a href="#cb42-17" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_DN_PRESS<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb42-18"><a href="#cb42-18" aria-hidden="true" tabindex="-1"></a>        radioFreq <span class="op">-=</span> INC_FREQ<span class="op">;</span></span>
-<span id="cb42-19"><a href="#cb42-19" aria-hidden="true" tabindex="-1"></a>        checkRadioFreq<span class="op">();</span></span>
-<span id="cb42-20"><a href="#cb42-20" aria-hidden="true" tabindex="-1"></a>        radioTimer <span class="op">=</span> radioTimeout<span class="op">;</span></span>
-<span id="cb42-21"><a href="#cb42-21" aria-hidden="true" tabindex="-1"></a>        state <span class="op">=</span> FREQ_DN<span class="op">;</span></span>
-<span id="cb42-22"><a href="#cb42-22" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb42-23"><a href="#cb42-23" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb42-24"><a href="#cb42-24" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FREQ_UP<span class="op">:</span></span>
-<span id="cb42-25"><a href="#cb42-25" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_UP_RELEASE<span class="op">)</span> </span>
-<span id="cb42-26"><a href="#cb42-26" aria-hidden="true" tabindex="-1"></a>        state <span class="op">=</span> IDLE<span class="op">;</span></span>
-<span id="cb42-27"><a href="#cb42-27" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb42-28"><a href="#cb42-28" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(--</span>radioTimer <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> </span>
-<span id="cb42-29"><a href="#cb42-29" aria-hidden="true" tabindex="-1"></a>          state <span class="op">=</span> FREQ_UP_FAST<span class="op">;</span></span>
-<span id="cb42-30"><a href="#cb42-30" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb42-31"><a href="#cb42-31" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb42-32"><a href="#cb42-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> FREQ_UP_FAST<span class="op">:</span></span>
-<span id="cb42-33"><a href="#cb42-33" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_TICK<span class="op">)</span> <span class="op">{</span></span>
-<span id="cb42-34"><a href="#cb42-34" aria-hidden="true" tabindex="-1"></a>        radioFreq <span class="op">+=</span> INC_FREQ<span class="op">;</span></span>
-<span id="cb42-35"><a href="#cb42-35" aria-hidden="true" tabindex="-1"></a>        checkRadioFreq<span class="op">();</span></span>
-<span id="cb42-36"><a href="#cb42-36" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
-<span id="cb42-37"><a href="#cb42-37" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>event <span class="op">==</span> EVT_UP_RELEASE<span class="op">)</span> </span>
-<span id="cb42-38"><a href="#cb42-38" aria-hidden="true" tabindex="-1"></a>        state <span class="op">=</span> IDLE<span class="op">;</span></span>
-<span id="cb42-39"><a href="#cb42-39" aria-hidden="true" tabindex="-1"></a>      <span class="cf">break</span><span class="op">;</span></span>
-<span id="cb42-40"><a href="#cb42-40" aria-hidden="true" tabindex="-1"></a>    <span class="co">// and the same for FREQ_DN and FREQ_DN_FAST</span></span>
-<span id="cb42-41"><a href="#cb42-41" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
-<span id="cb42-42"><a href="#cb42-42" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
-<span id="cb42-43"><a href="#cb42-43" aria-hidden="true" tabindex="-1"></a></span>
-<span id="cb42-44"><a href="#cb42-44" aria-hidden="true" tabindex="-1"></a><span class="co">// manage rollover</span></span>
-<span id="cb42-45"><a href="#cb42-45" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkRadioFreq<span class="op">()</span> <span class="op">{</span></span>
-<span id="cb42-46"><a href="#cb42-46" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>radioFreq <span class="op">&gt;</span> MAX_FREQ<span class="op">)</span></span>
-<span id="cb42-47"><a href="#cb42-47" aria-hidden="true" tabindex="-1"></a>    radioFreq <span class="op">=</span> MIN_FREQ<span class="op">;</span></span>
-<span id="cb42-48"><a href="#cb42-48" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>radioFreq <span class="op">&lt;</span> MIN_FREQ<span class="op">)</span></span>
-<span id="cb42-49"><a href="#cb42-49" aria-hidden="true" tabindex="-1"></a>    radioFreq <span class="op">=</span> MAX_FREQ<span class="op">;</span></span>
-<span id="cb42-50"><a href="#cb42-50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
-<p>This may seem like a lot of code, but it compiles to something quite
-small. It is non-blocking, and easily maintained and modified. And it
-works.</p>
-</body>
-</html>

+ 18 - 24
CooperativeMultitasking.md

@@ -46,36 +46,30 @@ It helps to have a passing knowledge of how to connect a transducer
 > practical supplementary reading.
 > practical supplementary reading.
 
 
 <details><summary>Reality Check</summary>
 <details><summary>Reality Check</summary>
+The technique described here is also called ***event driven programming***.
 
 
-<p> The technique described here is also called <b><i>event driven programming</i></b>. </p>
+This technique was used in the original Window (1995),
+including some of the system calls: `sendMessage(), postMessage() and setTimer()`.
 
 
-<p> This technique was used in the original Window (1995),
-including some of the system calls: <code> sendMessage(), postMessage() and setTimer()</code>.
-</p>
-
-<p> This event-driven technique is applicable to a whole host 
+This event-driven technique is applicable to a whole host 
 of small microcontrollers, including
 of small microcontrollers, including
-</p>
-
-<ul>
-<li> MSP430 </li>
-<li> Cortex M0, M0+ (SAM, STM32, PY32, Cypress, Kinetis, HT32, XMC, LPC81x) </li>
-<li> AtMega, AtTiny </li>
-<li> 8051 (SiliconLabs, Nuvoton, HT85) </li>
-<li>  RL78 (Renesas) </li>
-<li>  Pic 12/14/16 </li>
-<li>  Risc (ch32v) </li>
-<li>  STM8 </li>
-</ul>
-
-<blockquote> <i> Some of the really tiny ones don't have enough stack space to implement these
+
+- MSP430
+- Cortex M0, M0+ (SAM, STM32, PY32, Cypress, Kinetis, HT32, XMC, LPC81x)
+- AtMega, AtTiny
+- 8051 (SiliconLabs, Nuvoton, HT85)
+- RL78 (Renesas)
+- Pic 12/14/16
+- Risc (ch32v)
+- STM8
+
+*Some of the really tiny ones don't have enough stack space to implement these
 techniques (Puolop PB150, Padauk PxS15x, Bojuxing BJ8P, 
 techniques (Puolop PB150, Padauk PxS15x, Bojuxing BJ8P, 
-Yspring MDT1x, EastSoft HR7P, Holtek Ht68.)</i> </blockquote>
+Yspring MDT1x, EastSoft HR7P, Holtek Ht68.)*
 
 
-<p>
-Here is a <img src=blb.jpg>typical board</a> hosting 12 buttons, 12 RGB LEDs, all hosted
+![Here](blb.jpg) is a typical board hosting 12 buttons, 12 RGB LEDs, all hosted
 by an STM32. Every light and button can be controlled separately 
 by an STM32. Every light and button can be controlled separately 
-and simultaneously, using the technique described in this paper. </p>
+and simultaneously, using the technique described in this paper.
 </details>
 </details>
 
 
 ## The Problem
 ## The Problem

+ 1 - 1
README.md

@@ -1,4 +1,4 @@
-This is a [web-based article](CooperativeMultitasking.html) 
+This is a [web-based article](https://alt.pbeirne.com/cmt/CooperativeMultitasking.html) 
 describing *cooperative multitasking*, also known as
 describing *cooperative multitasking*, also known as
 *event driven programming*. The method described here is small enough to fit on
 *event driven programming*. The method described here is small enough to fit on
 many sub-$1 microcontrollers, those without memory management units. Examples are 
 many sub-$1 microcontrollers, those without memory management units. Examples are 

+ 274 - 0
pandoc.css

@@ -0,0 +1,274 @@
+body {
+	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+	font-size: 12pt;
+	line-height: 1.5;
+    max-width: 70em;
+    margin: auto;
+    padding: 1em;
+}
+
+a {
+	color: #337ab7;
+	text-decoration: none;
+}
+
+a:hover,
+a:focus {
+	color: #23527c;
+	text-decoration: underline;
+}
+
+dt {
+	font-weight: bold;
+}
+
+p {
+	text-align: justify;
+	word-wrap: break-word;
+}
+
+blockquote {
+	border-left: solid thick #d4d4d4;
+	padding-left: 1em;
+}
+
+/* Code */
+pre {
+	font-size: 10pt;
+	background: #f5f5f5;
+	border: solid thin #d4d4d4;
+	padding: 0.5em;
+}
+
+pre[class*="language-"] {
+	background: #f5f5f5;
+	padding: 0;
+}
+
+code,
+code[class*="language-"] {
+	font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+	font-size: 10pt;
+}
+
+/* Key */
+kbd {
+	padding: 0.2em 0.4em;
+	font-size: 75%;
+	color: #fff;
+	background: #333;
+	border-radius: 0.2em;
+}
+
+kbd kbd {
+	padding: 0;
+	font-size: 100%;
+	font-weight: bold;
+}
+
+/* Figure */
+figure {
+	text-align: center;
+}
+
+figcaption {
+	margin-top: 1em;
+}
+
+/* Table */
+table {
+	margin: auto;
+	border: solid thin #d4d4d4;
+	border-collapse: collapse;
+}
+
+table caption {
+	margin: 1em 0em;
+}
+
+table th,
+table td {
+	border: solid thin #d4d4d4;
+	padding: 0.2em 0.5em;
+}
+
+table th {
+	background: #f5f5f5;
+}
+
+/* Footnotes */
+.footnote {
+	margin: 0 0 0 0.5em;
+	font-size: 10pt;
+}
+
+p .footnote:first-of-type {
+	margin-top: 0.5em;
+}
+
+.footnote-num {
+	margin-right: 0.5em;
+}
+
+/* References */
+.references p {
+	text-align: left;
+}
+
+/* Custom Stuff */
+
+.file {
+	font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+	font-size: 10pt;
+}
+
+.file:before {
+	font-family: FontAwesome;
+	content: "\f15b";
+	display: inline-block;
+	padding-right: 0.5em;
+}
+
+/* ------------------------------------------------------------ Screen Style */
+@media screen {
+	body {
+		color: #333;
+	}
+
+	header, nav, section.level1 {
+		background-color: #fdfdfd;
+		border: solid thin #d4d4d4;
+		padding: 1em;
+		margin: 1em 0;
+	}
+
+	h1 {
+		margin-top: 0;
+	}
+
+	hr {
+		border: none;
+		border-top: solid thin #d4d4d4;
+	}
+
+	pre {
+		overflow-x: auto;
+	}
+
+	.container {
+		margin: auto;
+	}
+
+	/* Title */
+	.title, .subtitle, .authors, .date {
+		text-align: center;
+		padding: 0em;
+		margin: 0em;
+	}
+
+	.title {
+		font-size: 24pt;
+	}
+
+	.subtitle {
+		font-size: 17pt;
+	}
+
+	.subtitle:empty {
+		display: none;
+	}
+
+	.authors, .date {
+		font-size: 12pt;
+		margin: 1em 0em;
+	}
+
+	.authors li {
+		list-style-type: none;
+		display: inline;
+		margin: 0em 2em;
+	}
+
+	/* TOC */
+	nav ul {
+		margin: 0 0 0 1em;
+		padding: 0
+	}
+
+	nav li {
+		list-style: none;
+		line-height: 1.7;
+	}
+
+	nav > ul > li {
+		margin: 0 0 1em 0;
+	}
+
+	.toc-section-number,
+	.header-section-number {
+		padding-right: 0.5em;
+	}
+}
+
+/* -------------------------------------------------------- Responsive Stuff */
+@media screen and (min-width: 768px) {
+	.container {
+		width: 750px;
+	}
+
+	nav {
+		columns: 2;
+	}
+}
+
+@media screen and (min-width: 992px) {
+	.container {
+		width: 970px;
+	}
+}
+
+@media screen {
+	img {
+		display: block;
+		margin: auto;
+		max-width: 100%;
+		height: auto;
+	}
+}
+
+/* ------------------------------------------------------------- Print Style */
+@media print {
+	@page {
+		size: A4;
+		margin: 25mm;
+	}
+
+	header, nav {
+		display: none;
+	}
+
+	hr {
+		border: none;
+		border-top: solid thin black;
+	}
+
+	a {
+		color: #000;
+		text-decoration: none;
+	}
+
+	p, pre, table, blockquote, figure {
+		page-break-inside: avoid;
+	}
+
+	pre,
+	pre[class*="language-"],
+	pre[class*="language-"] > code[data-language] {
+		background: none;
+	}
+
+	h1 {
+		page-break-before: always;
+	}
+}
+