blob: e2b349d90460298998da11aef749c4d7417ff391 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rust Blinky application &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../index.html"/>
<link rel="up" title="Other" href="other.html"/>
<link rel="next" title="Third-party Resources" href="../../external_links.html"/>
<link rel="prev" title="Charge control on PineTime" href="chg_ctrl_on_pinetime.html"/>
<script src="../../_static/js/modernizr.min.js"></script>
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../_static/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released September 7, 2023)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li class="important">
<a href="/quick-start/">Quick Start</a>
</li>
<li>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../tutorials.html">Tutorials</a> /
<a href="other.html">Other</a> /
Rust Blinky application
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-documentation/edit/master/docs/tutorials/other/rust.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_11_0" selected="selected" >
Version: 1.11.0
</option>
<option value="/v1_10_0" >
Version: 1.10.0
</option>
<option value="/v1_9_0" >
Version: 1.9.0
</option>
<option value="/v1_8_0" >
Version: 1.8.0
</option>
<option value="/v1_7_0" >
Version: 1.7.0
</option>
<option value="/v1_6_0" >
Version: 1.6.0
</option>
<option value="/v1_5_0" >
Version: 1.5.0
</option>
<option value="/v1_4_0" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../concepts.html">Concepts</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../tutorials.html">Tutorials</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../blinky/blinky.html">Project Blinky</a></li>
<li class="toctree-l2"><a class="reference internal" href="../repo/add_repos.html">Working with repositories</a></li>
<li class="toctree-l2"><a class="reference internal" href="../slinky/project-slinky.html">Project Slinky for Remote Comms</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ble/ble.html">Bluetooth Low Energy</a></li>
<li class="toctree-l2"><a class="reference internal" href="../lora/lorawanapp.html">LoRa</a></li>
<li class="toctree-l2"><a class="reference internal" href="../os_fundamentals/os_fundamentals.html">OS Fundamentals</a></li>
<li class="toctree-l2"><a class="reference internal" href="../devmgmt/devmgmt.html">Remote Device Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sensors/sensors.html">Sensors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tooling/tooling.html">Tooling</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="other.html">Other</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="codesize.html">How to reduce Application Code Size</a></li>
<li class="toctree-l3"><a class="reference internal" href="unit_test.html">Write a Test Suite for a Package</a></li>
<li class="toctree-l3"><a class="reference internal" href="wi-fi_on_arduino.html">Enable Wi-Fi on Arduino MKR1000</a></li>
<li class="toctree-l3"><a class="reference internal" href="chg_ctrl_on_pinetime.html">Charge control on PineTime</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Rust Blinky application</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../os/os_user_guide.html">OS User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="alert alert-warning">
<p>
Version 1.11.0 is not the most recent version of the
Apache Mynewt documentation. Click <a href="/latest">here</a> to
read the latest version.
</p>
</div>
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="rust-blinky-application">
<h1>Rust Blinky application<a class="headerlink" href="#rust-blinky-application" title="Permalink to this headline"></a></h1>
<p>This tutorial shows you how to convert the Blinky application to Rust. This includes
integrating Cargo into newt builder.</p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#prerequisites" id="id1">Prerequisites</a></p></li>
<li><p><a class="reference internal" href="#initialize-rust" id="id2">Initialize Rust</a></p></li>
<li><p><a class="reference internal" href="#setup-the-basics" id="id3">Setup the basics</a></p></li>
<li><p><a class="reference internal" href="#converting-sysinit" id="id4">Converting sysinit</a></p></li>
<li><p><a class="reference internal" href="#doing-gpio-and-delays" id="id5">Doing GPIO and delays</a></p></li>
<li><p><a class="reference internal" href="#cargo-build" id="id6">Cargo build</a></p></li>
<li><p><a class="reference internal" href="#newt-integration" id="id7">Newt integration</a></p></li>
<li><p><a class="reference internal" href="#conclusion" id="id8">Conclusion</a></p></li>
</ul>
</div>
<div class="section" id="prerequisites">
<h2><a class="toc-backref" href="#id1">Prerequisites</a><a class="headerlink" href="#prerequisites" title="Permalink to this headline"></a></h2>
<p>Ensure that you meet the following prerequisites before continuing with
this tutorial:</p>
<ul class="simple">
<li><p>You have basic knowledge about <a class="reference external" href="https://doc.rust-lang.org/stable/book/">Rust</a>.</p></li>
<li><p>You have basic knowledge about <a class="reference external" href="https://rust-embedded.github.io/book/">Rust Embedded</a>.</p></li>
<li><p>You have rust installed using <a class="reference external" href="https://doc.rust-lang.org/stable/book/ch01-01-installation.html">rustup</a>.</p></li>
<li><p>Follow <a class="reference internal" href="../blinky/blinky.html"><span class="doc">Blinky tutorial</span></a> to create a
project with a basic application. You will extend that application in this
tutorial.</p></li>
</ul>
</div>
<div class="section" id="initialize-rust">
<h2><a class="toc-backref" href="#id2">Initialize Rust</a><a class="headerlink" href="#initialize-rust" title="Permalink to this headline"></a></h2>
<p>The first step is to initialize a crate for developing your application in. You
can do this in the existing <cite>blinky</cite> directory.</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>cargo<span class="w"> </span>init<span class="w"> </span>--lib<span class="w"> </span>apps/blinky
<span class="go">Created library package</span>
<span class="gp">$ </span>tree<span class="w"> </span>apps/blinky
<span class="go">apps/blinky</span>
<span class="go">├── Cargo.toml</span>
<span class="go">├── pkg.yml</span>
<span class="go">└── src</span>
<span class="go"> ├── lib.rs</span>
<span class="go"> └── main.c</span>
<span class="go">1 directory, 4 files</span>
</pre></div>
</div>
<p>This creates a Cargo.toml configuration file and src/lib.rs. We will use these
files to place our application in. You may notice that the Rust application is
not configured as an app, but as an lib. This is needed later to allow linking
to the rest of mynewt.</p>
</div>
<div class="section" id="setup-the-basics">
<h2><a class="toc-backref" href="#id3">Setup the basics</a><a class="headerlink" href="#setup-the-basics" title="Permalink to this headline"></a></h2>
<p>Now we want to actually convert the application code to Rust. Let’s open <cite>src/lib.rs</cite>
and remove the contents. Then start with some basic setup:</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="cp">#![no_std]</span>
<span class="k">extern</span><span class="w"> </span><span class="k">crate</span><span class="w"> </span><span class="n">panic_halt</span><span class="p">;</span>
<span class="cp">#[no_mangle]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The first line states that this program doesn’t use the standard library. This
means that only the core library is linked to the program. See
<a class="reference external" href="https://rust-embedded.github.io/book/intro/no-std.html">rust-embedded book</a>
for more information.</p>
<p>The next line specifies the panic handler. Panicking is an important feature of
Rust. To ease this tutorial we choose to halt the processor on panic. See
<a class="reference external" href="https://docs.rust-embedded.org/book/start/panicking.html">rust-embedded book</a>
for alternatives.</p>
<p>Then we have the <code class="docutils literal notranslate"><span class="pre">main</span></code> function. It contains a endless loop as it should never
return, but doesn’t do anything useful yet. It is marked <code class="docutils literal notranslate"><span class="pre">no_mangle</span></code> and <code class="docutils literal notranslate"><span class="pre">extern</span> <span class="pre">&quot;C&quot;</span></code>
to make sure it can be called from the mynewt C code.</p>
</div>
<div class="section" id="converting-sysinit">
<h2><a class="toc-backref" href="#id4">Converting sysinit</a><a class="headerlink" href="#converting-sysinit" title="Permalink to this headline"></a></h2>
<p>The next step is to do the sysinit. This is implemented as a C macro, which is
incompatible with Rust. This could be solved by using a C library, but for this
tutorial we will simply execute the macro manually.</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="cp">#![no_std]</span>
<span class="hll"><span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="p">{</span>
</span><span class="hll"><span class="w"> </span><span class="k">fn</span> <span class="nf">sysinit_start</span><span class="p">();</span>
</span><span class="hll"><span class="w"> </span><span class="k">fn</span> <span class="nf">sysinit_app</span><span class="p">();</span>
</span><span class="hll"><span class="w"> </span><span class="k">fn</span> <span class="nf">sysinit_end</span><span class="p">();</span>
</span><span class="hll"><span class="p">}</span>
</span>
<span class="k">extern</span><span class="w"> </span><span class="k">crate</span><span class="w"> </span><span class="n">panic_halt</span><span class="p">;</span>
<span class="cp">#[no_mangle]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="hll"><span class="w"> </span><span class="cm">/* Initialize all packages. */</span>
</span><span class="hll"><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">sysinit_start</span><span class="p">();</span><span class="w"> </span><span class="p">}</span>
</span><span class="hll"><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">sysinit_app</span><span class="p">();</span><span class="w"> </span><span class="p">}</span>
</span><span class="hll"><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">sysinit_end</span><span class="p">();</span><span class="w"> </span><span class="p">}</span>
</span>
<span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>First we manually define the three sysinit functions. This is similar to the
C header file. Then we execute the sysinit as the macro would do.</p>
<p>We need the <code class="docutils literal notranslate"><span class="pre">unsafe</span></code> indication because the C code doesn’t have the same memory
guarantees as Rust. Normally we need to build a safe Rust wrapper, but that is
out of scope for this tutorial.</p>
</div>
<div class="section" id="doing-gpio-and-delays">
<h2><a class="toc-backref" href="#id5">Doing GPIO and delays</a><a class="headerlink" href="#doing-gpio-and-delays" title="Permalink to this headline"></a></h2>
<p>Now it is time to do some GPIO and add a delay. Again we define the functions
and then use them in and around the loop. We need some constants that are
normally defined by the BSP or MCU. These constants need to move to a better
place later.</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="cp">#![no_std]</span>
<span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">sysinit_start</span><span class="p">();</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">sysinit_app</span><span class="p">();</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">sysinit_end</span><span class="p">();</span>
<span class="hll"><span class="w"> </span><span class="k">fn</span> <span class="nf">hal_gpio_init_out</span><span class="p">(</span><span class="n">pin</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">val</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span><span class="p">;</span>
</span><span class="hll"><span class="w"> </span><span class="k">fn</span> <span class="nf">hal_gpio_toggle</span><span class="p">(</span><span class="n">pin</span>: <span class="kt">i32</span><span class="p">);</span>
</span><span class="hll"><span class="w"> </span><span class="k">fn</span> <span class="nf">os_time_delay</span><span class="p">(</span><span class="n">osticks</span>: <span class="kt">u32</span><span class="p">);</span>
</span><span class="p">}</span>
<span class="k">extern</span><span class="w"> </span><span class="k">crate</span><span class="w"> </span><span class="n">panic_halt</span><span class="p">;</span>
<span class="hll"><span class="k">const</span><span class="w"> </span><span class="n">OS_TICKS_PER_SEC</span>: <span class="kt">u32</span> <span class="o">=</span><span class="w"> </span><span class="mi">128</span><span class="p">;</span>
</span>
<span class="hll"><span class="k">const</span><span class="w"> </span><span class="n">LED_BLINK_PIN</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="mi">23</span><span class="p">;</span>
</span>
<span class="cp">#[no_mangle]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* Initialize all packages. */</span>
<span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">sysinit_start</span><span class="p">();</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">sysinit_app</span><span class="p">();</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">sysinit_end</span><span class="p">();</span><span class="w"> </span><span class="p">}</span>
<span class="hll"><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">hal_gpio_init_out</span><span class="p">(</span><span class="n">LED_BLINK_PIN</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span><span class="w"> </span><span class="p">}</span>
</span>
<span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span>
<span class="hll"><span class="w"> </span><span class="cm">/* Wait one second */</span>
</span><span class="hll"><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">os_time_delay</span><span class="p">(</span><span class="n">OS_TICKS_PER_SEC</span><span class="p">);</span><span class="w"> </span><span class="p">}</span>
</span>
<span class="hll"><span class="w"> </span><span class="cm">/* Toggle the LED */</span>
</span><span class="hll"><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">hal_gpio_toggle</span><span class="p">(</span><span class="n">LED_BLINK_PIN</span><span class="p">);</span><span class="w"> </span><span class="p">}</span>
</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="cargo-build">
<h2><a class="toc-backref" href="#id6">Cargo build</a><a class="headerlink" href="#cargo-build" title="Permalink to this headline"></a></h2>
<p>Now that the application is converted we need to build it and link it the rest of mynewt. We start with Cargo.toml:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[package]</span>
<span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;rust-klok&quot;</span>
<span class="n">version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0.1.0&quot;</span>
<span class="n">authors</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;Casper Meijn &lt;casper@meijn.net&gt;&quot;</span><span class="p">]</span>
<span class="n">edition</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;2018&quot;</span>
<span class="hll"><span class="k">[dependencies]</span>
</span><span class="hll"><span class="n">panic-halt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0.2.0&quot;</span>
</span>
<span class="hll"><span class="k">[lib]</span>
</span><span class="hll"><span class="n">crate-type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;staticlib&quot;</span><span class="p">]</span>
</span></pre></div>
</div>
<p>This adds the <code class="docutils literal notranslate"><span class="pre">panic-halt</span></code> dependency, which is needed for the panic handler as
mentioned earlier. It also configures the crate as staticlib, which causes the
application to be build as .a-library. This will be needed in a later step.</p>
<p>Next we need a script for running <code class="docutils literal notranslate"><span class="pre">cargo</span></code> and moving the library to the correct
place. Create a new file named <code class="docutils literal notranslate"><span class="pre">apps/blinky/cargo_build.sh</span></code> with the following contents:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="hll"><span class="ch">#!/bin/bash</span>
</span><span class="hll">
</span><span class="hll"><span class="nb">set</span><span class="w"> </span>-eu
</span><span class="hll">
</span><span class="hll"><span class="k">if</span><span class="w"> </span><span class="o">[[</span><span class="w"> </span><span class="si">${</span><span class="nv">MYNEWT_VAL_ARCH_NAME</span><span class="si">}</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">&#39;&quot;cortex_m0&quot;&#39;</span><span class="w"> </span><span class="o">]]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
</span><span class="hll"><span class="w"> </span><span class="nv">TARGET</span><span class="o">=</span><span class="s2">&quot;thumbv6m-none-eabi&quot;</span>
</span><span class="hll"><span class="k">elif</span><span class="w"> </span><span class="o">[[</span><span class="w"> </span><span class="si">${</span><span class="nv">MYNEWT_VAL_ARCH_NAME</span><span class="si">}</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">&#39;&quot;cortex_m3&quot;&#39;</span><span class="w"> </span><span class="o">]]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
</span><span class="hll"><span class="w"> </span><span class="nv">TARGET</span><span class="o">=</span><span class="s2">&quot;thumbv7m-none-eabi&quot;</span>
</span><span class="hll"><span class="k">elif</span><span class="w"> </span><span class="o">[[</span><span class="w"> </span><span class="si">${</span><span class="nv">MYNEWT_VAL_ARCH_NAME</span><span class="si">}</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">&#39;&quot;cortex_m4&quot;&#39;</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="si">${</span><span class="nv">MYNEWT_VAL_ARCH_NAME</span><span class="si">}</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">&#39;&quot;cortex_m7&quot;&#39;</span><span class="w"> </span><span class="o">]]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
</span><span class="hll"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[[</span><span class="w"> </span><span class="nv">$MYNEWT_VAL_HARDFLOAT</span><span class="w"> </span>-eq<span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">]]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
</span><span class="hll"><span class="w"> </span><span class="nv">TARGET</span><span class="o">=</span><span class="s2">&quot;thumbv7em-none-eabihf&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="k">else</span>
</span><span class="hll"><span class="w"> </span><span class="nv">TARGET</span><span class="o">=</span><span class="s2">&quot;thumbv7em-none-eabi&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="k">fi</span>
</span><span class="hll"><span class="k">else</span>
</span><span class="hll"><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;The ARCH_NAME </span><span class="si">${</span><span class="nv">MYNEWT_VAL_ARCH_NAME</span><span class="si">}</span><span class="s2"> is not supported&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="nb">exit</span><span class="w"> </span><span class="m">1</span>
</span><span class="hll"><span class="k">fi</span>
</span><span class="hll">
</span><span class="hll">cargo<span class="w"> </span>build<span class="w"> </span>--target<span class="o">=</span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">TARGET</span><span class="si">}</span><span class="s2">&quot;</span><span class="w"> </span>--target-dir<span class="o">=</span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">MYNEWT_PKG_BIN_DIR</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class="hll">cp<span class="w"> </span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">MYNEWT_PKG_BIN_DIR</span><span class="si">}</span><span class="s2">&quot;</span>/<span class="si">${</span><span class="nv">TARGET</span><span class="si">}</span>/debug/*.a<span class="w"> </span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">MYNEWT_PKG_BIN_ARCHIVE</span><span class="si">}</span><span class="s2">&quot;</span>
</span></pre></div>
</div>
<p>The script first sets the name of the target as the Rust compiler knows it. Sadly
this is not the same as the names mynewt uses. You need to choose the same type of
compiler as mynewt uses. The following targets are available depending on the
MCU type:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">thumbv6m-none-eabi</span></code> - use this for Cortex-M0 and Cortex-M0+.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">thumbv7m-none-eabi</span></code> - use this for Cortex-M3.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">thumbv7em-none-eabi</span></code> - use this for Cortex-M4 and Cortex-M7.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">thumbv7em-none-eabihf</span></code> - use this for Cortex-M4 and Cortex-M7 with the
<code class="docutils literal notranslate"><span class="pre">HARDFLOAT</span></code> syscfg enabled.</p></li>
</ul>
<p>Then it runs <code class="docutils literal notranslate"><span class="pre">cargo</span> <span class="pre">build</span></code> with
the target directory set to a path that <code class="docutils literal notranslate"><span class="pre">newt</span></code> provides. Lastly it copies the
generated library to the correct path.</p>
<p>Don’t forget to mark the script as executable:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>chmod<span class="w"> </span>+x<span class="w"> </span>apps/blinky/cargo_build.sh
</pre></div>
</div>
</div>
<div class="section" id="newt-integration">
<h2><a class="toc-backref" href="#id7">Newt integration</a><a class="headerlink" href="#newt-integration" title="Permalink to this headline"></a></h2>
<p>To automatically run <code class="docutils literal notranslate"><span class="pre">cargo</span></code> we need to add the following to pkg.yml:</p>
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nn">...</span>
<span class="hll"><span class="nt">pkg.pre_build_cmds</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="s">&#39;./cargo_build.sh&#39;</span><span class="p p-Indicator">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">1</span>
</span><span class="hll">
</span><span class="hll"><span class="nt">pkg.lflags</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="s">&#39;-Wl,--allow-multiple-definition&#39;</span>
</span></pre></div>
</div>
<p>The first section tells the mynewt build system to run <code class="docutils literal notranslate"><span class="pre">cargo_build.sh</span></code> as part
of <code class="docutils literal notranslate"><span class="pre">newt</span> <span class="pre">build</span></code>. The second section tells the linker to ignore double function
definitions. This is needed as the Rust compiler adds some functions that are
also in baselibc.</p>
<p>Now we are ready to build a firmware! Remove <code class="docutils literal notranslate"><span class="pre">main.c</span></code> and start the build:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>rm<span class="w"> </span>apps/blinky/src/main.c
<span class="gp">$ </span>newt<span class="w"> </span>build<span class="w"> </span>nrf52_blinky
</pre></div>
</div>
<p>If this command complains about a target may not be installed, then you need to
install it. You need the same toolchain as configured earlier for the <code class="docutils literal notranslate"><span class="pre">TARGET</span></code>
variable:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>rustup<span class="w"> </span>target<span class="w"> </span>add<span class="w"> </span>&lt;your-target&gt;
</pre></div>
</div>
</div>
<div class="section" id="conclusion">
<h2><a class="toc-backref" href="#id8">Conclusion</a><a class="headerlink" href="#conclusion" title="Permalink to this headline"></a></h2>
<p>You now have a firmware where the application is written in Rust. It is nicely
integrated into newt builder. However it still needs some work: it misses safe
Rust wrappers for the mynewt libraries and there are some magic constants that
need to be moved to a better location.</p>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="../../external_links.html" class="btn btn-neutral float-right" title="Third-party Resources" accesskey="n">Next: Third-party Resources <span class="fa fa-arrow-circle-right"></span></a>
<a href="chg_ctrl_on_pinetime.html" class="btn btn-neutral" title="Charge control on PineTime" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: Charge control on PineTime</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
</small>
<a href="">
<img src="../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../_static/js/main.js"></script>
</body>
</html>