lupyuen.org/articles/hosting-embedded-rust-apps-on-apache-mynewt-with-stm32-blue-pill.html

1721 lines
No EOL
125 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/_static/css/banner-styles.css?v=bsmaklHF" />
<link rel="stylesheet" type="text/css" href="/_static/css/iconochive.css?v=qtvMKcIJ" />
<link rel="canonical" href="https://lupyuen.org/articles/hosting-embedded-rust-apps-on-apache-mynewt-with-stm32-blue-pill.html" />
<!-- End Wayback Rewrite JS Include -->
<title data-rh="true">Hosting Embedded Rust apps on Apache Mynewt with STM32 Blue Pill</title>
<meta data-rh="true" charset="utf-8" />
<meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" />
<meta data-rh="true" name="theme-color" content="#000000" />
<meta data-rh="true" property="og:type" content="article" />
<meta data-rh="true" property="article:published_time" content="2019-08-17T17:17:23.538Z" />
<meta data-rh="true" name="title" content="Hosting Embedded Rust apps on Apache Mynewt with STM32 Blue Pill" />
<meta data-rh="true" property="og:title" content="Hosting Embedded Rust apps on Apache Mynewt with STM32 Blue Pill" />
<meta data-rh="true" property="twitter:title"
content="Hosting Embedded Rust apps on Apache Mynewt with STM32 Blue Pill" />
<meta data-rh="true" name="description"
content="Build IoT devices the smarter, safer way with Rust and Apache Mynewt" />
<meta data-rh="true" property="og:description"
content="Build IoT devices the smarter, safer way with Rust and Apache Mynewt" />
<meta data-rh="true" property="twitter:description"
content="Build IoT devices the smarter, safer way with Rust and Apache Mynewt" />
<meta data-rh="true" name="twitter:card" content="summary_large_image" />
<meta data-rh="true" name="twitter:creator" content="@MisterTechBlog" />
<meta data-rh="true" name="author" content="Lup Yuen Lee 李立源" />
<meta data-rh="true" name="robots" content="index,follow" />
<meta data-rh="true" name="referrer" content="unsafe-url" />
<meta data-rh="true" name="twitter:label1" value="Reading time" />
<meta data-rh="true" name="twitter:data1" value="19 min read" />
<meta property="og:image"
content="https://lupyuen.github.io/images/legacy2/e1.png">
<!-- Begin scripts/rustdoc-header.html: Header for Custom Markdown files processed by rustdoc, like chip8.md -->
<link rel="alternate" type="application/rss+xml" title="RSS Feed for lupyuen" href="/rss.xml" />
<link rel="stylesheet" type="text/css" href="../normalize.css">
<link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle">
<link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle">
<link rel="stylesheet" type="text/css" href="../prism.css">
<script src="../storage.js"></script><noscript>
<link rel="stylesheet" href="../noscript.css"></noscript>
<link rel="shortcut icon" href="../favicon.ico">
<style type="text/css">
#crate-search {
background-image: url("../down-arrow.svg");
}
a {
color: #77d;
}
</style>
<!-- End scripts/rustdoc-header.html -->
</head>
<body>
<div id="root">
<div class="a b c">
<article>
<section class="cj ck cl cm ak cn ce n co"></section><span class="r"></span>
<div>
<div class="cp u cq cr cs ct"></div>
<section class="cu cv cw cx cy">
<div class="cz ak">
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e1.png" /></p>
<figcaption><p><em>What keeps me awake at night? Wondering why our
microcontrollers (like STM32 Blue Pill above) have become so powerful… that we cant write powerful
programs to exploit them</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<div>
<div id="3c0a" class="ea eb ec bk ed b ee ef eg eh ei ej ek">
<h1 class="ed b ee el ec">Hosting Embedded Rust apps on Apache Mynewt with STM32 Blue Pill</h1>
</div>
<div class="em">
<div class="n en eo ep eq">
<div class="o n">
<div><a rel="noopener"
href="https://lupyuen.github.io">
<div class="dd er es">
<div class="bs n et o p cp eu ev ew ex ey ct"></div>
</div>
</a></div>
<div class="fa ak r">
<div class="n">
<div style="flex:1"><span class="bj b bk bl bm bn r ec q">
<div class="fb n o fc"><span class="bj dy ds bl di fd fe ff fg fh ec"><a
class="at au av aw ax ay az ba bb bc fi bf bg bh bi" rel="noopener"
href="https://lupyuen.github.io">Lup
Yuen Lee 李立源</a></span>
</div>
</span></div>
</div><span class="bj b bk bl bm bn r bo bp"><span class="bj dy ds bl di fd fe ff fg fh bo">
<div><a class="at au av aw ax ay az ba bb bc fi bf bg bh bi" rel="noopener"
href="https://lupyuen.github.io/articles/hosting-embedded-rust-apps-on-apache-mynewt-with-stm32-blue-pill">
9 Jun 2019</a> <!-- -->·
<!-- -->
<!-- -->19
<!-- --> min read
</div>
</span></span>
</div>
</div>
</div>
</div>
</div>
<p id="ea07" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Todays microcontrollers (like
the <a
href="http://wiki.stm32duino.com/index.php?title=Blue_Pill"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">STM32 Blue Pill</a>) pack so many
features in a tiny package… yet few embedded programmers are capable of exploiting the <strong
class="gj gz">full potential of modern microcontrollers</strong>. Many of us (my IoT students
included) seem to be stuck in the 1980s —<strong class="gj gz"> painstakingly writing C programs for
small computers.</strong></p>
<p id="6d9c" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Its time to drop our legacy
programming practices and adopt smarter, safer ways to exploit these microcontrollers… starting with
<a href="https://mynewt.apache.org/latest/index.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">Apache
Mynewt</strong></a><strong class="gj gz"> and </strong><a
href="https://doc.rust-lang.org/stable/book/"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong
class="gj gz">Rust</strong></a><strong class="gj gz">.</strong></p>
<p id="a684" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Mynewt is a <strong
class="gj gz">modern realtime operating system</strong> that runs on many microcontroller platforms,
even on devices with little RAM and ROM like Blue Pill. It has an excellent <a
href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_framework.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">Sensor
Framework</strong></a> for creating IoT devices.</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e2.png" /></p>
<figcaption><p><em>Sensor Network with Blue Pill, ESP8266,
nRF24L01 and Mynewt</em></p></figcaption>
</div>
<p id="57a2" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Stretching Mynewt on Blue Pill to
the limit, I have created <a class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/build-your-iot-sensor-network-stm32-blue-pill-nrf24l01-esp8266-apache-mynewt-thethings-io">sophisticated
sensor networks</a> with <a
href="https://en.wikipedia.org/wiki/Constrained_Application_Protocol"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">CoAP encoding</a> (JSON and <a
href="https://en.wikipedia.org/wiki/CBOR"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">CBOR</a>), transmitting and
receiving simultaneously on both ESP8266 and nRF24L01 modules.</p>
<p id="bbb5" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Sadly, Mynewt only supports
<strong class="gj gz">applications developed in C</strong>, consistent with its frugal origins. But C
programming is a rare skill today (and C frustrates my IoT students too). What about other languages?
<a href="https://en.wikipedia.org/wiki/MicroPython"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">MicroPython</a> and <a
class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/stm32-blue-pill-dissecting-the-webusb-bootloader-for-makecode">JavaScript</a>
seem too heavy for a lightweight Mynewt device… <em class="ht">perhaps Rust?</em></p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e3.png" /></p>
<figcaption><p><em>Mynewt and Rust: The Perfect Match
</em></p></figcaption>
</div>
<p id="05d4" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">In my <a
class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://web.archive.org/https://medium.com/coinmonks/coding-the-stm32-blue-pill-with-rust-and-visual-studio-code-b21615d8a20">previous
experiments</a> with Embedded Rust (<a class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://web.archive.org/https://medium.com/coinmonks/running-rust-and-freertos-on-the-padi-iot-stamp-fb36c5ef4844">including
this one</a>), I know that Rust flies <strong class="gj gz">light and fast</strong> just like C.
Rust has <strong class="gj gz">great support in coding tools</strong> like Visual Studio Code, which
makes it easier to code for newbies.</p>
<p id="d118" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Rust advocates <strong
class="gj gz">“Safe Coding”</strong>. Rust<strong class="gj gz"> </strong>disallows bad code that
may cause our device to crash. <em class="ht">Rust could be the perfect match for Mynewt!</em></p>
<p id="762a" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">In this article well mix Mynewt
with Rust and learn…</p>
<p id="3f03" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1⃣ Why is <strong
class="gj gz">Rust better than C</strong> for embedded programming</p>
<p id="fd10" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2⃣ How to <strong
class="gj gz">call C functions from Rust</strong> and vice versa</p>
<p id="1f26" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3⃣ Whats <strong
class="gj gz">Unsafe Coding</strong> and how to make coding safer</p>
<p id="2d1e" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">4⃣ How <strong
class="gj gz">Rust compiles programs</strong></p>
<p id="fad9" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">5⃣ How to <strong
class="gj gz">inject Rust code</strong> into the Mynewt build</p>
<p id="3f3b" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">6⃣ How to <strong
class="gj gz">install and configure</strong> the Rust and Mynewt code</p>
<p id="23ff" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">7⃣ And finally well see an
actual <strong class="gj gz">Rust application running on Mynewt</strong> with Blue Pill</p>
<p id="d3b1" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Heres the <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/src"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Rust application code</a> that
well be running: A sensor application that <strong class="gj gz">polls Blue Pills internal
temperature sensor every 10 seconds</strong> and displays the result…</p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz">
<div class="dl r dd">
<div class="ie r"><iframe
src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FXeRKRI8JYQE%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DXeRKRI8JYQE&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FXeRKRI8JYQE%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube"
allowfullscreen="" frameborder="0" height="300" width="400"
title="Hosting Rust Applications on Apache Mynewt - Code" class="cp t u dh ak"
scrolling="auto"></iframe></div>
</div>
<figcaption><p><em>Walkthrough of the Rust application code
</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<p id="5ed5" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">The complete Rust and Mynewt code
may be found here…</p>
<div class="if ig ih ii ij ik"><a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust?source=post_page-----c86b119fe5f----------------------"
rel="noopener nofollow">
<section class="in cl cm ak ce n ar io ip iq ir is it iu iv iw ix iy iz ja jb jc">
<div class="jd n co p je jf">
<h2 class="bj jg jh bl ec">
<div class="di il fe ff im fh">lupyuen/stm32bluepill-mynewt-sensor</div>
</h2>
</div>
<div class="jk r">
<div class="jl r jm jn jo jk jp jq jr"></div>
</div>
</section>
</a></div>
<blockquote class="js jt ju">
<p id="7296" class="gh gi ec ht gj b gk gl gm gn go gp gq gr gs gt gu"><em class="bk">💎 </em>Sections
marked with a diamond are meant for advanced developers. If youre new to embedded programming, you
may skip these sections</p>
</blockquote>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="6a01" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Embedded Programming in Rust vs
C</h1>
<p id="cc7d" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">Why is Rust better than C for
Embedded Programming? Heres what I think…</p>
</div>
</div>
<div class="cz ak">
<div class="figure hb hc hd he hf cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e4.png" /></p>
<figcaption><p><em>Calling the Mynewt Sensor Listener API: Rust
Code (left) vs C Code (right)</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="kw">
<div id="476c" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Rust is Strict and Stubborn</p>
</div>
</blockquote>
<p id="1df5" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">Rust syntax is highly similar to
C. If youre looking at Rust code for the first time, you may think that Rust is an untyped language
(like JavaScript) that doesnt care about the precise types of each variable…</p>
<p id="b997" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Why would Rust allow <code
class="dm ln lo lp lq b">let rc = ...</code> without forcing us to declare <code
class="dm ln lo lp lq b">rc</code> as an <code class="dm ln lo lp lq b">int</code> like in C? Does
it mean that <code class="dm ln lo lp lq b">rc</code> can change its type from <code
class="dm ln lo lp lq b">int</code> to <code class="dm ln lo lp lq b">char*</code>?</p>
<p id="5c81" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Nope, thats because Rust has <a
href="https://en.wikipedia.org/wiki/Type_inference"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">Type
Inference</strong></a> — the Rust compiler analyses our source code and deduces that <code
class="dm ln lo lp lq b">rc</code> must be an <code class="dm ln lo lp lq b">int</code> (which is
named <code class="dm ln lo lp lq b">i32</code> in Rust). Why? Because <code
class="dm ln lo lp lq b"><a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_mgr_api.html#c.sensor_set_poll_rate_ms" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor_set_poll_rate_ms</a>()</code>
returns an <code class="dm ln lo lp lq b">i32</code> (32-bit integer). So Rust enforces variable types
as strongly as C, just smarter.</p>
<p id="a496" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Rust is actually<em class="ht">
stricter than C</em> — All Rust variables are <a
href="https://doc.rust-lang.org/stable/book/ch03-01-variables-and-mutability.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">assumed to be constant,
unchanging, <strong class="gj gz">immutable</strong></a> (<em class="ht">“stubborn”</em>) unless we
declare the variable as <code class="dm ln lo lp lq b"><strong class="gj gz">mut</strong></code>
(mutable). Check out the two examples of <code class="dm ln lo lp lq b">mut</code> in the Rust code
above.</p>
<p id="2717" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">C is the opposite<em class="ht">
(“loose and relaxed”). </em>All C variables are mutable unless you declare the variable as <code
class="dm ln lo lp lq b">const</code>.</p>
<p id="d797" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Check “<a
href="https://doc.rust-lang.org/stable/book/"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><em class="ht">The Rust
Programming Language</em></a>” for details.</p>
<blockquote class="kw">
<div id="4f66" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Rust is Lean and Lightweight</p>
</div>
</blockquote>
<p id="1a4f" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">According to <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/logs/build-application.log#L628-L668"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">this actual build log</a> of our
combined Rust and Mynewt Sensor application, the entire compiled executable fits into 56 KB of ROM.
The compiled Rust application and Rust libraries occupy <strong class="gj gz">under 4 KB of
ROM</strong>. (Most of the ROM space was taken up by the ESP8266 and nRF24L01 drivers written in C.)
</p>
<p id="dda4" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">The <strong
class="gj gz">lightweight nature</strong> of Rust makes it an excellent replacement for embedded C
programming on devices with constrained resources. Like Blue Pill!</p>
<blockquote class="kw">
<div id="5aa3" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Rust Plays Nice with C</p>
</div>
</blockquote>
<p id="6f23" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">Rust was designed for <strong
class="gj gz">low-level systems programming</strong>, like for coding an operating system or web
browser (<a class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://web.archive.org/https://medium.com/mozilla-tech/a-quantum-leap-for-the-web-a3b7174b3c12">Mozilla
Firefox</a>). Just like C, Rust is used for bare-metal programming, so it makes sense for <strong
class="gj gz">Rust and C functions to be interoperable</strong> — We may call C functions from Rust,
and Rust functions from C. Even pass the same <code class="dm ln lo lp lq b">structs</code> from Rust
to C and back!</p>
<p id="03f1" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Well cover the Rust and C
interoperability in a while.</p>
<blockquote class="kw">
<div id="1341" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Rust is Smarter than C</p>
</div>
</blockquote>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure lr ls lt lu lv cz">
<div class="dl r dd">
<div class="ie r"><iframe
src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FeGHxTuRWswY%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DeGHxTuRWswY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FeGHxTuRWswY%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube"
allowfullscreen="" frameborder="0" height="300" width="400" title="Rust vs C coding"
class="cp t u dh ak" scrolling="auto"></iframe></div>
</div>
<figcaption><p><em>Visual Studio Code: Rust vs C coding
</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<p id="4b92" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Check out this comparison of Rust
vs C coding in Visual Studio Code. <em class="ht">Why is Rust better than C for coding embedded
applications?</em></p>
<p id="daae" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Remember that Rust supports Type
Inference. The Rust compiler keeps deducing all the types of the variables as we type. So Rust
provides more helpful <strong class="gj gz">code completion and error highlighting</strong> than C.
Rust <a
href="https://lupyuen.github.io/stm32bluepill-mynewt-sensor/rust/mylib/"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">generates documentation</a> for
our functions too.</p>
<p id="c8b2" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This is great for preventing
programming errors in Rust, especially for beginners. Often in embedded programs we make undocumented
assumptions and take shortcuts to make the programs run on tiny devices. With Type Inference, Rust can
<strong class="gj gz">warn new embedded developers about these traps.</strong></p>
<blockquote class="kw">
<div id="f7ea" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Rust is Safer than C</p>
</div>
</blockquote>
<p id="7042" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">Helping us to write <strong
class="gj gz">safer, crash-proof programs</strong> is a key feature of Rust, thats why we see <code
class="dm ln lo lp lq b">unsafe</code> keywords in the Rust code above. Well cover <code
class="dm ln lo lp lq b">unsafe</code> in a while…</p>
<blockquote class="kw">
<div id="9e1d" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">But…</p>
</div>
</blockquote>
<p id="02dc" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">Rust is <strong
class="gj gz">evolving rapidly</strong>, especially for embedded platforms like Blue Pill. A year
ago I wrote two tutorials on Rust embedded programming…</p>
<div class="if ig ih ii ij ik"><a rel="noopener"
href="https://web.archive.org/https://medium.com/coinmonks/coding-the-stm32-blue-pill-with-rust-and-visual-studio-code-b21615d8a20?source=post_page-----c86b119fe5f----------------------">
<section class="in cl cm ak ce n ar io ip iq ir is it iu iv iw ix iy iz ja jb jc">
<div class="jd n co p je jf">
<h2 class="bj jg jh bl ec">
<div class="di il fe ff im fh">Coding the STM32 Blue Pill with Rust and Visual Studio Code
</div>
</h2>
</div>
<div class="jk r">
<div class="lw r jm jn jo jk jp jq jr"></div>
</div>
</section>
</a></div>
<div class="if ig ih ii ij ik"><a rel="noopener"
href="https://web.archive.org/https://medium.com/coinmonks/running-rust-and-freertos-on-the-padi-iot-stamp-fb36c5ef4844?source=post_page-----c86b119fe5f----------------------">
<section class="in cl cm ak ce n ar io ip iq ir is it iu iv iw ix iy iz ja jb jc">
<div class="jd n co p je jf">
<h2 class="bj jg jh bl ec">
<div class="di il fe ff im fh">Running Rust and FreeRTOS on the PADI IoT Stamp</div>
</h2>
</div>
<div class="jk r">
<div class="lx r jm jn jo jk jp jq jr"></div>
</div>
</section>
</a></div>
<p id="aa17" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">…And they have already become
obsolete.</p>
<p id="0e43" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><em class="ht">Be very patient if
things dont work quite right in Rust.</em> I may not have the answer for some deep issues, but Im
confident that Rust maintainers will have the answer for us someday.</p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="af57" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Mixing Mynewt and Rust</h1>
<p id="b102" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">Built in C, Mynewt is a modern,
well-designed operating system for microcontrollers. Rust is a modern, smarter, safer programming
language for embedded systems. <em class="ht">How shall we enjoy the best of both worlds — Mynewt and
Rust? </em>I propose to…</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e5.png" /></p>
<figcaption><p><em>Layering Rust above Mynewt</em></p></figcaption>
</div>
<p id="1dc3" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1<strong class="gj gz">Leave
the Mynewt operating system untouched</strong>, in C. Same goes for Mynewt drivers and libraries,
since they were coded by experienced C programmers.</p>
<p id="ef35" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<strong class="gj gz">Expose
the popular Mynewt APIs </strong>through safe Rust interop libraries</p>
<p id="3f78" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3<strong class="gj gz">Allow
Rust applications to be hosted</strong> on Mynewt with these exposed APIs</p>
<p id="de5e" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">So new embedded developers (and
my IoT students) can start <strong class="gj gz">coding Mynewt applications in Rust, the smarter,
safer way</strong>. <em class="ht">No more crashing pointers. Yay!</em></p>
<p id="8979" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">To host a Rust application on
Mynewt, we need to be sure that C and Rust can really call each other seamlessly…</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e6.png" /></p>
<figcaption><p><em>Rust and C interoperability</em></p></figcaption>
</div>
<p id="768d" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1⃣ Rust must allow <strong
class="gj gz">importing of Mynewts C API.</strong> So Rust functions must be able to call C
functions: <br /><strong class="gj gz">Rust ⟶ C</strong></p>
<p id="1449" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2⃣ Rust must allow <strong
class="gj gz">callbacks from Mynewts C API</strong>. So Rust must allow its functions to be called
from C functions: <br /><strong class="gj gz">Rust ⟵ C</strong></p>
<p id="3055" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3⃣ Rust must allow <code
class="dm ln lo lp lq b"><strong class="gj gz">structs</strong></code><strong class="gj gz"> to be
passed from Rust to C and back</strong>: <br /><strong class="gj gz">Rust ⟵📦⟶ C</strong></p>
<p id="e1b7" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Fortunately, Rust fulfils all the
criteria above. For example, to import the following <a
href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_api.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Mynewt Sensor API </a>functions
into our Rust application…</p>
<p id="4020" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">int <a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_mgr_api.html#c.sensor_set_poll_rate_ms" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">sensor_set_poll_rate_ms</strong></a>(const char *<em class="ht"> devname</em>, uint32_t<em class="ht"> poll_rate</em>)</code>
</p>
<p id="a29b" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">struct <a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_api.html#c.sensor" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor</a>* <a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_mgr_api.html#c.sensor_mgr_find_next_bydevname" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">sensor_mgr_find_next_bydevname</strong></a>(const char *<em class="ht"> devname</em>, struct <a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_api.html#c.sensor" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor</a>*<em class="ht"> prev_cursor</em>)</code>
</p>
<p id="381c" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">int <a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_listener_api.html#c.sensor_register_listener" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">sensor_register_listener</strong></a>(struct <a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_api.html#c.sensor" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor</a> *<em class="ht"> sensor</em>, struct sensor_listener *<em class="ht"> listener</em>)</code>
</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm mc md me mf hr">
<p><script src="https://gist.github.com/lupyuen/4086dff9b067959c5e337d1c164eea96.js"></script></p>
<figcaption><p><em>Rust code to import Mynewt Sensor API. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L35-L62"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L35-L62</a>
</em></p></figcaption>
</div>
<p id="556a" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">…We just compile this Rust code
with our Rust application, then we can call the Mynewt functions as though they were Rust functions!
</p>
<p id="c970" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">💎 <em class="ht">How did we
derive the Rust import declarations above from the Mynewt C declarations? This is explained in the
section “Calling C from Rust and back” below.</em></p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="f557" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Is This Code Unsafe?</h1>
<p id="8911" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu"><em class="ht">Question</em>:
Whats wrong with this C function that calls the Mynewt API <code
class="dm ln lo lp lq b"><a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_listener_api.html#c.sensor_register_listener" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor_register_listener</a>()</code>?
</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/f934d3539f4b5e79e6b0c30633f73b92.js"></script></p>
</div>
<p id="dfc3" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><em class="ht">Answer</em>: <code
class="dm ln lo lp lq b">listener</code> is a variable created on the stack frame for <code
class="dm ln lo lp lq b">start_sensor_listener()</code>. When passed to <code
class="dm ln lo lp lq b">sensor_register_listener()</code>, the <code
class="dm ln lo lp lq b">listener</code> is appended directly to the global list of sensor
listeners, without copying.</p>
<p id="1ea7" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">When <code
class="dm ln lo lp lq b">start_sensor_listener()</code> returns, the stack frame is reused by other
functions and the <code class="dm ln lo lp lq b">listener</code> may contain garbage. When the sensor
is polled 10 seconds later, Mynewt fetches the garbled <code class="dm ln lo lp lq b">listener</code>
to call the listener function. Which results in a catastrophic device failure. <em class="ht">One IoT
Device Down!</em></p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e7.png" /></p>
<figcaption><p><em>Bewildering variable choices for the C
programmer</em></p></figcaption>
</div>
<p id="8b23" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This is one key reason why my IoT
students find C programming so hard…<em class="ht"> Every time we define a variable in C, we need to
pick wisely whether it should be a</em> 1<strong class="gj gz">Static Variable, 2⃣ Stack
Variable or 3⃣ Heap Variable.</strong></p>
<p id="e960" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Choosing the wrong one will have
<em class="ht">dire consequences</em>… thats why Rust calls this “<strong
class="gj gz">Unsafe</strong>” code.</p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="385c" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Unsafe Coding in Rust</h1>
<p id="c688" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">Rust doesnt prevent us from
writing unsafe code though — it requires us to flag the code as unsafe using the <code
class="dm ln lo lp lq b">unsafe</code> keyword. Otherwise the Rust compiler politely terminates and
refuses to generate any unsafe executables, for our safety.</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/dcd83bcb334cee1506315bb8ccdc747a.js"></script></p>
</div>
<p id="6f51" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">In the Rust code above we are
required to ring the alarm bells and flag as <code class="dm ln lo lp lq b">unsafe</code> the call to
<code
class="dm ln lo lp lq b"><a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_listener_api.html#c.sensor_register_listener" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor_register_listener</a>()</code>
because…</p>
<p id="3d0e" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1⃣ We are <strong
class="gj gz">passing the address</strong> of the <code class="dm ln lo lp lq b">listener</code> to
a function <code class="dm ln lo lp lq b">sensor_register_listener()</code>. Which may cause problems
if the <code class="dm ln lo lp lq b">listener</code> was allocated incorrectly (like on the stack).
<code class="dm ln lo lp lq b">&amp;mut listener</code> is equivalent to <code
class="dm ln lo lp lq b">&amp;listener</code> in C, just that it also declares to Rust that the
<code class="dm ln lo lp lq b">listener</code> contents may change (mutable).</p>
<p id="e237" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<code
class="dm ln lo lp lq b">sensor_register_listener()</code> is a C function defined by Mynewt, that
we have imported into Rust. <strong class="gj gz">All imported functions must be flagged as
</strong><code class="dm ln lo lp lq b"><strong class="gj gz">unsafe</strong></code> because, as we
know, C functions are capable of doing really weird things.</p>
<p id="08c0" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">But we dont really want <code
class="dm ln lo lp lq b">unsafe</code> alarm bells to ring in our heads every time we call the
Mynewt API. <em class="ht">Is there a safer way to silence the alarms?</em></p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="ba09" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Safer Coding in Rust</h1>
<p id="7fa9" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">The safer way to call <code
class="dm ln lo lp lq b">unsafe</code> Mynewt APIs in Rust is to <a
href="https://doc.rust-lang.org/1.6.0/book/ffi.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">create
wrapper functions</strong></a> to check the parameters and the return values.</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/d7955a8edfe11422424c0d6c37b7e22d.js"></script></p>
<figcaption><p><em>From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs</a>
</em></p></figcaption>
</div>
<p id="30e3" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Check this out… we can now
register a sensor listener without flagging as <code class="dm ln lo lp lq b">unsafe</code>! And the
listener was allocated on the stack!</p>
<p id="2453" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This is the <em
class="ht">perfect kind of API</em> that my IoT students should be calling, without fear of <em
class="ht">crashing their devices</em>. What is the magic that makes this happen?</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/c41e3fb94adeaaba69c986817792dc56.js"></script></p>
<figcaption><p><em><a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs</a>
</em></p></figcaption>
</div>
<p id="0404" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Heres how we created <code
class="dm ln lo lp lq b">register_listener()</code> as the safe version of the <code
class="dm ln lo lp lq b"><a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_listener_api.html#c.sensor_register_listener" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor_register_listener</a>()</code>
API in Mynewt… <code class="dm ln lo lp lq b">register_listener()</code> makes a <strong
class="gj gz">local static copy of the listener</strong>, and passes the local copy to the unsafe
<code class="dm ln lo lp lq b">sensor_register_listener()</code>. So even if the listener was created
on the stack, we are actually passing a static copy to the Mynewt API. Which wont crash the device.
</p>
<p id="620f" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">We have created a simple Rust
wrapper that reuses the same types used by the Mynewt API. (Thats why <code
class="dm ln lo lp lq b">register_listener()</code> returns an integer as the result code.) But Rust
APIs generally use a different convention to return results — <a
href="https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">the </a><code
class="dm ln lo lp lq b"><a href="https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Result</a></code><a
href="https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"> type</a>. Well cover this in the
next article.</p>
<blockquote class="js jt ju">
<p id="a898" class="gh gi ec ht gj b gk gl gm gn go gp gq gr gs gt gu"><em class="bk">💎 </em>This
implementation looks simplistic… what if we need more sensor listeners? But in reality our device
RAM is highly constrained and we should plan in advance how many sensor listeners we really need
(and set it as a <code class="dm ln lo lp lq b">#define</code>). Then we create an array of
listeners thats allocated by <code class="dm ln lo lp lq b">register_listener()</code>.</p>
<p id="bbc0" class="gh gi ec ht gj b gk gl gm gn go gp gq gr gs gt gu">What about allocating listeners
on the heap? That could be a good solution but Im not keen on using the heap on constrained devices
(because we never know when well run out of heap space). The <code
class="dm ln lo lp lq b"><a href="https://docs.rust-embedded.org/book/collections/" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">alloc</a></code><a
href="https://docs.rust-embedded.org/book/collections/"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"> heap allocator</a> needs to be
implemented for our Rust environment.</p>
</blockquote>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="99fb" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">The Typical Rust Build</h1>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e8.png" /></p>
<figcaption><p><em>Files involved in the Rust build</em></p></figcaption>
</div>
<p id="9c3d" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">To understand how we merged the
Rust build with Mynewt, lets look at the typical Rust build process.</p>
<p id="f8d6" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">The following files are present
in a standard Rust build. You can find them in your <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">stm32bluepill-mynewt-sensor</a></code>
folder too…</p>
<p id="9187" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1<code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/Cargo.toml" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">Cargo.toml</strong></a></code>:
Just like building a typical Rust application, in Mynewt we run the command <code
class="dm ln lo lp lq b">cargo build</code> to build our embedded Rust application.</p>
<p id="76ed" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">cargo</code> performs the build according to the settings file <code
class="dm ln lo lp lq b">Cargo.toml</code>. This file must be present at the root of the workspace
folder.</p>
<p id="41d0" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Well check the contents of <code
class="dm ln lo lp lq b">Cargo.toml</code> in a while.</p>
<p id="5e65" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/.cargo/config" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">.cargo/config</strong></a></code>:
Our Rust build is for an embedded platform: STM32 Blue Pill. The target platform is specified in this
file.</p>
<p id="9a91" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Well check the contents of <code
class="dm ln lo lp lq b"><strong class="gj gz">.cargo/config</strong></code> in a while.</p>
<p id="f7eb" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3<code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/src" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">src</strong></a></code>:
This folder contains the Rust source code. <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/lib.rs" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">lib.rs</strong></a></code>
is the main Rust module that pulls in the other Rust files for the build (via the <code
class="dm ln lo lp lq b">mod</code> declaration).</p>
<p id="7fc2" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">4<code
class="dm ln lo lp lq b"><strong class="gj gz">target/thumbv7m-none-eabi/debug</strong></code>: The
<code class="dm ln lo lp lq b">cargo build</code> command compiles the <code
class="dm ln lo lp lq b">src</code> files and generates in this <code
class="dm ln lo lp lq b">debug</code> folder the Rust executable or library (according to <code
class="dm ln lo lp lq b">Cargo.toml</code>).</p>
<div class="figure hb hc hd he hf cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<div class="figure du cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e9.png" /></p>
<figcaption><p><em>Compiled Rust code in <code
class="dm ln lo lp lq b">libmylib.rlib</code></em></p></figcaption>
</div>
<p id="dad5" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">In our build, <code
class="dm ln lo lp lq b">cargo</code> generates a library archive file <code
class="dm ln lo lp lq b">libmylib.rlib</code>. If we peek at the contents of the archive file
<br /> <code
class="dm ln lo lp lq b">arm-none-eabi-ar t target/thumbv7m-none-eabi/debug/libmylib.rlib</code><br />…well
see that it contains <code class="dm ln lo lp lq b">*.o</code> object files, the compiled Rust code.
</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e10.png" /></p>
</div>
<p id="4a06" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">But the files in this <code
class="dm ln lo lp lq b">debug</code> folder exclude the external Rust libraries called by our
application (like <code
class="dm ln lo lp lq b"><a href="https://crates.io/crates/cty" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">cty</a></code>
and <code
class="dm ln lo lp lq b"><a href="https://crates.io/crates/cstr_core" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">cstr_core</a></code>).
</p>
<p id="53d4" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">To include the external Rust
libraries for the Mynewt build, we need to look one level deeper: <code
class="dm ln lo lp lq b"><strong class="gj gz">debug/deps</strong></code></p>
<p id="3421" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This folder contains the compiled
<code class="dm ln lo lp lq b">*.rlib</code> archive files for our Rust application (<code
class="dm ln lo lp lq b">libmylib-*.rlib</code>) as well as external Rust libraries.</p>
<p id="fbb9" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">As well see later, all the <code
class="dm ln lo lp lq b">*.rlib</code> files in <code
class="dm ln lo lp lq b"><strong class="gj gz">debug/deps</strong></code> will be injected into the
Mynewt build.</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e11.png" /></p>
<figcaption><p><em>Typical Rust Build</em></p></figcaption>
</div>
<p id="70d3" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">5<strong class="gj gz">Rust
Core Library </strong><code
class="dm ln lo lp lq b"><a href="https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/libcore-for-low-level-rust.html" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">libcore</strong></a></code>:
Theres one important Rust library thats missing — the Rust Core Library <code
class="dm ln lo lp lq b">libcore</code>. This library contains the fundamental code needed to
implement the <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/logs/libcore.S"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">core Rust functions</a>: data
structures, math, panicking, text formatting, …</p>
<p id="5627" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">libcore</code> is automatically included during the <code
class="dm ln lo lp lq b">cargo</code> build if we use <code class="dm ln lo lp lq b">cargo</code> to
generate the executable. But here we are using Mynewt to generate the executable, so we need to add
<code class="dm ln lo lp lq b">libcore</code> ourselves.</p>
<p id="e182" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Where is <code
class="dm ln lo lp lq b">libcore</code> located? Its actually located together with the Rust
compiler (not with the <code class="dm ln lo lp lq b">cargo</code> installation). <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L91-L109"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Our build script</a> runs this
command to get the location…</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/b2ce2714a6849c7e992f1606468cbc80.js"></script></p>
<figcaption><p><em>Locating the Rust Core Library libcore. From
<a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L91-L109"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L91-L109</a>
</em></p></figcaption>
</div>
<p id="7220" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">On my Mac, <code
class="dm ln lo lp lq b">libcore</code> is located at <code
class="dm ln lo lp lq b">/Users/Luppy/.rustup/toolchains/nightly-20190522-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/libcore-e6b0ad9835323d10.rlib</code>
</p>
<p id="c6ac" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Note that <code
class="dm ln lo lp lq b">libcore</code> is specific to the target platform (Blue Pill is <code
class="dm ln lo lp lq b">thumbv7m-none-eabi</code>). Well link the <code
class="dm ln lo lp lq b">libcore</code> library in the Mynewt build.</p>
<blockquote class="js jt ju">
<p id="968c" class="gh gi ec ht gj b gk gl gm gn go gp gq gr gs gt gu"><em class="bk">💎 </em>The
disassembled code for our Rust application is <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/logs/libmylib-demangle.S"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">available here</a>. The
disassembled code for <code class="dm ln lo lp lq b">libcore</code> is <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/logs/libcore.S"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">available here</a>.</p>
</blockquote>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="a9a7" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Rust Build Settings</h1>
<p id="c42e" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">Lets look at the simple Rust
build settings for our project (which was inspired by <a
href="https://rust-embedded.github.io/book/start/qemu.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">this sample</a>)…</p>
<blockquote class="kw">
<div id="9f39" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo"><a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/Cargo.toml"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong
class="az">Cargo.toml</strong></a></p>
</div>
</blockquote>
<div class="figure lr ls lt lu lv cz dr hg cd hh hi hj hk hl ba hm mc md me mf hr">
<p><script src="https://gist.github.com/lupyuen/3d1afad3c9827e3e7eb9ba04f20877aa.js"></script></p>
<figcaption><p><em>Rust build settings. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/Cargo.toml"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/Cargo.toml</a>
</em></p></figcaption>
</div>
<p id="74f7" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Here we indicate to <code
class="dm ln lo lp lq b">cargo</code> that were generating a library <code
class="dm ln lo lp lq b">[lib]</code> (instead of an executable <code
class="dm ln lo lp lq b">[bin]</code>).</p>
<p id="acaf" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">To keep the ROM size small, we
have included only a few small libraries.</p>
<p id="a5f0" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This <code
class="dm ln lo lp lq b">Cargo.toml</code><strong class="gj gz"> </strong>produces the compiled Rust
library <code class="dm ln lo lp lq b">libmylib.rlib</code> that well link with Mynewt.</p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz mt mu paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="kw">
<div id="bef0" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo"><code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/.cargo/config" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="az">.cargo/config</strong></a></code>
</p>
</div>
</blockquote>
<div class="figure lr ls lt lu lv cz dr hg cd hh hi hj hk hl ba hm mc md me mf hr">
<p><script src="https://gist.github.com/lupyuen/c100373c4a862e363268ea970d4e8c61.js"></script></p>
<figcaption><p><em>Rust target settings. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/.cargo/config"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/.cargo/config</a>
</em></p></figcaption>
</div>
<p id="a604" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Here we select the target
platform for the Rust compiler.</p>
<p id="ce0d" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">STM32 Blue Pill runs on an Arm
Cortex-M3 processor (which is based on the <a
href="https://en.wikipedia.org/wiki/ARM_Cortex-M#Cortex-M3"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">ARMv7-M architecture</a>), so we
have chosen the target <code class="dm ln lo lp lq b">thumbv7m-none-eabi</code></p>
<p id="7f6b" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">cargo build</code> will then generate compiled code in <code
class="dm ln lo lp lq b">libmylib.rlib </code>that will run on our Blue Pill.</p>
<div class="figure hb hc hd he hf cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<p id="00e2" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">As we have seen, <strong
class="gj gz">we havent changed anything in the Rust </strong><code
class="dm ln lo lp lq b"><strong class="gj gz">cargo build</strong></code><strong class="gj gz">
process</strong>. We used the standard <code class="dm ln lo lp lq b">cargo build</code> command to
generate a Rust library <code class="dm ln lo lp lq b">libmylib.rlib</code> for our Rust application.
</p>
<p id="24e5" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">The integration of Rust with
Mynewt is actually done by <strong class="gj gz">our custom build script that injects the compiled
Rust files into the Mynewt build</strong>. Before going into the integration details, lets learn
about the Mynewt build…</p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<div class="figure hb hc hd he hf cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e12.png" /></p>
<figcaption><p><em>Typical Mynewt Build</em></p></figcaption>
</div>
<h1 id="01cf" class="ke kf ec bk bj jg kg mx ki my kk mz km na ko nb kq">The Typical Mynewt Build</h1>
<p id="9661" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">The normal Mynewt build command
<code class="dm ln lo lp lq b">newt build</code> compiles some C and assembly files from these
folders…</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e13.png" /></p>
<figcaption><p><em>Libraries generated by newt build</em></p></figcaption>
</div>
<p id="abf0" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1<code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/apps/my_sensor_app" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">apps/my_sensor_app</strong></a></code>:
Our custom C application for Mynewt</p>
<p id="fb5a" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/libs" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">libs</strong></a></code>:
Custom drivers (e.g. ESP8266) and libraries (e.g. Sensor Network) for Mynewt</p>
<p id="dff8" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3<code
class="dm ln lo lp lq b"><strong class="gj gz">repos</strong></code>: Mynewt OS source code</p>
<p id="a9a1" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">newt build</code> compiles each source module (e.g. <code
class="dm ln lo lp lq b">my_sensor_app</code>, <code class="dm ln lo lp lq b">esp8266</code>) into a
separate <code class="dm ln lo lp lq b">*.a</code> library (e.g. <code
class="dm ln lo lp lq b">apps_my_sensor_app.a</code>, <code
class="dm ln lo lp lq b">libs_esp8266.a</code>), located at <code
class="dm ln lo lp lq b">bin/targets/bluepill_my_sensor</code></p>
<p id="f3cb" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">newt build</code> links the <code class="dm ln lo lp lq b">*.a</code>
libraries together to create the Blue Pill executable image <code
class="dm ln lo lp lq b">/bin/targets/bluepill_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf</code>
</p>
<p id="c250" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This is the image that get
flashed into the Blue Pill ROM.</p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="cz ak">
<div class="figure hb hc hd he hf cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e14.png" /></p>
<figcaption><p><em>Combined build with Rust and Mynewt: <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L1"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="0623" class="ke kf ec bk bj jg kg mx ki my kk mz km na ko nb kq">Merging the Rust build with
Mynewt</h1>
<p id="a00c" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">To host a Rust application on
Mynewt, we just need to inject three pieces of compiled code into the Mynewt build…</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e15.png" /></p>
<figcaption><p><em>Overwriting libs_rust_app.a by the compiled
Rust application and libraries</em></p></figcaption>
</div>
<p id="6fb8" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1<strong
class="gj gz">Compiled Rust application</strong>: <code
class="dm ln lo lp lq b">libmylib.rlib</code></p>
<p id="ec2d" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<strong
class="gj gz">Compiled external Rust libraries</strong>: <code
class="dm ln lo lp lq b">target/thumbv7m-none-eabi/debug/deps/*.rlib.</code> This folder also
contains <code class="dm ln lo lp lq b">libmylib.rlib</code></p>
<p id="1973" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3<strong class="gj gz">Rust
Core Library </strong><code class="dm ln lo lp lq b"><strong class="gj gz">libcore</strong></code>:
<code
class="dm ln lo lp lq b">~/.rustup/toolchains/nightly-*/lib/rustlib/thumbv7m-none-eabi/lib/libcore-*.rlib</code>
</p>
<p id="57fb" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">To do that, we have a super build
script <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">scripts/build-app.sh</strong></a></code>
that runs the Rust <code class="dm ln lo lp lq b">cargo build</code> command and injects the above
files at these Mynewt build locations…</p>
<p id="c88e" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">1<strong class="gj gz">Rust
application and external Rust libraries</strong>: Copy and overwrite <code
class="dm ln lo lp lq b">bin/targets/bluepill_my_sensor/app/libs/rust_app/libs_rust_app.a</code></p>
<p id="8472" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<strong class="gj gz">Rust
</strong><code class="dm ln lo lp lq b"><strong class="gj gz">libcore</strong></code>: Copy and
overwrite <code
class="dm ln lo lp lq b">bin/targets/bluepill_my_sensor/app/libs/rust_libcore/libs_rust_libcore.a</code>
</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm hn ho hp hq hr paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e16.png" /></p>
<figcaption><p><em>rust_app and rust_libcore are empty stub
libraries</em></p></figcaption>
</div>
<p id="4f1a" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">What are <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/libs/rust_app" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">rust_app</strong></a></code>
and <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/libs/rust_libcore" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">rust_libcore</strong></a></code>?
These are custom stub libraries that we added to Mynewt at <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/libs/rust_app" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">libs/rust_app</a></code>
and <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/libs/rust_libcore" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">libs/rust_libcore</a></code>.
No meaningful code inside, just stubs.</p>
<p id="9cc2" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">But because we instructed Mynewt
to <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/apps/my_sensor_app/pkg.yml#L17-L21"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">include them as part of the Mynewt
build</a>, Mynewt compiles them and generates the tiny libraries <code
class="dm ln lo lp lq b">libs_rust_app.a</code> and <code
class="dm ln lo lp lq b">libs_rust_libcore.a</code></p>
<p id="0d39" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Which gives us the perfect
opportunity to substitute <code class="dm ln lo lp lq b">libs_rust_app.a</code> and <code
class="dm ln lo lp lq b">libs_rust_libcore.a</code> with our compiled Rust code.</p>
<p id="3e22" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Our super build script <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L77-L83"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">overwrites </a><code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L77-L83" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">libs_rust_app.a</a></code>
with the compiled Rust application and libraries, and <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L91-L109"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">overwrites </a><code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L91-L109" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">libs_rust_libcore.a</a></code>
with the Rust <code class="dm ln lo lp lq b">libcore</code> library. So when <code
class="dm ln lo lp lq b">newt build</code> links all the <code class="dm ln lo lp lq b">*.a</code>
libraries, the <strong class="gj gz">Rust code gets injected into </strong><code
class="dm ln lo lp lq b"><strong class="gj gz">my_sensor_app.elf</strong></code>, which will be
flashed into the Blue Pill ROM. Sneaky!</p>
<div class="figure hb hc hd he hf cz dr hg cd hh hi hj hk hl ba hm mc md me mf hr">
<p><script src="https://gist.github.com/lupyuen/4b95ee72af032bee9d371069b7556608.js"></script></p>
<figcaption><p><em>From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L51-L83"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L51-L83</a>
</em></p></figcaption>
</div>
<p id="c238" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">But how do we replace <code
class="dm ln lo lp lq b">libs_rust_app.a</code> by multiple <code
class="dm ln lo lp lq b">*.rlib</code> libraries: <code
class="dm ln lo lp lq b">libmylib.rlib</code> + <code class="dm ln lo lp lq b">libcty.rlib</code> +
<code class="dm ln lo lp lq b">libcstr_core.rlib</code> + ...?</p>
<p id="fa2a" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Our <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/scripts/build-app.sh#L51-L83"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">super build script</a> extracts
the <code class="dm ln lo lp lq b">*.o</code> object files from every <code
class="dm ln lo lp lq b">*.rlib</code> file and archives them into a single <code
class="dm ln lo lp lq b">rustlib.a</code> library.</p>
<p id="fceb" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Thats how we create the Mynewt
ROM for Blue Pill that includes the Rust application and libraries!</p>
<div class="figure hb hc hd he hf cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<p id="6338" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This video explains the combined
Rust and Mynewt build…</p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz">
<div class="dl r dd">
<div class="ie r"><iframe
src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQTTqRlsiBfk%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQTTqRlsiBfk&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQTTqRlsiBfk%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube"
allowfullscreen="" frameborder="0" height="300" width="400"
title="Hosting Rust Applications on Apache Mynewt - Build" class="cp t u dh ak"
scrolling="auto"></iframe></div>
</div>
<figcaption><p><em>Building the combined Rust and Mynewt code
</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="js jt ju">
<p id="83a9" class="gh gi ec ht gj b gk gl gm gn go gp gq gr gs gt gu"><em class="bk">💎 </em>The
complete Rust and Mynewt build log is <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/logs/build-application.log#L1"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">available here</a>. The
disassembled code for our Mynewt ROM image is <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/logs/my_sensor_app.elf.lst"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">available here</a>.</p>
</blockquote>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="48c2" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Installation and Configuration
</h1>
<p id="b392" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">If you have the <a
href="http://wiki.stm32duino.com/index.php?title=Blue_Pill"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">STM32 Blue Pill</a> or <a
class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/super-blue-pill-like-stm32-blue-pill-but-better">Super
Blue Pill</a> and you wish to install and configure the Rust and Mynewt demo code, <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/README.md"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">follow the instructions here</a>.
The steps are quite lengthy and you may run into hiccups, so I dont recommend this if youre new to
embedded development.</p>
<p id="878e" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Make sure that youre using the
<code class="dm ln lo lp lq b">rust</code> branch of the code, not the <code
class="dm ln lo lp lq b">master</code> branch (that was used in previous articles)…</p>
<p id="3b88" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/<strong class="gj gz">rust</strong></a></code>
</p>
<p id="64a9" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Verify that the <code
class="dm ln lo lp lq b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/README.md" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">README.md</a></code>
says…</p>
<pre
class="hb hc hd he hf nj nk nl"><span id="8033" class="nm kf ec bk lq b ds nn no r np">Note: This is the rust branch that contains a Rust application hosted on Mynewt</span></pre>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="afdc" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Conclusion</h1>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz">
<div class="dl r dd">
<div class="ie r"><iframe
src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FPj3pl6GaztU%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DPj3pl6GaztU&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FPj3pl6GaztU%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube"
allowfullscreen="" frameborder="0" height="300" width="400"
title="Hosting Rust Applications on Apache Mynewt - Run" class="cp t u dh ak"
scrolling="auto"></iframe></div>
</div>
<figcaption><p><em>Running our Rust application on Mynewt
</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<p id="51c3" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Heres a video of our Rust
application, hosted on Mynewt, running on an actual Blue Pill. It works as expected: Reading the Blue
Pills internal temperature sensor every 10 seconds and displaying the results— <em
class="ht">Yay!</em></p>
<p id="683e" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">With some simple build
integration, we have proven that its indeed possible to <strong class="gj gz">host Rust applications
on Mynewt</strong> (and probably other embedded operating systems too). And it requires <strong
class="gj gz">very little RAM and ROM to support embedded Rust.</strong></p>
<p id="12b7" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Perhaps the bigger challenge is
to <strong class="gj gz">design a Rust API for Mynewt thats safe and easy to use.</strong></p>
<p id="a0cf" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">In the meantime, what we have
created is probably sufficient for new embedded developers (and my students) to <strong
class="gj gz">create IoT devices in Rust and Mynewt without fear of memory corruption</strong>. <em
class="ht">Saving the world from unsafe embedded C programming… one microstep at a time!</em></p>
<p id="e064" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Check out the latest article on
Visual Embedded Rust…</p>
<div class="if ig ih ii ij ik"><a rel="noopener"
href="https://lupyuen.github.io/articles/visual-embedded-rust-programming-with-visual-studio-code">
<section class="in cl cm ak ce n ar io ip iq ir is it iu iv iw ix iy iz ja jb jc">
<div class="jd n co p je jf">
<h2 class="bj jg jh bl ec">
<div class="di il fe ff im fh">Visual Embedded Rust Programming with Visual Studio Code</div>
</h2>
</div>
<div class="jk r">
<div class="nq r jm jn jo jk jp jq jr"></div>
</div>
</section>
</a></div>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="68b3" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq">Further Reading for Embedded
Rust</h1>
<p id="2b19" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">1<strong class="gj gz"><em
class="ht"></em></strong><a
href="https://rust-embedded.github.io/book/"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz"><em
class="ht">The Embedded Rust Book</em></strong></a><strong class="gj gz"><em
class="ht"></em></strong> was highly informative for embedded Rust programming on Arm Cortex M3
</p>
<p id="5798" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">2<em class="ht"></em><a
href="https://os.phil-opp.com/" class="at cg gv gw gx gy"
target="_blank" rel="noopener nofollow"><strong class="gj gz"><em class="ht">Writing an OS in
Rust</em></strong></a><strong class="gj gz"></strong>has plenty of tips for coding operating
systems in Rust</p>
<p id="d525" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">3<code
class="dm ln lo lp lq b"><a href="https://github.com/hashmismatch/freertos.rs" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow"><strong class="gj gz">freertos.rs</strong></a></code>
(Rust wrapper for <a href="https://www.freertos.org/"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">FreeRTOS</a>) was the original
inspiration for creating a safe Rust wrapper around an embedded operating system</p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="js jt ju">
<p id="634a" class="gh gi ec ht gj b gk gl gm gn go gp gq gr gs gt gu"><em class="bk">💎 </em>The
following Advanced Topic sections are for advanced developers. If youre new to embedded
programming, you may stop here.</p>
</blockquote>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="34b5" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq"><em class="nr">💎 </em>Advanced
Topic: Calling C from Rust and back</h1>
<p id="55a6" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">In this section we go into detail
to see how C functions and <code class="dm ln lo lp lq b">structs</code> are imported into Rust, and
how to export Rust functions to C.</p>
<blockquote class="kw">
<div id="494a" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Import C Functions into Rust: Rust ⟶ C</p>
</div>
</blockquote>
<p id="1ebd" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">For our demo Rust application, we
shall be calling the <a
href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_api.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Mynewt Sensor API</a> to configure
the onboard temperature sensor to be polled every 10 seconds. After polling the sensor, Mynewt should
call a Listener Function (defined in Rust) to display the result.</p>
<p id="dfbc" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">To import the Mynewt Sensor API
functions into our Rust application, we should include this code…</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/4086dff9b067959c5e337d1c164eea96.js"></script></p>
<figcaption><p><em>Rust code to import Mynewt Sensor API. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L35-L62"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L35-L62</a>
</em></p></figcaption>
</div>
<p id="4a5c" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">How did we derive the Rust import
declarations above? Lets look at the C declarations for the three Mynewt functions (right column) and
see how they map to the Rust import declaration (left column)…</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/b90f0bba75b16321a2fe3eb0e046bd09.js"></script></p>
<figcaption><p><em>Rust vs C declarations for Mynewt Sensor API.
From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L35-L62"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L35-L62</a>
and <a
href="https://github.com/apache/mynewt-core/blob/master/hw/sensor/include/sensor/sensor.h#L278-L296"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/apache/mynewt-core/blob/master/hw/sensor/include/sensor/sensor.h</a>
</em></p></figcaption>
</div>
<ul class="">
<li id="69c8" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu ns nt nu"><code
class="dm ln lo lp lq b">#[link(name = “hw_sensor”)]</code> declares to Rust that the C functions
to be imported will be located in the compiled C library archive <code
class="dm ln lo lp lq b">hw_sensor.a</code> (which will be generated by the Mynewt build)</li>
<li id="47cf" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">i32</code> in Rust is equivalent to <code
class="dm ln lo lp lq b">int</code> in C (signed 32-bit integer)</li>
<li id="9360" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">u32</code> in Rust is equivalent to <code
class="dm ln lo lp lq b">uint32_t</code> in C (unsigned 32-bit integer)</li>
<li id="b689" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">u8</code> in Rust is equivalent to <code
class="dm ln lo lp lq b">uint8_t</code> in C (unsigned byte)</li>
<li id="835b" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">*const u8</code> in Rust is equivalent to <code
class="dm ln lo lp lq b">const uint8_t *</code> in C. We use this to pass <code
class="dm ln lo lp lq b">devname</code> because <code
class="dm ln lo lp lq b">const uint8_t *</code> has the same size as <code
class="dm ln lo lp lq b">const char *</code></li>
<li id="1d4c" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">SensorListener</code> is a <code class="dm ln lo lp lq b">struct</code>
we imported from Mynewt to pass the listener info from Rust to C (to be explained in a while)</li>
<li id="1368" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">*mut SensorListener</code> in Rust is equivalent to <code
class="dm ln lo lp lq b">struct SensorListener *</code> in C</li>
<li id="19e8" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu">Why <code
class="dm ln lo lp lq b">*mut SensorListener</code> and not <code
class="dm ln lo lp lq b">*const SensorListener</code>? Because <code
class="dm ln lo lp lq b">SensorListener</code> will be stored and updated by Mynewt.</li>
<li id="752f" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu">We define <code
class="dm ln lo lp lq b">SensorPtr</code> as follows…</li>
</ul>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/bfe4f6d64c5039bf81d1d20c9f9ad0b0.js"></script></p>
<figcaption><p><em>Rust code to import Mynewt Sensor API Types.
From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L101-L120"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L101-L120</a>
</em></p></figcaption>
</div>
<ul class="">
<li id="9b5f" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu ns nt nu"><code
class="dm ln lo lp lq b">SensorPtr</code> represents a pointer to a Mynewt <code
class="dm ln lo lp lq b">sensor</code> <code class="dm ln lo lp lq b">struct</code>. Since we are
just passing the pointer through from Rust to Mynewt, without touching its contents, we declare
<code class="dm ln lo lp lq b">SensorPtr</code> as a <code class="dm ln lo lp lq b">void *</code>
type, which is <code class="dm ln lo lp lq b">*const CVoid</code> in Rust.</li>
<li id="a9fe" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">CVoid</code> is our Rust equivalent of <code
class="dm ln lo lp lq b">void</code> in C</li>
</ul>
<div class="figure hb hc hd he hf cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz mt mu paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="kw">
<div id="d786" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Import C Structs into Rust: Rust ⟵📦⟶ C</p>
</div>
</blockquote>
<div class="figure lr ls lt lu lv cz">
<p><script src="https://gist.github.com/lupyuen/6a55995681fe88fe99639d808aa3dae1.js"></script></p>
<figcaption><p><em>Rust code to import Mynewt SensorListener
struct. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L63-L82"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L63-L82</a>
</em></p></figcaption>
</div>
<p id="31a0" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">The Rust code above should be
included into our Rust application so that the <code class="dm ln lo lp lq b">SensorListener</code>
<code class="dm ln lo lp lq b">struct</code> may be passed through <code
class="dm ln lo lp lq b"><a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_listener_api.html#c.sensor_register_listener" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor_register_listener</a>()</code>.
To understand how the Rust import declaration was derived, lets compare the Rust import declaration
with the Mynewt declaration in C…</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/ce3b97055a6f25a2efe1c045163ac33d.js"></script></p>
<figcaption><p><em>Rust vs C declarations for Mynewt
SensorListener struct. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L63-L82"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L63-L82</a>
and <a
href="https://github.com/apache/mynewt-core/blob/master/hw/sensor/include/sensor/sensor.h#L278-L296"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/apache/mynewt-core/blob/master/hw/sensor/include/sensor/sensor.h#L278-L296</a>
</em></p></figcaption>
</div>
<ul class="">
<li id="0936" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu ns nt nu"><code
class="dm ln lo lp lq b">#[repr(C)]</code> tells Rust that this <code
class="dm ln lo lp lq b">struct</code> is used by both Rust and C functions. The <code
class="dm ln lo lp lq b">struct</code> memory layout shall be fixed according to the C convention.
</li>
<li id="5656" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">#[repr(C, packed)]</code> is used for C <code
class="dm ln lo lp lq b">structs</code> that are <code class="dm ln lo lp lq b">packed</code></li>
<li id="aa74" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">SensorType</code>, <code class="dm ln lo lp lq b">SensorArg</code>, <code
class="dm ln lo lp lq b">SensorDataFunc</code> are defined in the Sensor Types Definition code
above</li>
<li id="f67a" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">SensorDataFunc</code> is a pointer to a callback function in Rust that
Mynewt will call from a C function. This is explained below.</li>
<li id="79e3" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu ns nt nu"><code
class="dm ln lo lp lq b">sl_next</code> is defined as <code class="dm ln lo lp lq b">u32</code>
(32-bit unsigned integer) because we should initialise the field to <code
class="dm ln lo lp lq b">0</code> in our Rust code. <code class="dm ln lo lp lq b">sl_next</code>
is updated by Mynewt to store the pointer to the next <code
class="dm ln lo lp lq b">SensorListener</code> in the linked list</li>
</ul>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz mt mu paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="kw">
<div id="1864" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Export Rust Functions to C (Callback): Rust ⟵ C</p>
</div>
</blockquote>
<p id="a1cd" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">We have seen how C functions and
structs may be imported into Rust. Now lets see how Rust functions may be called from C.</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/4b0728052ee94db3c0b83188fb1ba382.js"></script></p>
<figcaption><p><em>From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs#L20-L56"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs#L20-L56</a>
</em></p></figcaption>
</div>
<p id="12f8" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Recall that <code
class="dm ln lo lp lq b"><a href="https://mynewt.apache.org/latest/os/modules/sensor_framework/sensor_listener_api.html#c.sensor_register_listener" class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">sensor_register_listener</a>()</code>
registers a Listener Function (defined in Rust) that will be called by Mynewt when the temperature
sensor has been polled. <code class="dm ln lo lp lq b">sensor_register_listener()</code> accepts a
<code class="dm ln lo lp lq b">SensorListener</code> <code class="dm ln lo lp lq b">struct</code>
(named <code class="dm ln lo lp lq b">LISTENER</code> here) as a parameter. The <code
class="dm ln lo lp lq b">SensorListener</code> <code class="dm ln lo lp lq b">struct</code> includes
<code class="dm ln lo lp lq b">sl_func</code>, the pointer to the Listener Function.</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/b5aeea3ea4d702d9200a7919f4c9e534.js"></script></p>
<figcaption><p><em>From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs#L41-L48"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs#L41-L48</a>
</em></p></figcaption>
</div>
<p id="d4de" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Here we pass the Rust function
<code class="dm ln lo lp lq b">read_temperature()</code> as the Listener Function.</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/7bd0b8a844fa12d5860e4585d2566ed5.js"></script></p>
<figcaption><p><em><a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs#L62-L108"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/listen_sensor.rs#L62-L108</a>
</em></p></figcaption>
</div>
<p id="7cc4" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu"><code
class="dm ln lo lp lq b">read_temperature()</code> is declared as <code
class="dm ln lo lp lq b">extern</code> so that it may be called from C as a callback function
(instead of calling by function name). Note that <code
class="dm ln lo lp lq b">read_temperature()</code> has the same function signature as <code
class="dm ln lo lp lq b">sl_func</code> (which has type <code
class="dm ln lo lp lq b">SensorDataFunc</code>)…</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/d2494d75118353e9910d629f8467ade8.js"></script></p>
<figcaption><p><em>From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L63-L109"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/sensor.rs#L63-L109</a>
</em></p></figcaption>
</div>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="hw hx hy hz ia ib ag ic ah id aj ak">
<div class="figure hb hc hd he hf cz mt mu paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<blockquote class="kw">
<div id="c159" class="kx ky kz bk ed b la lb lc ld le lf gu">
<p class="ed b lg lh bo">Export Rust Functions to C (Call By Name): Rust ⟵ C</p>
</div>
</blockquote>
<p id="dc5c" class="gh gi ec bk gj b gk li gm lj go lk gq ll gs lm gu">Previously we have seen how C may
call a Rust function <em class="ht">via callback</em> (i.e. the Rust function is passed to C as a
pointer). What if our C function wishes to call a Rust function <em class="ht">by its function
name?</em></p>
<p id="d304" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Normally the Rust compiler
converts Rust function names into a “mangled” format that includes the function signature. So the
<code class="dm ln lo lp lq b">read_temperature()</code> function would be compiled and renamed as:
<code class="dm ln lo lp lq b">_ZN5mylib13listen_sensor16read_temperature17h318673dbfba97d4bE()</code>
</p>
<p id="6b12" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">But if we are calling <code
class="dm ln lo lp lq b">read_temperature()</code> from C, this becomes a problem because the
function name has changed. To prevent the mangling of the Rust function name, use the <code
class="dm ln lo lp lq b">#[no_mangle]</code> directive like this:</p>
<div class="figure hb hc hd he hf cz">
<p><script src="https://gist.github.com/lupyuen/e8cce792e9259b7e680619a06fe6040a.js"></script></p>
<figcaption><p><em>From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/lib.rs#L21-L48"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/rust/src/lib.rs#L21-L48</a>
</em></p></figcaption>
</div>
<p id="1dfa" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">So in the above code, the
function <code class="dm ln lo lp lq b">main()</code> will not be renamed by the Rust compiler. The
<code class="dm ln lo lp lq b">pub extern “C”</code> directive tells the Rust compiler to export the
Rust function <code class="dm ln lo lp lq b">main()</code> to C functions.</p>
<p id="66c1" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">From a C function, we may now
call the function by its Rust name, <code class="dm ln lo lp lq b">main()</code>. In fact thats how
Mynewt starts our Rust application.</p>
<p id="d404" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">This interoperability of Rust and
C is known as the <strong class="gj gz">Foreign Function Interface</strong>. <a
href="https://doc.rust-lang.org/1.6.0/book/ffi.html"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Read the details here</a>.</p>
</div>
</div>
</section>
<hr class="jv dy jw jx jy dv jz ka kb kc kd" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="074d" class="ke kf ec bk bj jg kg kh ki kj kk kl km kn ko kp kq"><em class="nr">💎 </em>Advanced
Topic: Enhancements</h1>
<p id="c64c" class="gh gi ec bk gj b gk kr gm ks go kt gq ku gs kv gu">Although we have done a lot in
this article, we havent provided a <strong class="gj gz">comprehensive and maintainable
environment</strong> in Mynewt for hosting all kinds of Embedded Rust applications.</p>
<p id="d143" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu">Here are my suggestions for
<strong class="gj gz">improving the integration</strong> of Rust with Mynewt. <em class="ht">If youre
keen to work on the integration of Rust with Mynewt, lemme know!</em></p>
<ol class="">
<li id="68eb" class="gh gi ec bk gj b gk gl gm gn go gp gq gr gs gt gu oa nt nu">Rust folders should
<strong class="gj gz">follow the Mynewt folder structure</strong>:<br />Move Rust source files from
<code class="dm ln lo lp lq b">src</code> to <code
class="dm ln lo lp lq b">apps/my_sensor_app/src</code><br />Generate compiled Rust object files in
<code class="dm ln lo lp lq b">bin</code> instead of <code class="dm ln lo lp lq b">target</code>
</li>
<li id="08e7" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu"><strong
class="gj gz">Auto-generate the Rust code for importing Mynewt C functions and </strong><code
class="dm ln lo lp lq b"><strong class="gj gz">structs</strong></code>. <code
class="dm ln lo lp lq b">bindgen</code> is a tool that we could use to generate the Rust import
declarations by feeding in the Mynewt header files. <a class="at cg gv gw gx gy" target="_blank"
rel="noopener"
href="https://lupyuen.github.io/articles/safer-simpler-embedded-rust-with-apache-mynewt-on-stm32-blue-pill">Already
done here</a>.</li>
<li id="fd1b" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu">Create <strong
class="gj gz">safe Rust wrappers for the complete Mynewt API</strong>. We may need lots of
thinking to create a safe Rust API for Mynewt thats easy to use and error-proof. <a
class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/safer-simpler-embedded-rust-with-apache-mynewt-on-stm32-blue-pill">Already
done here</a>.</li>
<li id="36ea" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu">Rust wrappers for
Mynewt should return <code
class="dm ln lo lp lq b"><strong class="gj gz">Result</strong></code><strong class="gj gz"> type
instead of integers</strong> (thanks to <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/issues/3"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Marcel Hellwig</a>). <a
class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/safer-simpler-embedded-rust-with-apache-mynewt-on-stm32-blue-pill">Already
done here</a>.</li>
<li id="b578" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu"><strong
class="gj gz">CoAP (JSON and CBOR) API</strong> for Rust, similar to the network-agnostic <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/rust/libs/sensor_network"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">Sensor Network API</a>. <a
class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/safer-simpler-embedded-rust-with-apache-mynewt-on-stm32-blue-pill">Already
done here</a>.</li>
<li id="7cda" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu">Allow Mynewt <strong
class="gj gz">drivers and libraries to be created with Rust</strong></li>
<li id="0a9a" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu"><strong
class="gj gz">Support other microcontroller platforms</strong> besides Blue Pill</li>
<li id="9fcd" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu">Support <strong
class="gj gz">text formatting and heap allocator</strong> in Rust. While keeping RAM and ROM usage
low.</li>
<li id="e9c8" class="gh gi ec bk gj b gk nv gm nw go nx gq ny gs nz gu oa nt nu">Keep <strong
class="gj gz">monitoring for RAM and ROM bloat</strong> as we implement enhancements. For example,
the ROM size dropped from 73 KB to 55 KB after removing the <code
class="dm ln lo lp lq b">unwrap() / panic()</code> error checking. Check the memory map <a
href="https://docs.google.com/spreadsheets/d/1yep-QaAoaxrBz8tpYZ2TMo1xWNDaKCaFCGS-kON1Rt0/edit#gid=381366828&amp;fvid=1643056349"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">before</a> and <a
href="https://docs.google.com/spreadsheets/d/1tWbH8MMZE5_2NsaWs1qNHDC6V8iR8Hx-Le95gHS69fo/edit#gid=381366828&amp;fvid=1643056349"
class="at cg gv gw gx gy" target="_blank" rel="noopener nofollow">after</a>. <em
class="ht">(</em><a class="at cg gv gw gx gy" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/stm32-blue-pill-analyse-and-optimise-your-ram-and-rom"><em
class="ht">Learn more about memory maps</em></a><em class="ht">)</em></li>
</ol>
</div>
</div>
<div class="cz ak">
<div class="figure hb hc hd he hf cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/e17.png" /></p>
<figcaption><p><em>ROM usage before and after removing <code
class="dm ln lo lp lq b">unwrap() / panic()</code> error checking. From <a
href="https://docs.google.com/spreadsheets/d/1yep-QaAoaxrBz8tpYZ2TMo1xWNDaKCaFCGS-kON1Rt0/edit#gid=381366828"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1yep-QaAoaxrBz8tpYZ2TMo1xWNDaKCaFCGS-kON1Rt0/edit#gid=381366828</a>
and <a
href="https://docs.google.com/spreadsheets/d/1tWbH8MMZE5_2NsaWs1qNHDC6V8iR8Hx-Le95gHS69fo/edit#gid=381366828&amp;fvid=1643056349"
class="at cg gv gw gx gy" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1tWbH8MMZE5_2NsaWs1qNHDC6V8iR8Hx-Le95gHS69fo/edit#gid=381366828&amp;fvid=1643056349</a>
</em></p></figcaption>
</div>
</div>
</section>
</div>
</article>
</div>
</div>
<ul>
<li>
<p><a href="https://github.com/sponsors/lupyuen">Sponsor me a coffee</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io">Check out my articles</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io/rss.xml">RSS Feed</a></p>
</li>
</ul>
</body>
</html>
<!--
FILE ARCHIVED ON 19:42:25 Dec 04, 2019 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 01:29:47 Feb 23, 2021.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->
<!--
playback timings (ms):
esindex: 0.013
captures_list: 166.055
load_resource: 90.608
RedisCDXSource: 1.398
LoadShardBlock: 129.449 (3)
exclusion.robots: 0.41
PetaboxLoader3.datanode: 135.395 (4)
exclusion.robots.policy: 0.394
CDXLines.iter: 30.061 (3)
PetaboxLoader3.resolve: 48.522
-->