PageSourceSearch

http://www.hashmismatch.net/

html hashmismatch.net collected 2026-10-07 18:59:45 UTC 13,601 bytes, 257 lines download raw bytes

1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml">
3	<head>
4	<meta name="generator" content="Hugo 0.36" />
5		<meta content="en-US" http-equiv="Content-Language" />
6		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
7		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
8        
9
10	    <title>HashMismatch</title>
11	    <link href='//fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css' />
12	    <link href='//fonts.googleapis.com/css?family=Roboto:400,700,300' rel='stylesheet' type='text/css' />
13	    <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.css" />
14		<link rel="stylesheet" type="text/css" href="/css/site.css" />
15	    
16        <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png"/>
17        <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png"/>
18        <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"/>
19        <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"/>
20        <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"/>
21        <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"/>
22        <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"/>
23        <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"/>
24        <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/>
25        <link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png"/>
26        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
27        <link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/>
28	    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
29        <link rel="shortcut icon" href="/favicon.ico" />
30        
31        
31<script async defer src="https://buttons.github.io/buttons.js"></script>
31
32        
33        
34            <link href="http://www.hashmismatch.net/index.xml" rel="alternate" type="application/rss+xml" title="HashMismatch" />
35            <link href="http://www.hashmismatch.net/index.xml" rel="feed" type="application/rss+xml" title="HashMismatch" />
36        
37
38	</head>
39    <body>
40        <header role="banner">
41            <div class="logo-text"><a href="/index.html" title="HashMismatch">#<span class="ne">!=</span></a></div>
42            
43            <div class="icons">
44                <a href="https://github.com/hashmismatch" title="Github"><i class="fa fa-github"></i></a>
45            </div>
46        </header>
47        <nav>
48            
49                When things go mildly wrong
50            
51        </nav>
52        
53        <div id="content">
54
55            
56
57  <h2 style="line-height: 1.5em"><a href="/libraries/">Software development libraries</a></h2>
58
59  
60
61  
62
63    
64
65<a href="http://www.hashmismatch.net/libraries/packed-struct/">
66<div class="library_hello"
67    
68    style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.0) 0%,rgba(0,0,0,0.2) 70%, rgba(0,0,0,0.8) 100%), url(/libraries/packed_struct_gfx.png);"
69>
70
71    <div class="crate">
72        packed_struct
73    </div>
74
75    <div class="title">
76        Bit-level packing and unpacking
77    </div>
78
79</div>
80</a>
81    
82
83  
84
85    
86
87<a href="http://www.hashmismatch.net/libraries/freertos_rs/">
88<div class="library_hello"
89    
90    style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.0) 0%,rgba(0,0,0,0.2) 70%, rgba(0,0,0,0.8) 100%), url(/libraries/demo-hw.jpg);"
91>
92
93    <div class="crate">
94        freertos_rs
95    </div>
96
97    <div class="title">
98        A FreeRTOS API for embedded Rust
99    </div>
100
101</div>
102</a>
103    
104
105  
106
107    
108
109<a href="http://www.hashmismatch.net/libraries/terminal-cli/">
110<div class="library_hello"
111    
112    style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.0) 0%,rgba(0,0,0,0.2) 70%, rgba(0,0,0,0.8) 100%), url(/libraries/terminal_cli_gfx.png);"
113>
114
115    <div class="crate">
116        terminal_cli
117    </div>
118
119    <div class="title">
120        Interactive command line prompt
121    </div>
122
123</div>
124</a>
125    
126
127  
128
129
130  <h2><a href="/posts/">Articles</a></h2>
131
132  
133
134  
135  <div class='post'>
136    <h1><a href="http://www.hashmismatch.net/freertos-meets-rust/">FreeRTOS meets Rust</a></h1>
137    <div class="postdate"><time itemprop="datePublished" pubdate="pubdate" datetime="2016-09-26T09:33:52&#43;02:00">Mon, Sep 26, 2016</time></div>
138    
139    
140
141<p>The Rust ecosystem has made some cool progress on the embedded development front since my <a href="/pragmatic-bare-metal-rust/">last article</a>. Let&rsquo;s take a look how we can build a much more ergonomical and safe API to one of the more popular real time operating systems - <a href="http://www.freertos.org/">FreeRTOS</a> - with a full testing and continous integration setup.</p>
142
143<p>To get you going, a snippet from a <a href="https://github.com/hashmismatch/freertos.rs/blob/7a6d19aabb240d2f0cb281664919abe32b6f7d83/qemu_stm32_tests/src/test_sample1.rs">unit test</a> that demonstrates the usage of queues and compute tasks.</p>
144<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-rust" data-lang="rust"><span style="color:#75715e">// A shared queue
145</span><span style="color:#75715e"></span><span style="color:#66d9ef">let</span> queue <span style="color:#f92672">=</span> Arc::new(Queue::new(<span style="color:#ae81ff">10</span>).unwrap());
146
147<span style="color:#75715e">// Task that consumes integers from the shared queue. Returns the
148</span><span style="color:#75715e">// summed value when a new integer hasn&#39;t been posted for 100 ms.
149</span><span style="color:#75715e"></span><span style="color:#66d9ef">let</span> sum_task <span style="color:#f92672">=</span> {
150	<span style="color:#66d9ef">let</span> queue <span style="color:#f92672">=</span> queue.clone();
151
152	Task::new().name(<span style="color:#e6db74">&#34;sum&#34;</span>).compute(<span style="color:#66d9ef">move</span> <span style="color:#f92672">||</span> {
153		<span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> sum <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
154
155		<span style="color:#66d9ef">loop</span> {
156			<span style="color:#66d9ef">if</span> <span style="color:#66d9ef">let</span> Ok(val) <span style="color:#f92672">=</span> queue.receive(Duration::ms(<span style="color:#ae81ff">100</span>)) {
157				sum <span style="color:#f92672">+=</span> val;
158			} <span style="color:#66d9ef">else</span> {
159				<span style="color:#66d9ef">break</span>;
160			}
161		}
162
163		sum
164	}).unwrap()
165};
166
167<span style="color:#75715e">// Send the integers to the shared queue
168</span><span style="color:#75715e"></span><span style="color:#66d9ef">for</span> i <span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span>..<span style="color:#ae81ff">11</span> {
169	queue.send(i, Duration::ms(<span style="color:#ae81ff">15</span>)).unwrap();
170}
171
172<span style="color:#75715e">// Wait for the compute task to finish the calculation
173</span><span style="color:#75715e"></span><span style="color:#66d9ef">let</span> sum <span style="color:#f92672">=</span> sum_task.into_result(Duration::Infinite).unwrap();
174
175<span style="color:#75715e">// Check the result
176</span><span style="color:#75715e"></span>assert_eq<span style="color:#f92672">!</span>(<span style="color:#ae81ff">55</span>, sum);</code></pre></div>
177<h2 id="talking-to-freertos">Talking to FreeRTOS</h2>
178
179<p>Most of FreeRTOS&rsquo; offical API calls are actually macros that abstract various internal function, so we can&rsquo;t just directly invoke most of the function calls. So we need an <a href="https://github.com/hashmismatch/freertos.rs/blob/991ee0a4f59842c069f8980e03c58a012aa80e69/shim/freertos_rs.c">inter-op shim</a> written in C that helps us connect Rust and FreeRTOS.</p>
180
181<h2 id="cross-compilation">Cross compilation</h2>
182
183<p>Previously, we had to manually prepare the whole Rust library ecosystem for non-standard cross compilations targets. Rust&rsquo;s package manager Cargo is thankfully easily extensible and the <a href="https://crates.io/crates/xargo">xargo</a> helper command does the whole job of obtaining the correct sources and preparing an alternate set of Rust libraries (<code>core</code>, <code>alloc</code> and <code>collections</code>) for us. The final output is a set of object files that can be linked together with the target platform&rsquo;s linker.</p>
184
185<h2 id="base-firmware">Base firmware</h2>
186
187<p>My target board of choice is <a href="http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-discovery-kits/stm32f4discovery.html">STM32F4Discovery</a>. ST&rsquo;s hardware configuration and base firmware generator <a href="http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html">STM32CubeMX</a> greatly helps with setting all the correct clocks, IO ports, timer and other various peripherals. Using a <a href="https://github.com/baoshi/CubeMX2Makefile">project converter</a>, we&rsquo;re able to use <a href="https://launchpad.net/gcc-arm-embedded">GNU ARM GCC</a> to compile the CubeMX generated project.</p>
188
189<p>The final firmware boots up to the <code>main()</code> written in C, setups the hardware, then hands over the execution to Rust.</p>
190
191<h2 id="unit-tests-and-continous-integration">Unit tests and continous integration</h2>
192
193<p>We&rsquo;ll make a small compromise by using an emulator instead of the real hardware for continous integration, but it&rsquo;s an excusable cost cutting for a hobby, open source project. <a href="http://gnuarmeclipse.github.io/qemu/">The GNU ARM Eclipse QEMU</a> provides basic emulation of our development board.</p>
194
195<p>The emulator doesn&rsquo;t implement many peripherals at the moment. For testing interrupts, we emulate a timer-triggered interrupt by spawning a separate FreeRTOS task and triggering the interrupt programatically. Also the FPU registers aren&rsquo;t emulated fully, so a hack in FreeRTOS&rsquo; scheduler was required to omit the FPU registers while switching the context.</p>
196
197<p>But it all makes it worthwhile when Travis serves you a green tick mark.</p>
198
199<h2 id="standard-api-parity">Standard API parity</h2>
200
201<p>Rust&rsquo;s standard library provides the same primitives for mutual exclusion, threads and queues, so it would make sense to adopt its namespace and semantics to provide easier usage of other Rust libraries. However, I felt that semantics and requirements for embedded are slightly different so a separate namespace made sense. For embedded application code unit testing on the desktop, an alternative implementation that uses Rust&rsquo;s standard library could come in handy.</p>
202
203<h2 id="discussion">Discussion</h2>
204
205<p>
205Setting up the development environment is still a mess. Keeping the code generators, open source IDE like Eclipse, Makefiles and Rust in sync takes a lot of mental gymnastics.</p>
206
207<p>Reimplementing FreeRTOS-like functionality in Rust and assembler is a big undertaking, but the ecosystem will probably provide it in time. The one thing that the community seems to have trouble keeping up with is the chip makers and their drivers for peripherals. So I believe that linking to manufacturer&rsquo;s HAL libraries, with C shims in between - as C developers really like their macros - will be the norm for the foreseeable future.</p>
208
209<hr />
210
211<p>Github project: <a href="https://github.com/hashmismatch/freertos.rs">FreeRTOS.rs</a> Cargo crate: <a href="https://crates.io/crates/freertos_rs">freertos_rs</a> Documentation: <a href="https://docs.rs/freertos_rs">freertos_rs</a></p>
212
213</div>
214  
215
216  
217    <h2 style="margin-top: 1.5em;">Archive</h2>
218
219    <ul class="postArchive">
220      
221        <li>
222          <a class="postlink" href="http://www.hashmismatch.net/pragmatic-bare-metal-rust/">Pragmatic Bare Metal Rust</a>
223        </li>
224      
225    </ul>  
226  
227
228            
229
230
231        </div>
232
233        <div id="site_copyright">
234            &copy; 2015-
234<script>document.write(new Date().getFullYear())</script>
234
235            Rudi Benkovič •
236            <a href="https://www.linkedin.com/in/rudi-benkovi%C4%8D-6a59159/">LinkedIn</a> •
237            <a href="https://github.com/hashmismatch">GitHub</a> •
238            <a href="mailto:[email protected]">Contact</a>
239        </div>
240
241        
241<script src="//code.jquery.com/jquery-2.2.1.min.js"></script>
241
242        
242<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
242
243
244        
244<script>
vendor: 458 bytes, lines 244-252
244
245        (function (i, s, o, g, r, a, m) {
246            i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
247                (i[r].q = i[r].q || []).push(arguments)
248            }, i[r].l = 1 * new Date(); a = s.createElement(o),
249            m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
250        })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
251
252        ga('create', '
252UA-63040981-1
vendor: 56 bytes, lines 252-255
252', 'auto');
253        ga('send', 'pageview');
254
255        
255</script>
255
256    </body>
257</html>            

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.