<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>"Justins Embedded Blog</title>
    <link>http://www.jwtanner.com</link>
    <description>embedded programming and micro-controllers</description>
    <language>en-us</language>
    <item>
      <title>Burned by Embedded Systems: Volatile</title>
      <author>justinwtanner@gmail.com</author>
      <description>
        <![CDATA[<p>The following is a excerpt from <a href="http://www.jwtanner.com/csc460/Report2/">this report</a> on the construction of a real time operating system.</p>

<h4>Volatile</h4>

<p>During development of the RTOS we ran into a nasty bug.  When we chose an optimization
option in the gcc compiler such as <code>-O2</code>, our OS behaved differently than when
compiled without optimization. Upon closer inspection we found that certain C statements were ignored.</p>

<h4>The Problem</h4>

<p>To illustrate this problem imagine we have a sensor that takes 50ms to read.
Code to read this sensor might look like this:</p>

<pre class="code">
<span class="type">int</span> <span class="ident">finished_reading</span> = 0;

<span class="type">void</span> <span class="ident">main</span>(void)
{
    <span class="ident">init_sensor</span>();

    <span class="construct">for</span>(;;)
    {
        <span class="ident">finished_reading</span> = 0;
        <span class="ident">read_sensor</span>();

        <span class="construct">while</span>(<span class="ident">finished_reading</span> == 0) {};
    }
}


<span class="ident">ISR</span>()
{
    <span class="comment">/* read the sensor value */</span>
    <span class="ident">finished_reading</span> = 1;
}
</pre>

<p>The expected behavior of this code inside the <code>for(;;)</code> loop is as follows,</p>

<ol>
    <li>call <code>read_sensor()</code> and enter <code>while()</code> loop</li>
    <li>ISR fires, gets the sensor value, and sets <code>finished_reading</code> to 1</li>
    <li>the <code>while()</code> loop exits</li>
    <li>go back to step one</li>    
</ol>

<p>But the optimization of this code causes a problem: step 3 never occurs.  The ISR executes as expected, but the value of <code>finished_reading</code> never gets set to 1.</p>

<h4>Upon Closer Inspection</h4>

<p>To see what is going on we must go down to the assembly level.</p>

<p><b>C code</b></p>

<pre class="code">
<span class="construct">while</span>(<span class="ident">finished_reading</span> == 0) {};
</pre>

<p><b>AVR RISC assembler</b></p>

<pre class="code">
+000004A8:   9180010B    <span class="construct">LDS</span>     R24,0x010B    <span class="comment">Load direct from data space</span>
+000004AA:   2388        <span class="construct">TST</span>     R24           <span class="comment">Test for Zero or Minus</span>
+000004AB:   F4A9        <span class="construct">BRNE</span>    PC-0x01       <span class="comment">Branch if not equal</span>
</pre>

<p>The first line of assembly gets finished_reading from memory and places it in register 24.  The next instruction tests if the value in register 24 is zero.  And the last instruction branches back to the previous instruction.</p>

<p>But a problem lies in the last line of assembler.
We want the instruction to branch back to the top of the loop.
 Since GCC thinks the value of finished_reading will never change it jumps back
to the second instruction, not the first.
The last instruction should read <code>BRNE PC-0x0<b>3</b></code>, not <code>BRNE PC-0x01</code>.</p>

<p>From the compilers perspective the value of finished_reading is set once in main() and never changed.  The behavior of the ISR() and how it interacts with the globals used in main() is completely unknown to the compiler.  So it is making the right optimization, saving 2 cpu cycles for each loop iteration.</p>

<h4>The Solution</h4>

<p>The solution to this problem is to change the definition of finished_reading to be volatile.</p>

<pre class="code">
<span class="type">int <b>volatile</b></span> <span class="ident">finished_reading</span>;
</pre>

<p>This will change the third instruction to read BRNE PC-0x03, getting a fresh value of finished_reading from its location in memory.</p>

<h4>How does volatile work?</h4>

<p>A variable declared with a type qualifier <code>volatile</code>, informs the compiler not to optimize references to or modifications of the variable across <em>sequence points</em>, such as the end of statements or expressions in a test.
In practice,  declaring a variable with the <code>volatile</code> qualifier forces the compiler to produce machine instructions that read or write directly to the memory location of the variable every time the variable is accessed.</p>

<p>In the example above, there are several sequence points between the initial setting of the <code>finished_reading</code> variable, and its occurrence in the loop condition. Under optimization, the compiler noticed
that the variable never gets modified between these two points, and so optimized the accesses to it.
But the ISR can execute at any time, which the compiler cannot expect.
By using <code>volatile</code>, we forced the compiler to put the variable access back in.</p>

<p>Choosing an optimization option in the compiler typically makes the execution of the code faster,
at the expense of a larger executable. For example, sections of code may be repeated several times,
rather than using a loop variable. Or functions may be copied and placed inline to save the time of
a function call. Higher levels of optimization perform even deeper analysis on the code, to skip
unnecessary machine instructions. Sometimes, this is not desirable.</p>

<p>In our project, we qualified as <code>volatile</code> every variable used within an ISR. This sometimes makes the
code run more slowly than it could, but at least it runs correctly.</p>

<p>More information about <code>volatile</code> can be found here,</p>

<a href="http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html">The C Book - Const and volatile</a>
<p>And here,</p>
<a href="http://www.embedded.com/story/OEG20010615S0107">Embedded.com - Introduction to the Volatile Keyword</a>
<br /><br />]]>
      </description>
      <pubDate>Mon, 31 Dec 2007 00:00:00 +0000</pubDate>
      <link>http://www.jwtanner.com/archive/burned_by_embedded_systems_volatile</link>
      <guid>http://www.jwtanner.com/archive/burned_by_embedded_systems_volatile</guid>
    </item>
    <item>
      <title>The LED Wheel</title>
      <author>justinwtanner@gmail.com</author>
      <description>
        <![CDATA[<p>Last summer I created a project for the <a href="http://www.uvic.ca">University of Victoria</a> that I unimaginatively named the <a href="http://www.jwtanner.com/led_wheel/">LED Wheel</a>.  The <a href="http://www.jwtanner.com/led_wheel/">LED Wheel</a> is an embedded systems project designed to spin a single row of blinking LEDs and achieve persistence of vision.</p>

<p>Here is a picture of the LED Wheel displaying the pattern &quot;UVIC OPEN HOUSE&quot;.</p>

<img src="http://www.jwtanner.com/led_wheel/images/action1.jpg" border="0" alt="led wheel displaying pattern"></img>

<p>More pictures, video and all the details can be found in the <a href="http://www.jwtanner.com/led_wheel/">report</a>.</p>]]>
      </description>
      <pubDate>Fri, 26 Dec 2008 00:05:35 +0000</pubDate>
      <link>http://www.jwtanner.com/archive/the_led_wheel</link>
      <guid>http://www.jwtanner.com/archive/the_led_wheel</guid>
    </item>
    <item>
      <title>Roombas at UVIC 2008 Wrap-up</title>
      <author>justinwtanner@gmail.com</author>
      <description>
        <![CDATA[<p>Last semester at <a href="http://www.uvic.ca/">UVIC</a> I was privileged to work as the teaching assistant for the class <a href="http://web.uvic.ca/calendar2008/CDs/CSC/460.html">CSC 460: Design and Analysis of Real-time Systems</a>.  This year <a href="http://webhome.csc.uvic.ca/~mcheng/samples/personal/About%20Me.html">the professor</a> bought 6 refurbished <a href="http://store.irobot.com/corp/index.jsp">Roomba&#39;s</a> to be used by the students.</p>

<p>These Roomba&#39;s were programmed with the serial control interface (<a href="http://www.roombadevtools.com/productcart/pc/docs/docs_roombasci.pdf">pdf</a>).  This inteface allows API commands to be sent directly from a micro-controller to a Roomba via UART.</p>

<p>In under a month each team in this class created an impressive project using more than one combination of Roomba&#39;s, micro-controller&#39;s, and wireless radio&#39;s.  Here are the some of the video highlights.</p>

<p>Mike Waltz and Rayeed Ashir made three Roomba&#39;s dance in synchronization.</p>

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/z-7naUQi2TI&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/z-7naUQi2TI&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>

<br />

<p>Neil MacMillan and Ryan Downing made two Roomba&#39;s follow each other with <a href="http://www.pololu.com/catalog/product/701">pololu IR sensor&#39;s</a>.</p>

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/6RGcUic6UZI&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/6RGcUic6UZI&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>

<br />

<p>Here is a link to <a href="http://www.youtube.com/watch?v=WPQOre2YyiE">another video</a> of the follow the leader Roomba from a POV perspective.</p>

<p>Allen River and Duncan Penfold-brown created an ant Roomba that gathers IR beacons.</p>

<object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/wlP2403tKLE&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/wlP2403tKLE&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object>

<br />

<p>More videos of the ant Roomba.</p>

<ul>
<li><a href="http://www.youtube.com/watch?v=axHumg9Xb8A">Ant Roomba Resource Other Angle</a></li>
<li><a href="http://www.youtube.com/watch?v=wxwowPQ7vhA">Ant Roomba Queen Base Station</a></li>
<li><a href="http://www.youtube.com/watch?v=Xq287SYQoC8">Ant Roomba Collision Other Angle</a></li>
<li><a href="http://www.youtube.com/watch?v=7teFD0LKzdQ">Ant Roomba Collision</a></li>
<li><a href="http://www.youtube.com/watch?v=FpWNV0oKhhU">Ant Roomba Init</a></li>
</ul>

<p>Cecelia Redding and Matt Campbell created an attacker Roomba and a defender Roomba.  No video was available.</p>

<p>I also managed a Roomba project of my own this semester.  I created a USB gamepad controlled Roomba ( using wireless Bluetooth ).</p>

<object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/TAxUaDayFFg&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/TAxUaDayFFg&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object>

<p>More videos of the gamepad controlled Roomba.</p>

<ul>
<li><a href="http://www.youtube.com/watch?v=e_ZfxjYHOJ8">Joystick-controlled Roomba at UVIC</a></li>
<li><a href="http://www.youtube.com/watch?v=tccGOWjfq1w">IR Sensor and the joystick controlled Roomba</a></li>
</ul>
]]>
      </description>
      <pubDate>Mon, 05 Jan 2009 01:05:02 +0000</pubDate>
      <link>http://www.jwtanner.com/archive/roombas_at_uvic_2008_wrap_up</link>
      <guid>http://www.jwtanner.com/archive/roombas_at_uvic_2008_wrap_up</guid>
    </item>
  </channel>
</rss>
