<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>State Space</title>
	<atom:link href="http://embeddedgurus.com/state-space/feed/" rel="self" type="application/rss+xml" />
	<link>http://embeddedgurus.com/state-space</link>
	<description>A Blog by Miro Samek</description>
	<lastBuildDate>Mon, 30 Apr 2012 16:45:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>ESD closes shop. What&#8217;s next in store for embedded programming?</title>
		<link>http://embeddedgurus.com/state-space/2012/04/esd-closes-shop-whats-next-in-store-for-embedded-programming/</link>
		<comments>http://embeddedgurus.com/state-space/2012/04/esd-closes-shop-whats-next-in-store-for-embedded-programming/#comments</comments>
		<pubDate>Sun, 29 Apr 2012 16:36:59 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[event-driven programming]]></category>
		<category><![CDATA[modeling tool]]></category>
		<category><![CDATA[RTOS Multithreading]]></category>
		<category><![CDATA[state machines]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[UML]]></category>
		<category><![CDATA[predictions]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=154</guid>
		<description><![CDATA[The demise of the ESD Magazine marks the end of an era. In his recent post &#8220;Trends in Embedded Software Design&#8220;, the magazine insider Michael Barr commemorates this occasion by looking back at the early days and offering a look ahead at the new emerging trends. As we all enjoy predictions, I&#8217;d also like to [...]]]></description>
			<content:encoded><![CDATA[<p>The demise of the ESD Magazine marks the end of an era. In his recent post &#8220;<a href="http://embeddedgurus.com/barr-code/2012/04/trends-in-embedded-software-design/">Trends in Embedded Software Design</a>&#8220;, the magazine insider Michael Barr commemorates this occasion by looking back at the early days and offering a look ahead at the new emerging trends. As we all enjoy predictions, I&#8217;d also like to add a couple of my own thoughts about the current status and the future developments in embedded systems programming.</p>
<p>&nbsp;</p>
<h3><strong>It&#8217;s never been better to be an embedded software engineer!</strong></h3>
<p>&nbsp;</p>
<p>When I joined the embedded field in the mid 1990s, I thought that I was late to the party. The really cool stuff, such as programming in C, C++, or Ada (as opposed to assembly), RTOS, <a href="http://en.wikipedia.org/wiki/Rate-monotonic_scheduling" target="_blank">RMA</a>, or even modeling (remember <a href="http://www.drdobbs.com/184410342" target="_blank">ROOM</a>?) have been already invented and applied to programming embedded systems. The Embedded Systems Programming magazine brought every month invaluable, relevant articles that advanced the art and taught the whole generation. But then, right around the time of the first Internet boom, something happened that slowed down the progress. The universities and colleges stopped teaching C in favor of Java and, the numbers of graduates with skills necessary to write embedded code dropped sharply, at least in the U.S. In 2005 the Embedded Systems Programming magazine has been renamed to Embedded Systems Design (ESD), and lost its focus on embedded software. After this transition, I&#8217;ve noticed that the ESD articles became far less relevant to my software work.</p>
<p>All this is ironic, because at the same time embedded software grew to be more important than ever. The whole society is already completely dependent on embedded software and looks to embedded systems for solutions to the toughest problems of our time: environment protection, energy production and delivery, transportation, and healthcare. With the Moore&#8217;s law marching unstoppably into its fifth decade, even hardware design starts looking more like software development. There is no doubt in my mind: the golden time of embedded systems programming is right now. The skyrocketing demand for embedded software, on one hand, and diminished supply of qualified embedded developers on the other hand, creates a perfect storm. It simply has never been better to be an embedded software engineer! And I don&#8217;t see this changing in the foreseeable future.</p>
<p>&nbsp;</p>
<h3><strong>Future trends</strong></h3>
<p>&nbsp;</p>
<p>Speaking about the future, it&#8217;s obvious that we need to develop more embedded code with less people in less time. The only way to achieve this is to increase programmer&#8217;s productivity. And the only know way to boost productivity is to increase the level of abstraction either by working with higher-level concepts or by building code from higher-level components (code reuse).</p>
<h4><strong>Trend 1: Real-time embedded frameworks</strong></h4>
<p>My first prediction is that embedded applications will increasingly be based on specialized real-time embedded frameworks, which will increasingly augment and eventually displace the traditional RTOSes.</p>
<p>The software development for the desktop, the web, or mobile devices has already moved to frameworks (.NET, Cocoa, Qt, Ruby on Rails, Android, etc.), far beyond the raw APIs of the underlying OSes. In contrast, the dominating approach in the embedded space is still based directly on the venerable RTOS (or the &#8220;superloop&#8221; at the lowest end). The main difference is that when you use an RTOS <strong>you</strong> write the main body of the application (such as the thread routines for all your tasks) and <strong>you</strong> call the RTOS services (e.g., a semaphore, or a time delay). When you use a framework, you reuse the main body and write the code that <strong>it</strong> calls. In other words, the control resides in the framework, not in your code, so the control is <strong>inverted</strong> compared to an application based on an RTOS.</p>
<p>The advantage, long discovered by the developers of &#8220;big&#8221; software, is that frameworks offer much higher level of <strong>architectural reuse</strong> and give architectural integrity (often based on design patterns) to the applications. Frameworks also encapsulate the difficult or dangerous aspects of their application domains. For example, most programmers vastly underestimate the skills needed to use the various RTOS mechanisms, such as semaphores, mutexes, or even simple time delays, correctly and therefore developers vastly underestimate the true costs of using an RTOS. A generic, event-driven, real-time framework can encapsulate such low-level mechanisms, so the programmers can develop responsive, multitasking applications without even knowing what a semaphore is. The difference is like having to build a bridge each time you want to cross a river, and driving over a bridge that experts in this domain have built for you.</p>
<p>Real-time, embedded frameworks are not new and, in fact, have been extensively used for decades inside modeling tools capable of code generation. For example, a leading such tool, IBM Rhapsody, comes with an assortment of frameworks (<a href="http://www.ibm.com/developerworks/rational/library/rhapsody_release-v7.6/release.html">OXF, IDF, SXF, MXF, MicroC</a>, as well as third-party frameworks, such as <a href="http://www.willert.de/embedded-uml-rxf/">RXF from Willert</a>).</p>
<p>However, I don&#8217;t think that many people realize that frameworks of this sort can be used even without the big modeling tools and that they can be very small, about the same size as bare-bones RTOS kernels. For example, the open source<a href="http://www.state-machine.com/qp"> QP/C or QP/C++</a> frameworks from <a href="http://www.state-machine.com">Quantum Leaps</a> (my company) require only 3-4KB of ROM and significantly less RAM than an RTOS.</p>
<p>I believe that in the future we will see proliferation of various real-time embedded frameworks, just as we see proliferation of RTOSes today.</p>
<h4><strong>Trend 2: Agile modeling and code generation</strong></h4>
<p>Another trend, closely related to frameworks is modeling and automatic code generation.</p>
<p>I realize of course, that big tools for modeling and code generation have been tried and failed to penetrate the market beyond a few percentage points. The main reason, as I argued in my previous post &#8220;<a href="http://embeddedgurus.com/state-space/2012/04/economics-101-uml-in-embedded-systems/" target="_blank">Economics 101: UML in Embedded Systems</a>&#8220;, is the poor ROI (return on investment) of such tools. The investment, in terms of tool&#8217;s cost, learning curve, maintenance, and constant &#8220;fighting the tool&#8221; is so large, that the returns must also be extremely high to make any economic sense.</p>
<p>As the case in point take for example <a href="http://en.wikipedia.org/wiki/Executable_UML" target="_blank">xtUML</a> (executable UML) tools, which are perhaps the highest-ceremony tools of this kind on the market. In xtUML, you create platform-independent models (PIMs), which need to be translated to platform-specific models (PSMs) by highly customizable &#8220;model compilers&#8221;. To preserve the illusion of complete &#8220;platform and technology independence&#8221; (whatever that means in embedded systems that by any definition of the term are specific to the task and technology), any code entered into the model is specified in &#8220;<a href="http://www.ooatool.com/docs/OAL08.pdf" target="_blank">Object Action Language</a>&#8221; (OAL). AOL functionally corresponds to crippled C, but has a different syntax. All this is calculated to keep you completely removed from the generated code, which you can only influence by tweaking the &#8220;model compiler&#8221;.</p>
<p>But what if you could skip the indirection level of AOL and use C or C++ directly for programming &#8220;action functions&#8221;? (Maybe you don&#8217;t care for the ability to change the generated code from C to, say, Java). What if you could replace the &#8220;model compiler&#8221; indirection layer with a real-time framework? What if the tool can turn the code generation &#8220;upside down&#8221; and give you direct access to the code and the freedom to actually do the physical design (see my previous post &#8220;<a href="http://embeddedgurus.com/state-space/2012/02/turning-automatic-code-generation-upside-down/" target="_blank">Turning code generation upside down</a>&#8220;)?</p>
<p>Obviously, the resulting tool will be far less ambitious and &#8220;lover level&#8221; than xtUML. But &#8220;lower level&#8221; is not necessarily pejorative. In fact, the main reason for popularity of C in embedded programming is that C is a relatively &#8220;low level&#8221; high-level programming language.</p>
<p>I predict that we will see more innovation in the area of &#8220;low level&#8221; and low-cost modeling and code generating tools (such as the free <a href="http://www.state-machine.com/qm" target="_blank">QM modeling tool</a> from Quantum Leaps). I hope that this innovation will eventually bring us &#8220;modeling and code generation for the masses&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2012/04/esd-closes-shop-whats-next-in-store-for-embedded-programming/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Economics 101: UML in Embedded Systems</title>
		<link>http://embeddedgurus.com/state-space/2012/04/economics-101-uml-in-embedded-systems/</link>
		<comments>http://embeddedgurus.com/state-space/2012/04/economics-101-uml-in-embedded-systems/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 19:09:04 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[event-driven programming]]></category>
		<category><![CDATA[modeling tool]]></category>
		<category><![CDATA[state machines]]></category>
		<category><![CDATA[UML]]></category>
		<category><![CDATA[automatic code generation]]></category>
		<category><![CDATA[modeling]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=143</guid>
		<description><![CDATA[With UML, just as with anything else in the embedded space, the ultimate criterion for success is the return on investment (ROI). Sure there are many factors at play, such as &#8220;coolness factor&#8221;, yearning for a &#8220;silver bullet&#8221; and truly &#8220;automatic programming&#8221; all fueled by the aggressive marketing rhetoric of tool vendors. But ultimately, to be successful, [...]]]></description>
			<content:encoded><![CDATA[<p>With UML, just as with anything else in the embedded space, the ultimate criterion for success is the return on investment (ROI). Sure there are many factors at play, such as &#8220;coolness factor&#8221;, yearning for a &#8220;silver bullet&#8221; and truly &#8220;automatic programming&#8221; all fueled by the aggressive marketing rhetoric of tool vendors. But ultimately, to be successful, the benefits of a method must outweigh the learning curve, the cost of tools, the added maintenance costs, the hidden costs of &#8220;fighting the tool&#8221; and so on.</p>
<p>As it turns out, the ROI of UML is lousy unless the models are used to generate substantial portions of the production code. Without code generation, the models inevitably fall behind and become more of a liability than an asset. In this respect I tend to agree with the &#8220;<a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/BruceDouglass/entry/bruce_s_top_ten_modeling_hints_9_all_models_are_abstractions_in_that_they_focus_on_some_properties_and_aspects_at_the_expense_of_others49?lang=en" target="_blank">UML Modeling Maturity Index (UMMI)</a>&#8220;, invented by Bruce Douglass. According to the UMMI, without code generation UML can reach at most 30% of its potential, and this is assuming correct use of behavioral modeling. Without it, the benefits are below 10%. This is just too low to outweigh all the costs.</p>
<p>Unfortunately, code generation capabilities have been always associated with complex, expensive UML tools with a very steep learning curve and a price tag to match. With such a big investment side of the ROI equation, it&#8217;s quite difficult to reach sufficient return. Consequently, all too often big tools get abandoned and if they continue to be used at all, they end up as overpriced drawing packages.</p>
<p>So, to follow my purely economic argument, unless we make the investment part of the ROI equation low enough, without reducing the returns too much, UML has no chance. On the other hand, if we could achieve positive ROI (something like 80% of benefits for 10% of the cost), we would have a &#8220;game changer&#8221;.</p>
<p>To this end, when you look closer, the biggest &#8220;bang for the buck&#8221; in UML with respect to embedded code generation are: (1) an embedded real-time framework and (2) support for hierarchical state machines (UML statecharts). Of course, these two ingredients work best together and complement each other. State machines can&#8217;t operate in vacuum and need a framework to provide execution context, thread-safe event passing, event queueing, etc. Framework benefits from state machines for structure and code generation capabilities.</p>
<p>I&#8217;m not sure if many people realize the critical importance of a framework, but a good framework is in many ways even more valuable than the tool itself, because the framework is the big enabler of architectural reuse, testability, traceability, and code generation to name just a few. The second component are state machines, but again I&#8217;m not sure if everybody realizes the importance of state nesting. Without support for state hierarchy, traditional &#8220;flat&#8221; state machines suffer from the phenomenon known as &#8220;state-transition explosion&#8221;, which renders them unusable for real-life problems.</p>
<p>As it turns out, the two critical ingredients for code generation can be had with much lower investment than traditionally thought. An event-driven, real-time framework can be no more complex as a traditional bare-bones RTOS (e.g., see the family of the open source <a href="http://www.state-machine.com/qp" target="_blank">QP frameworks</a>). A UML modeling tool for creating hierarchical state machines and production code generation can be free and can be designed to minimize the problem of &#8220;fighting the tool&#8221; (e.g., see <a href="http://www.state-machine.com/qm" target="_blank">QM</a>). Sure, you don&#8217;t get all the bells and whistles of IBM Rhapsody, but you get the arguably most valuable ingredients. More importantly, you have a chance to achieve a positive ROI on your first project. As I said, this to me is game changing.</p>
<p>Can a lightweight framework like QP and the QM modeling tool scale to really big projects? Well, I&#8217;ve seen it used for tens of KLOC-size projects by big, distributed teams and I haven&#8217;t seen any signs of over-stressing the architecture or the tool.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2012/04/economics-101-uml-in-embedded-systems/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Turning automatic code generation upside down</title>
		<link>http://embeddedgurus.com/state-space/2012/02/turning-automatic-code-generation-upside-down/</link>
		<comments>http://embeddedgurus.com/state-space/2012/02/turning-automatic-code-generation-upside-down/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 16:34:28 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[modeling tool]]></category>
		<category><![CDATA[state machines]]></category>
		<category><![CDATA[UML]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=135</guid>
		<description><![CDATA[Much ink has been spilled on the Next Big Thing in software development. One of these things has always been &#8220;automatic code generation&#8221; from high-level models (e.g., from state machines). But even though many tools on the market today support code generation, their widespread acceptance has grown rather slowly. Of course, many factors contribute to [...]]]></description>
			<content:encoded><![CDATA[<p>Much ink has been spilled on the Next Big Thing in software development. One of these things has always been &#8220;automatic code generation&#8221; from high-level models (e.g., from state machines).</p>
<p>But even though many tools on the market today support code generation, their widespread acceptance has grown rather slowly. Of course, many factors contribute to this, but one of the main reasons is that the generated code has simply too many shortcomings, which too often require manual &#8220;massaging&#8221; of the generated code. But this breaks the connection with the original model. The tool industry&#8217;s answer has been &#8220;round-trip engineering&#8221;, which is the idea of feeding the changes in the code back to the model.</p>
<p>Unfortunately, &#8220;round-trip engineering&#8221; simply does not work well enough in practice. This should not be so surprising, considering that no other code generation in software history has ever worked that way. You don&#8217;t edit by hand the binary machine code generated by an assembler. You don&#8217;t edit by hand the assembly code generated by the high-level language compiler. This would be ridiculous. So, why modeling tools assume that the generated code will be edited manually?</p>
<p>Well, the modeling tools have to assume this, because the generated is hard to use &#8220;as-is&#8221; without modifications.</p>
<p>First, the generated code might be simply incomplete, such as skeleton code with &#8220;TODO&#8221; comments generated from class diagrams. I&#8217;m not a fan of this, because I think that in the long run such code generation is outright counterproductive.</p>
<p>Second, most code generating tools impose a specific physical design (by physical design I mean partitioning of the code into directories, and files, such as header files and implementation files). For example, for generation of C/C++ code (which dominate real-time embedded programming), the beaten path is to generate &lt;class&gt;.h and &lt;class&gt;.cpp files for every class. But what if I want to put class declaration in a file scope? Actually, I often want to do this to achieve even better encapsulation. A typical tool would not allow me to do this.</p>
<p>And finally, all too often the automatically generated code is hard to <strong>integrate</strong> with other code, not created by the tool. For example, a class definition might rely on many included header files. But while most tools recognize that and allow inserting some custom beginning of the file, they don&#8217;t allow to insert code in an arbitrary place in the file.</p>
<p>But, how about a tool that actually allows you to do your own physical design? How about turning the whole code generation process upside down?</p>
<p>A tool like this would allow <strong>you</strong> to create and name directories and files instead of the tool imposing it on you. Obviously, this is still manual coding. But, the twist here is that in this code you can &#8220;ask&#8221; the tool to synthesize parts of the code based on the model. (The &#8220;requests&#8221; are special tags that you mix in your code.) For example, you can &#8220;ask&#8221; the tool to generate a class declaration in one place, a class method definition in another, and a state machine definition in yet another place in <strong>your</strong> code.</p>
<p>This &#8220;inversion&#8221; of code generation responsibilities solves most of the problems with the integration between the generated code and other code. You can simply &#8220;ask&#8221; the tool to generate as much or as little code as you see fit. The tool helps, where it can add value, but otherwise you <strong>can</strong> keep it out of your way.</p>
<p>The idea of &#8220;inverting&#8221; the code generation is so simple, that I would be surprised if it was not already implemented in some tools. One example I have is the free QM tool from my company (<a title="state-machine.com/qm" href="http://www.state-machine.com/qm" target="_blank">http://www.state-machine.com/qm</a>). If you know of any other tool that works that way, I would be very interested to hear about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2012/02/turning-automatic-code-generation-upside-down/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Online Embedded Software Store: a good idea?</title>
		<link>http://embeddedgurus.com/state-space/2012/02/online-embedded-software-store-a-good-idea/</link>
		<comments>http://embeddedgurus.com/state-space/2012/02/online-embedded-software-store-a-good-idea/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 15:57:56 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[software licensing]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=126</guid>
		<description><![CDATA[Have you visited the new online Embedded Software Store (embeddedsoftwarestore.com) operated by Avnet and ARM? Did you buy anything there? What do you think? Well, I visited the website, but frankly, I wouldn&#8217;t be comfortable buying software there. For example, suppose you are interested in operating systems. That&#8217;s easy enough, because on the home page [...]]]></description>
			<content:encoded><![CDATA[<p>Have you visited the new online Embedded Software Store (<a title="embeddedsoftwarestore.com" href="http://embeddedsoftwarestore.com" target="_blank">embeddedsoftwarestore.com</a>) operated by Avnet and ARM? Did you buy anything there? What do you think?</p>
<p>Well, I visited the website, but frankly, I wouldn&#8217;t be comfortable buying software there.</p>
<p>For example, suppose you are interested in operating systems. That&#8217;s easy enough, because on the home page Embeddedsoftwarestore.com lists &#8220;New Products&#8221; in this category. Yesterday they listed uC/OS-II and CMS-RX RTOS. I clicked on uC/OS-II, which brought me to the product page for &#8220;uC/OS-II on the TI LM3S9Bxx &#8211; Product Line&#8221; by Micrium for $40,982.14. There is really not much of a product description, except for the &#8220;Product License&#8221;, which is a click-through EULA (End User License Agreement). Otherwise you can just add the product to the shopping cart and head out to check-out. Before you pay, you are presented with an order summary, where they list the products RoHS status, the packaging, as well as other equally &#8220;useful&#8221; information for software. You are also reminded that you are responsible for Duties and Taxes.</p>
<p>But, wait a minute. What are you buying here? First, you are not really buying the software, because you most likely already <strong>have</strong> it. It is available for a free download from Micrium (see <a title="micrium.com/page/downloads/source_code" href="http://micrium.com/page/downloads/source_code" target="_blank">http://micrium.com/page/downloads/source_code</a>). So, you obviously don&#8217;t care about &#8220;shipping&#8221;. Rather, you buy the <strong>rights</strong> to use the software in your Product Line. But then the click-through EULA makes no sense. It has no binding signature of the vendor and it has no Product Line definition.</p>
<p>If I would really spend $40,000 for legal rights, I would accept nothing less than a contract signed personally by an officer of Micrium. A click-through contract is good, perhaps, for buying a 99-cent song online, but then you actually get the song. Here, you are about to spend $40K, which is like buying two cars with a mouse click, and you don&#8217;t get anything.</p>
<p>Well, perhaps I&#8217;m missing something here, but it seems to me that software is a bit more complex product than chips and boards. What do you think of this business model?</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2012/02/online-embedded-software-store-a-good-idea/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s the state of your Cortex?</title>
		<link>http://embeddedgurus.com/state-space/2011/09/whats-the-state-of-your-cortex/</link>
		<comments>http://embeddedgurus.com/state-space/2011/09/whats-the-state-of-your-cortex/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 20:24:37 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[Firmware Bugs]]></category>
		<category><![CDATA[MCUs]]></category>
		<category><![CDATA[RTOS Multithreading]]></category>
		<category><![CDATA[ARM Cortex-M]]></category>
		<category><![CDATA[hardware race condition]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=118</guid>
		<description><![CDATA[Recently, I&#8217;ve been involved in a fascinating bug hunt related to a very peculiar behavior of the ARM Cortex-M3 core. Given the incredible popularity of this core, I thought that digging a little deeper into the mysteries of ARM Cortex could be interesting and informative. First, I need to provide some background. So, the bug [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I&#8217;ve been involved in a fascinating bug hunt related to a very peculiar behavior of the ARM Cortex-M3 core. Given the incredible popularity of this core, I thought that digging a little deeper into the mysteries of ARM Cortex could be interesting and informative.</p>
<p>First, I need to provide some background. So, the bug was related to the very unique ARM Cortex-M exception type called PendSV. This is an exception triggered by software, but unlike any regular software interrupt, PendSV is an <strong>asynchronous</strong> exception. This means that PendSV typically does not run immediately after it is triggered, but only after the Nested Vectored Interrupt Controller (NVIC) determines that the priority of the currently executing code drops below the priority associated with PendSV.</p>
<p>At this point, you might wonder, why and where would such &#8220;Pended Software Interrupt&#8221; be useful? Well, it turns out that PendSV is the only reliable way on ARM Cortex-M to find out when all (possibly nested) interrupt service routines (ISRs) have completed. And this determination is essential to run the scheduler in any preemptive real time kernel.</p>
<p>Virtually all preemptive RTOSes for ARM Cortex-M processors work as follows. Upon initialization the priority associated with PendSV is set to be the lowest of all exceptions (0xFF). All ISRs in the system, prioritized above PendSV, trigger the PendSV exception by writing 1 to the PENDSVSET bit in the NVIC ICSR register, like this:</p>
<p><code>*((uint32_t volatile *)0xE000ED04) = 0x10000000;<br />
</code><br />
Now, the heavy lifting is left entirely to the NVIC hardware. NVIC will activate PendSV only <strong>after</strong> the last of all nested interrupts completes and is about to return to the preempted task context. This is exactly the right time for a context switch. In other words, the PendSV exception is designed to call the scheduler and perform the task preemption. ARM Cortex is so smart that it eliminates the overhead of exiting one exception (the last nested interrupt) and activating another (the PendSV) in the trick called &#8220;tail-chaining&#8221;.</p>
<p>Everything looks easy so far, but ARM Cortex has one more trick up it&#8217;s sleeve and this optimization, called &#8220;late-arrival&#8221;, has interesting side effects related to PendSV. This subtle interaction between PendSV and late-arrival leads essentially to a hardware race condition I&#8217;ve recently had a pleasure to chase down.</p>
<p>To illustrate the events that lead up to the bug, I&#8217;ve prepared a distilled hardware trace available for viewing at <a title="ARM-Cortex-M3 bug trace" href="http://www.state-machine.com/attachments/ARM-Cortex-M3_bug.txt" target="_blank">ARM-Cortex-M3_bug.txt</a>. Please go ahead and click on this link to follow along.</p>
<p>The trace starts with an interrupt entry (labelled as Exception 83). This system runs under the preemptive kernel called QK, so the ISR calls QK_ISR_ENTRY() and later QK_ISR_EXIT() macros to inform the kernel about the interrupt. At trace index 069545 the QK_ISR_EXIT() macro triggers the PendSV exception by writing 0&#215;10000000 into the ICSR register.</p>
<p>After this, the Exception 83 runs to completion and eventually tail-chains to Exception 14 (PendSV). This is all as expected.</p>
<p>However, the real problem starts at trace index 069618, at which the execution of the first instruction of PendSV (CPSID i) is cancelled due to arrival of a higher-priority Exception 36 (another interrupt).</p>
<p>This cancellation of low-priority Exception 14 in favor of the higher-priority Exception 36 is anotehr ARM Cortex-special called <strong>late arrival</strong>. The ARM core optimizes the interrupt entry (which is identical for all exception), and instead of entering the low-priority exception and than immediately high-priority exception, it simply enters the high-priority exception.</p>
<p>The problem is that just before the late arrival, the PENDSVSET bit in the NVIC-ICSR register is already <em>cleared</em>.</p>
<p>However, the late-arriving Exception 36 sets this bit again in QK_ISR_EXIT(), which is normal for any interrupt (trace index 070126).</p>
<p>The Exception 36 eventually exits to the original PendSV (trace index 070130), but this is <strong>not</strong> the usual tail-chaining (the trace indicates tail-chaining by the pair Exception Exit/Exception Entry). This time around the trace shows only Exception Exit, but no entry.</p>
<p>This difference has very important implication, which is that the PENDSVSET bit in the NVIC-ICSR register is <span style="text-decoration: underline"><span style="color: #ff0000"><strong>not</strong></span></span> cleared (remember that it is set, however).</p>
<p>What unfolds next is the consequence of the PENDSVSET bit being set. PendSV executes, fakes its own return to the QK scheduler, and eventually it unlocks interrupts. But before SVCall (Exception 11) can execute, the PendSV Exception 14 is taken again (because it is triggered by the PENDSVSET bit). This makes no sense and should never happen, because PendSV should never be in the triggered state at this point.</p>
<p>***<br />
So, what are the consequences of this behavior and what is the fix?</p>
<p>Well, as you can see, due to late-arrival PendSV can be occasionally entered with the PENDSVSET bit being set, so it will be triggered again immediately after it completes. This might or might not have grave consequences. In case of the QK kernel, this was unacceptable and led to a Hardware Fault. In other RTOSes it might simply cause another scheduler call, waste of some CPU, and delay of the task-level response, but perhaps not a catastrophic failure.</p>
<p>The actual fix of the problem is very simple. Since you cannot rely on the automatic clearing of the PENDSVSET bit in the NVIC-ICSR register, you need to clear it manually (by writing 1 to the PENDSVCLR bit in the NVIC-ICSR register.) Of course this is wasteful, because only one time in a million this bit is actually not cleared automatically.</p>
<p>Interestingly, I have not seen such writing to the PENDSVCLR bit in open source RTOSes for ARM Cortex-M (such as FreeRTOS.org). Recently, I&#8217;ve come across some posts to the ARM Community Forums that this problem exists for the Frescale MQX RTOS (see <a title="PendSV pending inside PendSV handler?" href="http://forums.arm.com/index.php?/topic/15245-pendsv-pending-inside-pendsv-handler-cortex-m4/">PendSV pending inside PendSV handler? (Cortex-M4)</a>).</p>
<p>If you use a preemptive kernel on ARM Cortex-M0/M3, perhaps you could check how <em>your </em>kernel handles PendSV. If you don&#8217;t see an explicit write to the PENDSVCLR bit, I would recommend that you think through the consequences of re-entering PendSV. I&#8217;d be very interested to collect a survey of how the existing kernels for ARM Cortex-M handle this situation.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2011/09/whats-the-state-of-your-cortex/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>On the Origin of Software by Means of Artificial Selection</title>
		<link>http://embeddedgurus.com/state-space/2011/08/on-the-origin-of-software-by-means-of-artificial-selection/</link>
		<comments>http://embeddedgurus.com/state-space/2011/08/on-the-origin-of-software-by-means-of-artificial-selection/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 21:32:44 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[TDD]]></category>
		<category><![CDATA[embedded books]]></category>
		<category><![CDATA[embedded software development]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=102</guid>
		<description><![CDATA[If you haven&#8217;t put your hands on the recent James Grenning&#8217;s book &#8220;Test-Driven Development for Embedded C&#8221; yet, I highly recommend you do. Here is why. First, you need to realize that this book is not really about testing&#8211;it is about software development. The central idea behind TDD (Test-Driven Development) is that software, as any complex [...]]]></description>
			<content:encoded><![CDATA[<p>If you haven&#8217;t put your hands on the recent James Grenning&#8217;s book<em> &#8220;Test-Driven Development for Embedded C&#8221;</em> yet, I highly recommend you do. Here is why.</p>
<p>First, you need to realize that this book is <strong>not</strong> really about testing&#8211;it is about software <strong>development</strong>. The central idea behind TDD (Test-Driven Development) is that software, as any complex system in nature, has to evolve gradually and has to keep <strong>working</strong> throughout all the development stages. This idea is of course not new and goes back all the way to the Darwin&#8217;s &#8220;<em>On the Origin of Species&#8221;</em>. More recently, in his 1977 book &#8220;<em>Systemantics: How Systems Work and Especially How They Fail</em>&#8221; John Gall wrote:</p>
<blockquote><p><em>&#8220;A complex system that works is invariably found to have evolved from a simple system that worked&#8230;. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over, beginning with a working simple system&#8221;. </em></p></blockquote>
<p>The key point of TDD is to subject the software to constant &#8220;struggle for existence&#8221; to actually see if it indeed <strong>is</strong> still working and in the process weed out any undesired mutations.</p>
<p>Of course, in developing software we don&#8217;t have the deep evolutionary time, so we need to accelerate the pace of software evolution. We do this by <strong>automating</strong> the testing.</p>
<p>For embedded development this means avoiding the target system bottleneck (James calls it DOH-Development On Hardware). The embedded TDD strategy is to develop embedded software on the <strong>desktop</strong> and only occasionally check it on the real embedded hardware. This means that the C/C++ compilers and tools for the desktop (such as Visual C++, MinGW, or Cygwin for Windows and GCC for Linux and Mac OS X) are important for us.</p>
<p>The book comes with testing frameworks (Unity and CppUTest) and plenty of example code. The code works right of the box on Linux, but I had some issues running it on Windows. In the process of learning the tools, I&#8217;ve prepared a small template for Visual C++ 2008, which is available for download from:</p>
<p><a title="tdd_blinky.zip" href="http://www.state-machine.com/attachments/tdd_blinky.zip">http://www.state-machine.com/attachments/blinky_tdd.zip</a></p>
<p>This demo assumes that you download and install the CppUTest framework (<a href="http://sourceforge.net/projects/cpputest/">http://sourceforge.net/projects/cpputest/</a>) and that you define the environment variable CPP_U_TEST to point to the directory where you installed CppUTest. The Visual Studio solution AllTest.sln is located in the blinky\tests directory.</p>
<p>I&#8217;d love to hear about your experiences with TDD in embedded programming. I&#8217;m sure I will blog more about it in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2011/08/on-the-origin-of-software-by-means-of-artificial-selection/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Protothreads versus State Machines</title>
		<link>http://embeddedgurus.com/state-space/2011/06/protothreads-versus-state-machines/</link>
		<comments>http://embeddedgurus.com/state-space/2011/06/protothreads-versus-state-machines/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 17:28:53 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[Efficient C/C++]]></category>
		<category><![CDATA[event-driven programming]]></category>
		<category><![CDATA[state machines]]></category>
		<category><![CDATA[multitasking]]></category>
		<category><![CDATA[protothreads]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=92</guid>
		<description><![CDATA[For a number of years I&#8217;ve been getting questions regarding Protothreads and comparisons to state machines. Here is what I think. Protothreads are an attempt to write event-driven code in a sequential way. To do so, protothreads introduce a concept of &#8220;blocking abstraction&#8221; to event-driven programming&#8211;something that event-driven programming is trying to get rid of [...]]]></description>
			<content:encoded><![CDATA[<p>For a number of years I&#8217;ve been getting questions regarding <a title="Protothreads" href="http://en.wikipedia.org/wiki/Protothreads">Protothreads</a> and comparisons to state machines. Here is what I think.</p>
<p>Protothreads are an attempt to write event-driven code in a sequential way. To do so, protothreads introduce a concept of &#8220;blocking abstraction&#8221; to event-driven programming&#8211;something that event-driven programming is trying to get rid of in the first place.</p>
<p>Obviously, to be compatible with event-driven programming, protothreads cannot *really* block, at least not in the same sense as traditional threads of a conventional blocking RTOS can. Instead, a protothread is still called for every event and still *returns* to the caller without really blocking. However, when a given event does not match the &#8220;blocking abstraction&#8221;, the protothread returns without doing anything and without progressing. Only when the current event matches the &#8220;blocking abstraction&#8221; the protothread advances to the next &#8220;blocking abstraction&#8221; and also returns. Please note that protothreads allow standard flow control statements, such as IF-THEN-ELSE and WHILE loops between any two &#8220;blocking abstractions&#8221;. Therefore the program feels more &#8220;natural&#8221; for designers used to the traditional sequential programming style. You simply see the expected sequence of events.</p>
<p>Protothreads are indeed a simplification, but only for *sequential problems*, in which only specific sequences of events are valid and all other sequences are invalid. Examples for using protothreads include the sequence of events for initializing a radio modem.</p>
<p>However, protothreads lose their advantage entirely if there are many valid sequences of events. This is actually the most common situation in event-driven systems. State machines are capable to handle multiple sequences of events easily. In fact, state machines are getting simpler when the sequence of events matters less. In contrast, protothreads are getting more and more complex when they need to accept more sequences of events.</p>
<p>So, in the end, protothreads are an attempt to replace state machines, which are considered complex and messy by the inventors of the protothread mechanism. But, the &#8220;messiness&#8221; of state machines is obviously a very subjective statement. A good state machine implementation technique can remove many (most) accidental difficulties of coding state machines. I mean, if a state machine as depicted in a state diagram is simple, and if the code does not reflect this simplicity, the problem is with the implementation technique, not with the inherent complexity of a state machine.</p>
<p>The bottom line: good state machine implementation techniques eliminate most reasons for using protothreads. State machines are far more generic and flexible, because they can easily handle multiple sequences of events. In comparison, protothreads are intentionally crippled state machines that transition implicitly from one &#8220;blocking abstraction&#8221; to another executing code in between as the &#8220;actions&#8221; on such implicit transition.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2011/06/protothreads-versus-state-machines/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Is an RTOS really the best way to design embedded systems?</title>
		<link>http://embeddedgurus.com/state-space/2011/06/is-an-rtos-really-the-best-way-to-design-embedded-systems/</link>
		<comments>http://embeddedgurus.com/state-space/2011/06/is-an-rtos-really-the-best-way-to-design-embedded-systems/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 17:44:23 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[event-driven programming]]></category>
		<category><![CDATA[RTOS Multithreading]]></category>
		<category><![CDATA[state machines]]></category>
		<category><![CDATA[multitasking]]></category>
		<category><![CDATA[RTOS]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=86</guid>
		<description><![CDATA[Recently I&#8217;ve been involved in a discussion on the LinkedIn Real-Time Embedded Engineering group, which I started with the question &#8220;Is an RTOS really the best way to design embedded systems?&#8221;. The discussion, which has swollen to over 0xFF comments by now, has sometimes low signal to noise ratio, but I believe it is still [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.state-machine.com/attachments/linkedin_rte_group.jpg" alt="LinkedIn RTE group" /></p>
<p>Recently I&#8217;ve been involved in a discussion on the <a href="http://www.linkedin.com/groups?gid=102939">LinkedIn Real-Time Embedded Engineering group</a>, which I started with the question &#8220;Is an RTOS really the best way to design embedded systems?&#8221;.</p>
<p>The discussion, which has swollen to over 0xFF comments by now, has sometimes low signal to noise ratio, but I believe it is still interesting.</p>
<p>I consider this discussion to be a continuation of the topic from my April blog post <a href="http://embeddedgurus.com/state-space/2010/04/i-hate-rtoses/">I hate RTOSes</a>.</p>
<p>As before, my main point is centered on the fundamental mismatch of using the sequential programming paradigm (RTOS or superloop) to solve problems that are event-driven by nature.</p>
<p>I&#8217;m really curious what the visitors to <a href="http://EmbeddedGurus.com">EmbeddedGurus</a> think.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2011/06/is-an-rtos-really-the-best-way-to-design-embedded-systems/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rapid Prototyping with QP and Arduino</title>
		<link>http://embeddedgurus.com/state-space/2011/02/rapid-prototyping-with-qp-and-arduino/</link>
		<comments>http://embeddedgurus.com/state-space/2011/02/rapid-prototyping-with-qp-and-arduino/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 16:54:50 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=62</guid>
		<description><![CDATA[Arduino (see arduino.cc) is an open-source electronics prototyping platform, designed to make digital electronics more accessible to non-specialists in multidisciplinary projects. Arduino has gained popularity, because it provides both hardware and compatible software focused on developing working prototypes. By making it easier to build the first prototype, Arduino lowers the barrier of entry to the [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float: right;margin-left: 5px" src="http://www.state-machine.com/news/logo_arduino.png" alt="" /></p>
<p>Arduino (see <a href="http://arduino.cc">arduino.cc</a>) is an open-source electronics prototyping platform, designed to make digital electronics more accessible to <strong>non-specialists</strong> in multidisciplinary projects. Arduino has gained popularity, because it provides both hardware and compatible software focused on developing working prototypes. By making it easier to build the first prototype, Arduino lowers the barrier of entry to the field of modern microelectronics and enables a host of new applications.</p>
<p>However, programming the Arduino microcontroller (Atmel AVRmega) remains a challenge. Traditionally, Arduino programs are written in a sequential manner, which means that whenever an Arduino program needs to synchronize with some external event, such as a button press, arrival of a character through the serial port, or a time delay, it explicitly waits in-line for the occurrence of the event. Waiting &#8220;in-line&#8221; means that the Arduino processor spends all of its cycles constantly checking for some condition in a tight loop (called the polling loop).</p>
<p>Although this approach is functional in many situations, it doesn&#8217;t work very well when there are multiple possible sources of events whose arrival times and order you cannot predict and where it is important to handle the events in a timely manner. The fundamental problem is that while a sequential program is waiting for one kind of event (e.g., a button press), it is not doing any other work and is not responsive to other events (e.g., characters from the serial port).</p>
<p>Another big problem with the sequential program structure is wastefulness in terms of power dissipation. Regardless of how much or how little actual work is being done, the Arduino processor is always running at top speed, which drains the battery quickly and prevents you from making truly long-lasting battery-powered devices.</p>
<h3>Event-Driven Programming for Arduino</h3>
<p>For these and other reasons experienced programmers turn to the long-know design strategy called <em>event-driven programming</em>, which requires a distinctly different way of thinking than conventional sequential programs. All event-driven programs are naturally divided into the application, which actually handles the events, and the supervisory event-driven infrastructure (framework), which waits for events and dispatches them to the application. The control resides in the event-driven framework, so from the application standpoint, the control is inverted compared to a traditional sequential program.</p>
<p>It turns out that the <strong>QP/C++</strong> state machine framework beautifully complements the Arduino platform and provides everything you need to build responsive, robust, and power-efficient Arduino programs based on modern hierarchical state machines. In many ways the open source QP/C++ state machine framework is like a modern real-time operating system (RTOS) specifically designed for executing event-driven state machines. The free QM™ graphical modeling tool takes Arduino programming to the next level, by enabling automatic code generation of complete Arduino sketches.</p>
<p>The QP Development Kit (QDK) for Arduino is different from most other QDKs available from <a href="http://www.state-machine.com">state-machine.com</a> in that it is self-contained and includes the simplified and compacted source-code version of the QP/C++ framework. The QDK-Arduino is designed to plug directly into the Arduino IDE to become immediately useful without building a binary library. The extensive Application Note <a href="http://www.state-machine.com/arduino/AN_Event-Driven_Arduino.pdf">&#8220;Event Driven Arduino Programming with QP&#8221;</a> describes the main concepts and how to get started.</p>
<div><a href="http://www.state-machine.com/arduino" target="_blank">QDK-Arduino on state-machine.com<strong>»</strong></a><br />
<a href="http://arduino.cc/playground/Code/QP" target="_blank">QP on Arduino Playground<strong>»</strong></a></div>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2011/02/rapid-prototyping-with-qp-and-arduino/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Linear statechart notation</title>
		<link>http://embeddedgurus.com/state-space/2010/11/linear-statechart-notation/</link>
		<comments>http://embeddedgurus.com/state-space/2010/11/linear-statechart-notation/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 16:58:43 +0000</pubDate>
		<dc:creator>Miro Samek</dc:creator>
				<category><![CDATA[modeling tool]]></category>
		<category><![CDATA[state machines]]></category>
		<category><![CDATA[UML]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/state-space/?p=54</guid>
		<description><![CDATA[The traditional fully 2-dimensional structure of UML state diagrams is too much rope to hang yourself with. There is no standard drawing order or pattern; some designers start from the top, some from the middle, and others just &#8220;go with the flow&#8221;. Transitions can originate at any state edge and go in any direction, so they are [...]]]></description>
			<content:encoded><![CDATA[<p>The traditional fully 2-dimensional structure of UML state diagrams is too much rope to hang yourself with. There is no standard drawing order or pattern; some designers start from the top, some from the middle, and others just &#8220;go with the flow&#8221;. Transitions can originate at any state edge and go in any direction, so they are easy to miss in any nontrivial diagram because you don&#8217;t know exactly where to look.</p>
<p>In many ways, UML state diagrams resemble the old way of drawing tree structures (e.g., a family tree) with the root in the middle and branches fanning out in all directions. But today nobody draws hierarchical structures that way anymore. If you look at your file-system explorer you will see the hierarchical structure of directories and files arranged <strong>linearly</strong>, top-to-bottom. The &#8220;linear statechart notation&#8221; that I would like to propose here is based on the same idea.</p>
<p>The goal of the &#8220;linear statechart notation&#8221; is to make the diagrams more structured and legible by reducing the use of horizontal dimension.</p>
<p>As an example of the &#8220;linear notation&#8221; consider the state diagram shown in the screen shot from the <a title="Free QM state machine tool for embedded systems" href="http://embeddedgurus.com/state-space/2010/11/free-state-machine-tool-for-embedded-systems/" target="_self">free QM tool</a>.  (This statechart shows the lifescycle of a space ship in a simple &#8220;Fly &#8216;n&#8217; Shoot&#8221; game.) First please take a look at the hierarchical model explorer pane on the left-side of the screen. You see the Ship object, its attributes and methods followed by the Statechart with the hierarchically arranged elements below. Now, please take a look at the state diagram in the middle. You will see the one-to-one correspondence between the diagram and the explorer view. Please note that the state diagram is essentially 1-dimensional.</p>
<p><img src="http://www.state-machine.com/attachments/linear.jpg" alt="" /></p>
<p>Finally, please take a look at the right-hand side, which is a screenshot of the *generated code* in the Eclipse-based tool (Atollic TrueSTUDIO in this case). The generated code corresponds to the state &#8220;flying&#8221;, which is highlighted in the diagram. Interestingly, the code itself is an extension of the &#8220;linear notation&#8221; that zooms into the &#8220;flying&#8221; state. Again, just go from the top to bottom in the code, inside the &#8220;flying&#8221; state in the diagram, and in the &#8220;flying&#8221; element in the model explorer. You see exactly the same elements represented in the same order, from the entry action, through the events TIME_TICK, PLAYER_TRIGGER, DESTROYED_MINE, HIT_WALL, and HIT_MINE. I think this consistency and tracibility is great.</p>
<p>I&#8217;d like to hear your comments about the proposed notation. I also hope that this post explains a bit how the <a title="Free QM state machine tool for embedded systems" href="http://www.state-machine.com/qm" target="_self">free QM tool</a> works and generates code.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/state-space/2010/11/linear-statechart-notation/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

