lupyuen.org/articles/coding-nrf52-with-rust-and-apache-mynewt-on-visual-studio-code.html

1797 lines
No EOL
137 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/coding-nrf52-with-rust-and-apache-mynewt-on-visual-studio-code.html" />
<!-- End Wayback Rewrite JS Include -->
<title data-rh="true">Coding nRF52 with Rust and Apache Mynewt on Visual Studio Code</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-11-26T04:43:21.543Z" />
<meta data-rh="true" name="title" content="Coding nRF52 with Rust and Apache Mynewt on Visual Studio Code" />
<meta data-rh="true" property="og:title" content="Coding nRF52 with Rust and Apache Mynewt on Visual Studio Code" />
<meta data-rh="true" property="twitter:title"
content="Coding nRF52 with Rust and Apache Mynewt on Visual Studio Code" />
<meta data-rh="true" name="description"
content="Build an iBeacon with Apache NimBLE… Connect nRF52 to ST-Link / Raspberry Pi… And more!" />
<meta data-rh="true" property="og:description"
content="Build an iBeacon with Apache NimBLE… Connect nRF52 to ST-Link / Raspberry Pi… And more!" />
<meta data-rh="true" property="twitter:description"
content="Build an iBeacon with Apache NimBLE… Connect nRF52 to ST-Link / Raspberry Pi… And more!" />
<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="26 min read" />
<meta property="og:image"
content="https://lupyuen.github.io/images/legacy/o1.jpeg">
<!-- 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/legacy/o1.jpeg" /></p>
<figcaption><p><em>EBYTE E73-TBB Development Board with onboard
Nordic nRF52832 Microcontroller, connected to ST-Link USB Programmer. Shot with Sony NEX-7.
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<div>
<div id="a6d1" class="ea eb ec bk ed b ee ef eg eh ei ej ek el em en eo">
<h1 class="ed b ee ep eg eq ei er ek es em et ec">Coding nRF52 with Rust and Apache Mynewt on Visual
Studio Code</h1>
</div>
<div class="eu">
<div class="n ev ew ex ey">
<div class="o n">
<div><a rel="noopener"
href="https://lupyuen.github.io">
<div class="dd ez fa">
<div class="bs n fb o p cp fc fd fe ff fg ct"></div>
</div>
</a></div>
<div class="fi ak r">
<div class="n">
<div style="flex:1"><span class="bj b bk bl bm bn r ec q">
<div class="fj n o fk"><span class="bj dy ds bl di fl fm fn fo fp ec"><a
class="at au av aw ax ay az ba bb bc fq 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 fl fm fn fo fp bo">
<div><a class="at au av aw ax ay az ba bb bc fq bf bg bh bi" rel="noopener"
href="https://lupyuen.github.io/articles/coding-nrf52-with-rust-and-apache-mynewt-on-visual-studio-code">
3 Oct 2019</a> <!-- -->·
<!-- -->
<!-- -->26
<!-- --> min read
</div>
</span></span>
</div>
</div>
</div>
</div>
</div>
<p id="f66d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The <a
href="https://infocenter.nordicsemi.com/pdf/nRF52832_PS_v1.0.pdf"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong class="gr hh">nRF52
Microcontroller</strong></a> by Nordic Semiconductor is an awesome gadget with powerful Bluetooth
Low Energy networking capability. Its affordable too… For under $8, I can buy an <a
href="http://www.ebyte.com/product-view-news.aspx?id=644"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">EBYTE E73-TBB Development
Board</a> with onboard nRF52 (photo above). And it works like a supercharged <a
href="https://en.wikipedia.org/wiki/Micro_Bit"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">BBC micro:bit</a> (based on the
older nRF51) in a smaller, cheaper form factor!</p>
<p id="ca61" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Powered by an <strong
class="gr hh">Arm Cortex-M4 CPU </strong>(hardware floating-point) with <strong class="gr hh">64 KB
of RAM</strong> and <strong class="gr hh">512 KB of Flash ROM</strong>, the nRF52 has plenty of
capacity to run modern embedded platforms… Like <a
href="https://mynewt.apache.org/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong class="gr hh">Apache
Mynewt</strong></a> realtime OS and <strong class="gr hh">Embedded Rust</strong>!</p>
<p id="8503" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">But what tools
would we use to code the nRF52? Will we get locked in with proprietary IDEs and programming
dongles?</em></p>
<p id="de66" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Great News: The nRF52 works with
popular open-source tools on Windows and macOS like <a
href="https://code.visualstudio.com/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong class="gr hh">Visual
Studio Code</strong></a><strong class="gr hh">, </strong><a
href="http://openocd.org/" class="at cg hd he hf hg"
target="_blank" rel="noopener nofollow"><strong class="gr hh">OpenOCD</strong></a><strong
class="gr hh">, </strong><a
href="https://www.rust-lang.org/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong
class="gr hh">Rust</strong></a><strong class="gr hh"> and </strong><a
href="https://www.aliexpress.com/wholesale?catId=0&amp;initiative_id=SB_20180924134644&amp;SearchText=st-link+v2&amp;switch_new_app=y"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong
class="gr hh">ST-Link</strong></a>… Ill show you how, right now! (ST-Link is not really
open-source but <a
href="https://www.aliexpress.com/wholesale?catId=0&amp;initiative_id=SB_20180924134644&amp;SearchText=st-link+v2&amp;switch_new_app=y"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">its only $2</a>!)</p>
<p id="d918" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Even if youre new to nRF52,
Bluetooth, Mynewt, Visual Studio Code, … Youre welcome to skim! Well cover a broad range of topics.
including…</p>
<p id="edeb" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">1<strong
class="gr hh">Bluetooth Low Energy</strong> and the <strong class="gr hh">iBeacon</strong> protocol
</p>
<p id="c689" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">2⃣ Build your own iBeacon with
nRF52 and <strong class="gr hh">Apache NimBLE</strong></p>
<p id="4b2b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">3<strong
class="gr hh">Embedded Rust</strong> programming on nRF52</p>
<p id="0096" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">4⃣ Programming <strong
class="gr hh">IoT Sensors</strong> with Mynewt and Rust</p>
<p id="79d7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">5⃣ Why Rust not C?</p>
<p id="7d68" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">6⃣ Code, flash and debug the
nRF52 with <strong class="gr hh">Visual Studio Code</strong> and <strong
class="gr hh">OpenOCD</strong></p>
<p id="0080" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">7<strong class="gr hh">Remove
Flash Protection</strong> from your nRF52 with a <strong class="gr hh">Raspberry Pi</strong></p>
<p id="97cf" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">8⃣ Plus upcoming topics: <strong
class="gr hh">Bluetooth Mesh</strong> and <strong class="gr hh">PineTime Smart Watch</strong>!</p>
<p id="b990" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Theres something
for everyone in this article</em>! The source code for this article may be found in the <code
class="dm hj hk hl hm b">nrf52</code> branch of this repository…</p>
<div class="hn ho hp hq hr hs"><a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52"
rel="noopener nofollow">
<section class="hv cl cm ak ce n ar hw hx hy hz ia ib ic id ie if ig ih ii ij ik">
<div class="il n co p im in">
<h2 class="bj io ip bl ec">
<div class="di ht fm fn hu fp">lupyuen/stm32bluepill-mynewt-sensor</div>
</h2>
</div>
</section>
</a></div>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="3325" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Whats an iBeacon?</h1>
<p id="d546" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">There was a time… (When people
still shopped at physical retail stores…) You could walk into your favourite store and your phone
would <em class="hi">“Ding!”</em> with a notification specially customised for you… <em
class="hi">“Save up to 40% on Baby and Kids Products!”</em></p>
<p id="f4b6" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">What is this magic
that senses your mere presence… And summons a unique offer… Just for you?</em></p>
<p id="2866" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">That magic is called <a
href="https://en.wikipedia.org/wiki/IBeacon"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong
class="gr hh">iBeacon</strong></a>. Its a wireless protocol released by Apple in 2013 for
detecting Bluetooth Low Energy devices nearby (within a few metres). iBeacon Transmitters are dumb
devices planted in the store that broadcast an iBeacon ID thats specific to the store.</p>
<p id="1e9d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Your phone needs to have an app
installed that indicates which iBeacon ID its seeking. When your phone detects a nearby iBeacon
Transmitter with a matching iBeacon ID, it wakes up the app so that the app can send you a custom
notification.</p>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o2.png" /></p>
</div>
<p id="4d90" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">In reality its hard to detect
Bluetooth 4 iBeacons reliably because of conflicts with WiFi, which also operates in the crowded 2.4
GHz airwaves (see <a
href="https://www.hindawi.com/journals/misy/2016/8367638/"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://www.hindawi.com/journals/misy/2016/8367638/</a>).</p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o3.png" /></p>
<figcaption><p><em>Our nRF52 detected as an iBeacon (“My
iBeacon”) in the “Locate Beacon” app: <a
href="https://apps.apple.com/us/app/locate-beacon/id738709014"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://apps.apple.com/us/app/locate-beacon/id738709014</a></em></p></figcaption>
</div>
<p id="f401" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">In this tutorial well program
our nRF52 to be an iBeacon Transmitter, because…</p>
<ol class="">
<li id="b4bc" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc km kn ko">iBeacon is the
simplest Bluetooth LE protocol to implement (and troubleshoot)</li>
<li id="b6d5" class="gp gq ec bk gr b gs kp gu kq gw kr gy ks ha kt hc km kn ko">Its easy to use our
phones to verify that our nRF52 is indeed working correctly as a Bluetooth LE transmitter</li>
<li id="2833" class="gp gq ec bk gr b gs kp gu kq gw kr gy ks ha kt hc km kn ko">Nostalgia…<em
class="hi"> iBeacon actually served a purpose in the real world!</em> (But if you decide to
implement iBeacons today, beware of the iBeacon security implications, especially <a
href="https://en.wikipedia.org/wiki/IBeacon#Spoofing"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">iBeacon spoofing</a>)</li>
</ol>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="d379" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">nRF52 is Radio-Capable</h1>
<p id="11de" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">nRF52 is similar to other
microcontrollers (like the STM32 F103 found in Blue Pill)… Except that the nRF52 has 2.4 GHz Radio
capabilities not found in most other microcontrollers.</p>
<p id="2044" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">2.4 GHz is used
for WiFi… Does this mean that the nRF52 can talk WiFi?</em></p>
<p id="e9be" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Not quite… WiFi protocols are
highly complex, beyond what the nRF52 can handle. Specialised microcontrollers like ESP8266 are better
at handling WiFi.</p>
<p id="4f46" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">But nRF52 is perfect for
Bluetooth Low Energy (LE) protocols, including iBeacon. Note that Bluetooth LE is not compatible with
the older standard Bluetooth. So we cant operate our nRF52 like a classic Bluetooth tethered network
device.</p>
<p id="b18d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">nRF52 doesnt come with hardcoded
firmware that enables the Bluetooth LE functions… We need to load our own Bluetooth LE firmware. Lets
discuss two options: Nordic SoftDevice and Apache NimBLE.</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="dc0d" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Nordic SoftDevice</h1>
<p id="77d7" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Most nRF52 developers would
probably use <a
href="https://infocenter.nordicsemi.com/pdf/S112_SDS_v3.1.pdf"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Nordic SoftDevice</a>. This is the
standard firmware provided by Nordic Semiconductor that implements the Bluetooth LE functions.</p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o4.png" /></p>
<figcaption><p><em>Nordic SoftDevice Architecture. From <a
href="https://infocenter.nordicsemi.com/topic/struct_nrf52/struct/nrf52_softdevices.html"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://infocenter.nordicsemi.com/topic/struct_nrf52/struct/nrf52_softdevices.html</a>
</em></p></figcaption>
</div>
<p id="3ffc" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The firmware runs as a base
system layer underneath our application code and RTOS.</p>
<p id="bd36" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">SoftDevice reserves some hardware
resources for itself, like the radio transceiver, some timers and some ROM+RAM.</p>
<p id="9935" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The remaining resources would be
available for our application, which would call the <a
href="https://infocenter.nordicsemi.com/pdf/S112_SDS_v3.1.pdf"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">SoftDevice API</a> to perform
Bluetooth LE functions and receive notifications.</p>
<p id="b48a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">What if we wish to
experiment with the Bluetooth LE implementation… Trace it to see how it works, tweak it to improve
it, or even roll out a new Bluetooth LE protocol?</em></p>
<p id="a39d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">SoftDevice is clearly not meant
for experimentation… Apache NimBLE is perfect for that!</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="9ea4" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Apache NimBLE</h1>
<p id="4c92" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc"><a
href="https://mynewt.apache.org/latest/network/docs/index.html"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Apache NimBLE</a> is an
open-source Bluetooth LE stack that <strong class="gr hh">completely replaces SoftDevice</strong> on
nRF51 and nRF52 chipsets. Its designed to run with the Apache Mynewt embedded OS, so NimBLE feels
like a typical Mynewt task.</p>
<p id="3ed9" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Apache NimBLE is
the Bluetooth LE implementation that were adopting for this tutorial.</em></p>
<p id="2f2f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">In this tutorial well often
refer to NimBLE as Mynewt… Because NimBLE is so seamlessly integrated with Mynewt. Just note that
Mynewt and NimBLE actually belong to two different code repositories…</p>
<p id="f73c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Mynewt: <code
class="dm hj hk hl hm b"><a href="https://github.com/apache/mynewt-core" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">https://github.com/apache/mynewt-core</a></code>
</p>
<p id="8322" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">NimBLE: <code
class="dm hj hk hl hm b"><a href="https://github.com/apache/mynewt-nimble" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">https://github.com/apache/mynewt-nimble</a></code>
</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="ffd4" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Why Visual Studio Code with
ST-Link (instead of nRFgo Studio with J-LINK)</h1>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o5.jpeg" /></p>
<figcaption><p><em>nRF52 Development Board connected to ST-Link
USB Programmer</em></p></figcaption>
</div>
<p id="d46f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">If youre already familiar with
nRF52 development tools like <a
href="https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRFgo-Studio"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">nRFgo Studio</a> and <a
href="https://en.wikipedia.org/wiki/Segger_Microcontroller_Systems#J-Link"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">J-LINK</a>… This tutorial will
open your eyes!</p>
<p id="75b2" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">My previous tutorials have been
based on open-source tools and affordable, accessible hardware. For this tutorial well be reusing <a
href="https://code.visualstudio.com/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Visual Studio Code</a> and ST-Link
(with <a href="http://openocd.org/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">OpenOCD</a>).</p>
<p id="1ad7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Yes, the
open-source tools we use for coding STM32 may also be used for nRF52!</em></p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="ky kz la lb lc ld ag le ah lf aj ak">
<div class="figure js jt ju jv jw cz lh li paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o6.png" /></p>
<figcaption><p><em>Debugging Embedded Rust on nRF52 with Visual
Studio Code and ST-Link</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<p id="9090" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The generic <a
href="https://www.aliexpress.com/wholesale?catId=0&amp;initiative_id=SB_20180924134644&amp;SearchText=st-link+v2"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">ST-Link V2 USB Adapter</a><strong
class="gr hh"> </strong>costs under $2 (search <a
href="https://www.aliexpress.com/wholesale?catId=0&amp;initiative_id=SB_20180924134644&amp;SearchText=st-link+v2&amp;switch_new_app=y"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">AliExpress</a> for <code
class="dm hj hk hl hm b">st-link v2</code>) and works perfectly fine for flashing and debugging the
nRF52… <strong class="gr hh">Except for removing nRF52 flash protection.</strong></p>
<p id="fb3e" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">How is ST-Link
different from J-LINK, since both are used for flashing and debugging Arm microcontrollers?</em></p>
<p id="2442" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">ST-Link and J-LINK are both Arm
SWD (Serial Wire Debug) Programmers. ST-Link is known as a High-Level Adapter… ST-Link doesnt
implement all SWD functions, just the <em class="hi">minimal set of high-level functions needed for
flashing and debugging. </em>Thus ST-Link cant be used for removing the nRF52 flash protection.</p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o7.jpeg" /></p>
<figcaption><p><em>Removing nRF52 flash ROM protection with
Raspberry Pi</em></p></figcaption>
</div>
<p id="0328" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">If your nRF52 flash ROM is
protected (and ST-Link refuses to flash your device), you may use a Raspberry Pi to remove the
protection.</p>
<p id="15e5" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This only needs to be done once
(and ST-Link will work fine after that).</p>
<p id="dc60" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Check the instructions in the
section <em class="hi">“Advanced Topic: Remove nRF52 Flash Protection” </em>at the end of this
article.</p>
<p id="1129" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Welcome nRF52 (and
nRF51)! Come join STM32 in the Open Source Party… Rust included!</em></p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="cz ak">
<div class="figure js jt ju jv jw cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o8.png" /></p>
<figcaption><p><em>Mynewt Project Structure based on <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="a2c8" class="jb jc ec bk bj io ee ln eg lo jf lp jh lq jj lr jl">Mynewt Project Structure</h1>
<p id="e168" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Mynewt is a lightweight embedded
operating system that pulls in only the modules that it needs to create the firmware image. Here are
the files in our Mynewt project… (<a class="at cg hd he hf hg" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/install-apache-mynewt-and-embedded-rust-for-nrf52-and-visual-studio-code-on-windows-and-macos">Check
this article</a> if you wish to download the source code and browse with Visual Studio Code)</p>
<p id="e060" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">1<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/apps" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">apps</a></code>:
<strong class="gr hh">C Source Code for Bootloader and Application</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o9.png" /></p>
</div>
<p id="9ed4" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This is where we put our
Bootloader and Application source code in C. The Mynewt build script will compile the code here into
the Bootloader and Application Firmware Images.</p>
<p id="6089" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/apps/boot_stub/src" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">apps/boot_stub/src</a></code>:
C source code for our Bootloader. Were using a simple Stub Bootloader: Upon startup it doesnt do
anything, it just jumps to the Application.</p>
<p id="e247" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/apps/my_sensor_app/src" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">apps/my_sensor_app/src</a></code>:
C source code for our Application. The iBeacon code is located in <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/apps/my_sensor_app/src/ble.c" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">ble.c</a></code>.
Well cover this in a while.</p>
<p id="1f86" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">2<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/rust" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">rust</a></code>:
<strong class="gr hh">Rust Source Code</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o10.png" /></p>
</div>
<p id="8303" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">All Rust code is placed in this
folder. Mynewt doesnt support Rust officially (yet), so I created a custom Application Build Script
for Mynewt that injects Rust Application code into the Mynewt Application Build. (Well soon discover
that the Rust code was injected in a sneaky way…)</p>
<p id="4a6a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This means that we can write our
<code class="dm hj hk hl hm b">main()</code> function in Rust and call other Rust modules and crates.
Since Rust supports the calling of C functions, we may call the Mynewt API from Rust as well. (Though
calling the Mynewt API through a proper Rust Wrapper is preferred… More about this later)</p>
<p id="0f81" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Heres the Rust code in our
Mynewt Project…</p>
<p id="bff9" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/rust/app/src" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">rust/app/src</a></code>:
Rust source code for our Application. The <code class="dm hj hk hl hm b">main()</code> function is
defined in <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">lib.rs</a></code>,
its called when our device starts up. Well cover this in a while.</p>
<p id="f52f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/rust/mynewt/src" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">rust/mynewt/src</a></code>:
Rust Wrappers for Mynewt API. Its possible to call the Mynewt API via <code
class="dm hj hk hl hm b">extern</code> declarations in Rust, but that wouldnt be efficient.
(Imagine converting Rust strings to null-terminated C strings for every <code
class="dm hj hk hl hm b">extern</code> call.) Also we wouldnt be able to exploit the power of Rust
Macros, Iterators, Error Handling, …</p>
<p id="84b4" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Thus I have created Rust Wrappers
that allow Rust applications to call the Mynewt API in a safe and simple way. Well see examples of
this in a while.</p>
<p id="c632" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/rust/macros/src" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">rust/macros/src</a></code>:
Rust Macros for generating Rust Wrappers. Most of the Rust Wrappers were automatically generated with
the <code class="dm hj hk hl hm b">bindgen</code> tool and Rust Procedural Macros. These macros are
invoked only during Rust compilation, not at runtime.</p>
<p id="5e56" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">3<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/libs" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">libs</a></code>:
<strong class="gr hh">Custom Mynewt Libraries used by our Application</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o11.png" /></p>
</div>
<p id="80ff" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">These are C libraries that I have
created to make Mynewt more friendly for embedded developers. <code
class="dm hj hk hl hm b">semihosting_console</code> allows debugging messages to be displayed in the
Visual Studio Code Debugger (without using a serial port). <code
class="dm hj hk hl hm b">temp_stub</code> is a Mynewt Driver that simulates a Temperature Sensor,
used in our Rust application.</p>
<p id="fdde" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b">rust_app</code> is a Stub Library for injecting the compiled Rust
Application code. Our build script will bundle the compiled Rust Application code (including external
crates) into <code class="dm hj hk hl hm b">rust_app</code>, which gets linked into the Application
Firmware. (Remember our <code class="dm hj hk hl hm b">main()</code> function in Rust? It gets bundled
into <code class="dm hj hk hl hm b">rust_app</code>)</p>
<p id="ce1b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Similarly, <code
class="dm hj hk hl hm b">rust_libcore</code> is a Stub Library for injecting the Rust Core Library
into the Application Firmware. The Rust Core Library is part of the Rust Compiler and its needed for
core functions (like manipulating strings). Note that were not using the full Rust Standard Library,
which contains lots of code thats irrelevant for embedded platforms.</p>
<p id="aaf3" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">4<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/hw/bsp" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">hw/bsp</a></code>:
<strong class="gr hh">Board Support Packages for Mynewt</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o12.png" /></p>
</div>
<p id="04a8" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">A Board Support Package contains
information, scripts and drivers necessary to build Mynewt for our microcontroller (nRF52832) and the
associated peripherals on our microcontroller board: flash memory, LEDs, UART ports, …</p>
<p id="d76f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/hw/bsp/nrf52" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">hw/bsp/nrf52</a></code>:
Board Support Package for our nRF52 microcontroller board. This is a clone of the official <code
class="dm hj hk hl hm b"><a href="https://github.com/apache/mynewt-core/tree/master/hw/bsp/ada_feather_nrf52" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">ada_feather_nrf52</a></code>
Board Support Package, with the <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/hw/bsp/nrf52/include/bsp/bsp.h#L42-L49"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">LED and Button settings</a>
customised for the EBYTE E73-TBB Development Board. (You should update these settings to suit your
nRF52 development board.)</p>
<p id="80d7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">5<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/targets" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">targets</a></code>:
<strong class="gr hh">Bootloader and Application Targets for Mynewt</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o13.png" /></p>
</div>
<p id="dac8" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Mynewt Applications are designed
to be portable across microcontrollers… An application like <code
class="dm hj hk hl hm b">my_sensor_app</code> may be recompiled to run on STM32 Blue Pill F103,
STM32 F476, or even BBC micro:bit (based on Nordic nRF51).</p>
<p id="8926" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">How do we compile an application
like <code class="dm hj hk hl hm b">my_sensor_app</code> for our nRF52832 development board? We tell
Mynewt to create a “Target” for the application, i.e. an instance of <code
class="dm hj hk hl hm b">my_sensor_app</code> thats targeted for our Board Support Package <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/hw/bsp/nrf52" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">hw/bsp/nrf52</a></code>
</p>
<p id="3f45" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/targets" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">targets</a></code>
folder contains Bootloaders and Applications that have been targeted for specific Board Support
Packages…</p>
<p id="cfb2" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/targets/nrf52_boot" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">targets/nrf52_boot</a></code>:
This is the <code class="dm hj hk hl hm b">boot_stub</code> Bootloader targeted for nRF52</p>
<p id="53dd" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/targets/nrf52_my_sensor" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">targets/nrf52_my_sensor</a></code>:
This is the <code class="dm hj hk hl hm b">my_sensor_app</code> Application targeted for nRF52. The
Application Settings are configured at <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/targets/nrf52_my_sensor/syscfg.yml" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">targets/nrf52_my_sensor/syscfg.yml</a></code>
</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/0d232faf505ea8987a864b39c1f7517c.js"></script></p>
<figcaption><p><em>Application Settings. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/targets/nrf52_my_sensor/syscfg.yml"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/targets/nrf52_my_sensor/syscfg.yml</a>
</em></p></figcaption>
</div>
<p id="ab9a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">6<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/scripts" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">scripts</a></code>:
<strong class="gr hh">Build, Flash and Debug Scripts</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o14.png" /></p>
</div>
<p id="1a26" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.cmd" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">scripts/build-app.cmd</a>, <a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.sh" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">.sh</a></code>:
This shell script <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.sh#L80-L82"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">builds the Rust Application</a> by
calling <code class="dm hj hk hl hm b">cargo build</code> and <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.sh#L87-L120"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">bundles the compiled Rust code</a>
(with external crates) into the <code class="dm hj hk hl hm b">rust_app</code> library.</p>
<p id="fda9" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Then it <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.sh#L157-L160"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">builds the Application
Firmware</a> by running <code class="dm hj hk hl hm b">newt build nrf52_my_sensor</code>, injecting
<code class="dm hj hk hl hm b">rust_app</code> (Rust Application) and <code
class="dm hj hk hl hm b">rust_libcore</code> (<a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.sh#L129-L148"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Rust Core Library</a>) into the
Application Firmware.</p>
<p id="0f38" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The Rust build is targeted for
<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.cmd#L3-L6" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">thumbv7em-none-eabihf</a></code>
(Arm Cortex M4 with Hardware Floating-Point), which is the designation for the Arm processor in the
nRF52832 microcontroller.</p>
<p id="9f6d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/scripts/nrf52" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">scripts/nrf52</a></code>:
Contains the build, flash and debug scripts specific to nRF52. The <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/flash-boot.cmd"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Flash Bootloader</a>, <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/flash-app.cmd"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Flash Application</a> and <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/debug.ocd"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Debug Scripts</a> include OpenOCD
scripts (<code class="dm hj hk hl hm b">*.ocd</code>) that connect to the nRF52 via ST-Link.</p>
<p id="830c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Heres the OpenOCD command used
in the <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/flash-app.cmd"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Flash Application</a> Script that
connects to nRF52 via ST-Link to flash the Application Firmware…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="102b" class="mi jc ec bk hm b ds mj mk r ml">openocd/bin/openocd \<br/> -f scripts/nrf52/flash-init.ocd \<br/> -f interface/stlink.cfg \<br/> -c &quot;transport select hla_swd&quot; \<br/> -f target/nrf52.cfg \<br/> -f scripts/nrf52/flash-app.ocd</span></pre>
<p id="3f56" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The OpenOCD script <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/flash-app.ocd" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">scripts/nrf52/flash-app.ocd</a></code>
specifies the firmware image file to be flashed (<code
class="dm hj hk hl hm b">my_sensor_app.img</code>) and the ROM address (<code
class="dm hj hk hl hm b">0x0000 4000</code>)…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="2673" class="mi jc ec bk hm b ds mj mk r ml"># From <a href="https://devzone.nordicsemi.com/f/nordic-q-a/42824/flashing-nrf5832-using-only-st-link-v2-and-openocd" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">https://devzone.nordicsemi.com/f/nordic-q-a/42824/flashing-nrf5832-using-only-st-link-v2-and-openocd</a><br/>gdb_flash_program enable<br/>gdb_breakpoint_override hard</span><span id="6a4b" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml"># Connect to the device.<br/>init</span><span id="44a6" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml"># Enable ARM semihosting to show debug console output.<br/>arm semihosting enable</span><span id="c173" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">echo &quot;Stopping...&quot;<br/>reset halt</span><span id="73c3" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">echo &quot;Flashing Application...&quot;<br/>program bin/targets/nrf52_my_sensor/app/apps/my_sensor_app/my_sensor_app.img verify 0x00004000</span><span id="7139" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml"># Restart the device.<br/>reset halt<br/>exit</span></pre>
<p id="628a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Note that…<br />Bootloader Code
is located at ROM Address <code class="dm hj hk hl hm b">0x0000 0000</code> <br />Application Code is
located at ROM Address <code class="dm hj hk hl hm b">0x0000 4000</code></p>
<p id="e459" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">7<code
class="dm hj hk hl hm b">repos</code>: <strong class="gr hh">Apache Mynewt and NimBLE Source
Code</strong></p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o15.png" /></p>
</div>
<p id="b0ac" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This folder contains the official
Mynewt and NimBLE source code in C. We shouldnt change anything here.</p>
<p id="f9b5" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">8<code
class="dm hj hk hl hm b">bin</code>: <strong class="gr hh">Compiled Bootloader and Application
Code</strong></p>
<p id="fae7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The build scripts produce
Bootloader and Application Firmware Images in this folder. These firmware images are used by the <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/flash-boot.cmd"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Flash Bootloader</a> and <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/flash-app.cmd"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Flash Application</a> Scripts to
flash the Bootloader and Application to the nRF52.</p>
<p id="fd03" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The Application Firmware is also
flashed to the nRF52 when we click <code class="dm hj hk hl hm b">Start Debugging</code>.</p>
<p id="8bc8" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">9<code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/.vscode" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">.vscode</a></code>:
<strong class="gr hh">Visual Studio Code Settings</strong></p>
<p id="3f39" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/.vscode/tasks.json" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">tasks.json</a></code>
defines the Build and Flash Bootloader / Application Tasks in Visual Studio Code. These tasks invoke
the scripts in the <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/tree/nrf52/scripts" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">scripts</a></code>
folder</p>
<p id="c94d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/.vscode/launch-nrf52.json" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">launch-nrf52.json</a></code>
contains the nRF52 debugger settings for the <a
href="https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Cortex-Debug Extension</a> that
were using to debug our application. When we run the <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/build-app.cmd#L4-L6"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Build Application</a> script, the
script copies <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/.vscode/launch-nrf52.json" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">launch-nrf52.json</a></code>
to <code class="dm hj hk hl hm b">launch.json</code>, which is loaded by the Cortex-Debug debugger.
</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="6166" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Create an iBeacon with NimBLE
</h1>
<p id="918b" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Lets look at the application
code that calls the NimBLE API to create an iBeacon Transmitter: <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/apps/my_sensor_app/src/ble.c" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">apps/my_sensor_app/src/ble.c</a></code>.
Why did we code this in C and not Rust? Well discuss this in a while.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/36aad6f0453ef7dd7f61d2c1c20bce82.js"></script></p>
</div>
<p id="be55" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b">start_ble()</code> is called by the Rust <code
class="dm hj hk hl hm b">main()</code> function to start the iBeacon broadcasts in our application.
</p>
<p id="8732" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">In Bluetooth LE applications,
its mandatory to wait for the Host (i.e. Arm Processor) and Controller (i.e. Radio Transceiver) to
sync up before performing any Bluetooth LE functions.</p>
<p id="fe53" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Here we set up the <code
class="dm hj hk hl hm b">ble_hs_cfg.sync_cb</code> callback defined in NimBLE, so that NimBLE will
call our function <code class="dm hj hk hl hm b">ble_app_on_sync()</code> as soon as the Host and
Controller are in sync. (Which happens very quickly upon startup… Just set a breakpoint in <code
class="dm hj hk hl hm b">ble_app_on_sync()</code> and watch!)</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/ee65281b1e160c054fa896d40ee52901.js"></script></p>
</div>
<p id="acb7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">When the Host and Controller are
in sync, <code class="dm hj hk hl hm b">ble_app_on_sync()</code> calls two functions to set up the
iBeacon Transmitter…</p>
<ol class="">
<li id="9cb0" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc km kn ko"><code
class="dm hj hk hl hm b">ble_app_set_addr()</code>: Generate a Non-Resolvable Private Address</li>
<li id="d9c3" class="gp gq ec bk gr b gs kp gu kq gw kr gy ks ha kt hc km kn ko"><code
class="dm hj hk hl hm b">ble_app_advertise()</code>: Advertise indefinitely as an iBeacon</li>
</ol>
<p id="dc35" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Whats a <strong
class="gr hh">Non-Resolvable Private Address</strong>? Just like any networking protocol, in
Bluetooth LE we need to identify ourselves with a network address. Since were creating an iBeacon
Transmitter with no receive capability, its OK to use a temporary random address, i.e. Non-Resolvable
Private Address.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/1ab29d101c4bd579821e8942cb0d282f.js"></script></p>
</div>
<p id="e5dd" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Heres how we call the NimBLE API
<code class="dm hj hk hl hm b">ble_hs_id_gen_rnd()</code> to generate that random 6-byte
Non-Resolvable Private Address.</p>
<p id="f857" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Once we have obtained the random
address, we tell NimBLE to use it by calling <code
class="dm hj hk hl hm b">ble_hs_id_set_rnd()</code>. If youre curious to see the random address,
just set a Debugger Breakpoint by clicking the gutter to add a red dot like this…</p>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o16.png" /></p>
<figcaption><p><em>Setting a breakpoint to observe the
randomly-generated 6-byte Non-Resolvable Private Address</em></p></figcaption>
</div>
<p id="5ec4" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Now lets find out what our nRF52
shall be broadcasting…</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="6779" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Set iBeacon Parameters</h1>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o17.png" /></p>
<figcaption><p><em>iBeacon ID links the iBeacon Transmitter to
the Mobile App</em></p></figcaption>
</div>
<p id="e87a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Remember our iBeacon sketch?
Every iBeacon Transmitter needs to broadcast the following…</p>
<ol class="">
<li id="39d3" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc km kn ko"><strong
class="gr hh">iBeacon ID</strong>: Our iBeacon Transmitter shall broadcast this 16-byte iBeacon
ID, which looks like <code class="dm hj hk hl hm b">11111111111111111111111111111111</code> (in
hexadecimal). Upon sensing the iBeacon ID in the airwaves, the phone OS (iOS or Android) will <a
href="https://www.raywenderlich.com/632-ibeacon-tutorial-with-ios-and-swift"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">wake up our Mobile App</a>
thats linked to this iBeacon ID.</li>
<li id="cc3d" class="gp gq ec bk gr b gs kp gu kq gw kr gy ks ha kt hc km kn ko"><strong
class="gr hh">Major ID</strong>: A 16-bit number to differentiate iBeacon Transmitters</li>
<li id="523c" class="gp gq ec bk gr b gs kp gu kq gw kr gy ks ha kt hc km kn ko"><strong
class="gr hh">Minor ID</strong>: Another 16-bit number to differentiate iBeacon Transmitters</li>
</ol>
<p id="618c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">How are Major and
Minor IDs used?</em> Lets say we operate a chain of stores. All stores in the chain would use the
same Mobile App, so all iBeacon Transmitters in the stores should broadcast the same iBeacon ID.</p>
<p id="aa9d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">How would we
identify which store the customer has stepped into?</em> Easy… Just assign a unique Major ID for
each store! The app would be able to sense the Major ID from the iBeacon broadcasts and figure out
which store youre at.</p>
<p id="83d1" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Could we identify
which part of the store the customer is at?</em> Sure! Just assign a unique Minor ID for each
iBeacon Transmitter in the store. Heres how we broadcast the iBeacon ID, Major ID and Minor ID in
NimBLE…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/8da46373649da93dd313b5ae1a8c777d.js"></script></p>
</div>
<p id="9a20" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">In our code we used an arbitrary
iBeacon ID <code class="dm hj hk hl hm b">uuid128</code> thats defined as <code
class="dm hj hk hl hm b">11111111111111111111111111111111</code> (in hexadecimal). We pass the
iBeacon ID to <code class="dm hj hk hl hm b">ble_ibeacon_set_adv_data()</code>, together with Major ID
<code class="dm hj hk hl hm b">2</code> and Minor ID <code class="dm hj hk hl hm b">10</code>. When we
call <code class="dm hj hk hl hm b">ble_gap_adv_start()</code>, our nRF52 starts advertising itself as
an iBeacon.</p>
<p id="f1a1" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Theres one more parameter that
we passed to <code class="dm hj hk hl hm b">ble_ibeacon_set_adv_data()</code>… Measured Power, which
is the RSSI value at 1 meter: <code class="dm hj hk hl hm b">-60</code>. This value is broadcast by
the iBeacon, together with the other IDs.</p>
<p id="c2d0" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Since we are diving deep into
wireless transmission, lets study the meaning of RSSI, known to most of us as Signal Strength…</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="f2d6" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">How Near Is Our iBeacon?</h1>
<p id="1524" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc"><a
href="https://www.bluetooth.com/blog/proximity-and-rssi/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Received Signal Strength
Indication</a> (RSSI) is a common metric for measuring the Signal Strength of wireless networks like
WiFi, NB-IoT and Bluetooth LE. RSSI values are usually negative, and higher values denote stronger
signals (RSSI <code class="dm hj hk hl hm b">-50</code> is stronger than RSSI <code
class="dm hj hk hl hm b">-60</code>).</p>
<p id="14ec" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Why do iBeacons
broadcast their RSSI values?</em> So that we may estimate how near they are!</p>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o18.png" /></p>
<figcaption><p><em>Estimated Proximity for our nRF52 iBeacon in
the Locate Beacon app: 0.7 metres</em></p></figcaption>
</div>
<p id="4946" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Recall that we set our iBeacon
Transmitters Measured Power as <code class="dm hj hk hl hm b">-60</code>. According to the definition
of Measured Power, if we placed our mobile phone 1 metre away from our iBeacon Transmitter, the phone
would record the RSSI as <code class="dm hj hk hl hm b">-60</code>.</p>
<p id="c39e" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Thus if the RSSI recorded by the
phone was <code class="dm hj hk hl hm b">-50</code> or higher, the iBeacon Transmitter would probably
be close to the phone (within 1 metre). This gives us a simple way to estimate the distance between
the iBeacon Transmitter and our mobile phone.</p>
<p id="079c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">In the real world, the estimated
proximity of iBeacons is not really accurate. Bluetooth LE signals often clash with WiFi in the
crowded 2.4 GHz airwaves, so the RSSI values may fluctuate wildly. And when Bluetooth LE signals pass
through objects (like human bodies) the RSSI values will drop.</p>
<p id="cac4" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Its hard to do accurate distance
ranging for any kind of wireless signal (WiFi and NB-IoT included). But its good to understand what
RSSI means, and how wireless signals degrade when transmitting over long distances, passing through
obstacles.</p>
<p id="6bad" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">For more details on implementing
iBeacon Transmitters with NimBLE, check out the complete tutorial at <code
class="dm hj hk hl hm b"><a href="https://mynewt.apache.org/latest/tutorials/ble/ibeacon.html" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">https://mynewt.apache.org/latest/tutorials/ble/ibeacon.html</a></code>
</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="cz">
<div class="n p">
<div class="ky kz la lb lc ld ag le ah lf aj ak">
<div class="figure js jt ju jv jw cz lh li paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o19.jpeg" /></p>
<figcaption><p><em>Testing our nRF52 iBeacon with the “Locate
Beacon” mobile app</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="3a00" class="jb jc ec bk bj io ee ln eg lo jf lp jh lq jj lr jl">Test Our iBeacon</h1>
<p id="9ee9" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Lets use a real Mobile App to
verify that our nRF52 is indeed broadcasting as an iBeacon.</p>
<p id="a308" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><a class="at cg hd he hf hg"
target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/install-apache-mynewt-and-embedded-rust-for-nrf52-and-visual-studio-code-on-windows-and-macos">Follow
the instructions in this article</a> to flash and debug your nRF52 with an <a
href="https://www.aliexpress.com/wholesale?catId=0&amp;initiative_id=SB_20180924134644&amp;SearchText=st-link+v2&amp;switch_new_app=y"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">ST-Link V2 adapter</a>.</p>
<p id="76dd" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Start a debug session for nRF52
in Visual Studio Code. Whenever the program pauses at a breakpoint (this will happen twice), click
<code class="dm hj hk hl hm b">Continue</code> or press <code class="dm hj hk hl hm b">F5</code>. Keep
the nRF52 powered on.</p>
<p id="178f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Install the <strong
class="gr hh"></strong><a
href="https://apps.apple.com/us/app/locate-beacon/id738709014"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow"><strong class="gr hh">Locate
Beacon</strong></a><strong class="gr hh"></strong> app on your iPhone…</p>
<div class="hn ho hp hq hr hs"><a
href="https://apps.apple.com/us/app/locate-beacon/id738709014"
rel="noopener nofollow">
<section class="hv cl cm ak ce n ar hw hx hy hz ia ib ic id ie if ig ih ii ij ik">
<div class="il n co p im in">
<h2 class="bj io ip bl ec">
<div class="di ht fm fn hu fp">Locate Beacon</div>
</h2>
</div>
<div class="my r">
<div class="mz r na nb nc my nd ne nf"></div>
</div>
</section>
</a></div>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o20.png" /></p>
</div>
<p id="6840" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">1⃣ Launch the “Locate Beacon”
app on your iPhone.</p>
<p id="1df7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Tap the Gear icon at top right
</p>
<p id="0d42" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Tap <code
class="dm hj hk hl hm b">Add New UUID</code></p>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o0.png" /></p>
</div>
<div class="figure du cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o21.png" /></p>
</div>
<p id="da8b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">2⃣ Tap the <code
class="dm hj hk hl hm b">+</code> button at top right</p>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o0.png" /></p>
</div>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o0.png" /></p>
</div>
<div class="figure du cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o22.png" /></p>
</div>
<p id="c6cf" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">3⃣ Enter <code
class="dm hj hk hl hm b">My iBeacon</code> as the name</p>
<p id="e19a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">For the UUID, enter<br /><code
class="dm hj hk hl hm b">11111111111111111111111111111111</code></p>
<p id="e9df" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Leave the Major, Minor and Power
fields empty</p>
<p id="3d7f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Tap <code
class="dm hj hk hl hm b">Save</code></p>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o0.png" /></p>
</div>
<div class="figure du cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o23.png" /></p>
</div>
<p id="b2d7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">4⃣ Our nRF52 should appear in
the list of detected iBeacons as <code class="dm hj hk hl hm b">My iBeacon</code></p>
<p id="386d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Tap <code
class="dm hj hk hl hm b">My iBeacon</code></p>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o0.png" /></p>
</div>
<div class="figure du cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o24.png" /></p>
</div>
<p id="928d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">5⃣ Details of our iBeacon
appear, including the RSSI and estimated proximity.</p>
<p id="dfe2" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">How did I figure
out that my nRF52s Measured Power was </em><code class="dm hj hk hl hm b">-60</code>? By trial and
error!</p>
<p id="2ff6" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">I placed my phone 1 metre away
from the nRF52, then adjusted the Measured Power value until the estimated distance in the Locate
Beacon app showed 1 metre.</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="e10d" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Poll A Sensor With Rust</h1>
<p id="b82e" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Now lets talk about Embedded
Rust! As we have discovered, our Mynewt Project allows us to embed Rust modules and crates into our
Application Firmware (via sneaky substitution of the <code class="dm hj hk hl hm b">rust_app</code>
and <code class="dm hj hk hl hm b">rust_libcore</code> libraries). The <code
class="dm hj hk hl hm b">main()</code> function is defined in Rust, in fact.</p>
<p id="7318" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">But we havent seen Rust in
action while creating our iBeacon. <em class="hi">How can we be sure that Rust is indeed running
properly on our nRF52?</em></p>
<p id="ecb3" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Well prove that by <strong
class="gr hh">polling a Simulated Mynewt Sensor with Rust</strong>! Here how we do that…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/abc8db30b03f4aef9ea0bbc7f7554f31.js"></script></p>
<figcaption><p><em>Very first thing in any Mynewt Application:
Call sysinit(). From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs</a>
</em></p></figcaption>
</div>
<p id="8e2f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Our <code
class="dm hj hk hl hm b">main()</code> function is defined in the Rust module <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">rust/app/src/lib.rs</a></code>.
The first thing that happens in <code class="dm hj hk hl hm b">main()</code>: Call <code
class="dm hj hk hl hm b">sysinit()</code> to initialise the Mynewt libraries and drivers. (Mynewt
programs in C also call <code class="dm hj hk hl hm b">sysinit()</code> at startup)</p>
<p id="fd37" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">On the nRF52, <code
class="dm hj hk hl hm b">sysinit()</code> initialises the 2.4 GHz Radio Transceiver and the Stub
Temperature Sensor. Well talk about this simulated temperature sensor in a while.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/48c7069c26672cfcc7310e85b6b1ea76.js"></script></p>
<figcaption><p><em>Start polling the simulated temperature
sensor. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs</a>
</em></p></figcaption>
</div>
<p id="b467" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Remember we said that Mynewt
programs are designed to be portable across microcontrollers? The Rust-Mynewt application were
studying now actually runs fine on STM32 F103 (Blue Pill) and L476 microcontrollers… But they run a
little differently.</p>
<p id="c094" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">On STM32 microcontrollers, our
Rust application polls the onboard temperature sensor every 10 seconds and transmits the temperature
data to a server (via an NB-IoT module connected to the microcontroller).</p>
<p id="7c9a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">On the nRF52 we wont be
transmitting the sensor data to a server, so the code to start the Server Transport has been commented
out (for now).</p>
<p id="a445" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Next, we call <code
class="dm hj hk hl hm b">start_sensor_listener()</code> (defined in our application module <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">app_sensor.rs</a></code>)
to begin polling the simulated temperature sensor every 10 seconds.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/40d6de45a1e55ef1b447f1030d5b1d71.js"></script></p>
<figcaption><p><em>Start broadcasting as iBeacon. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs</a>
</em></p></figcaption>
</div>
<p id="7105" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Remember our C function <code
class="dm hj hk hl hm b">start_ble()</code> that initiates the iBeacon broadcasting? This is how we
call <code class="dm hj hk hl hm b">start_ble()</code> from <code
class="dm hj hk hl hm b">main()</code>. It needs to be tagged as <code
class="dm hj hk hl hm b">unsafe</code> because to the Rust Compiler, all C functions are risky and
could potentially cause problems (memory corruption, crashing, …) The <code
class="dm hj hk hl hm b">unsafe</code> tag will be removed once we create a safe and proper Rust
Wrapper for NimBLE.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/060053e8c27a4e063cc0cb4f739d51a5.js"></script></p>
<figcaption><p><em>Mynewt Event Loop. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/lib.rs</a>
</em></p></figcaption>
</div>
<p id="69f0" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">At the end of the <code
class="dm hj hk hl hm b">main()</code> function we have a standard Mynewt Event Loop to handle
Mynewt system events. (Mynewt programs in C also have this Mynewt Event Loop). Without this Event
Loop, the NimBLE functions will never get any processing done.</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="4258" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Mynewt Sensor Framework,
Enhanced With Rust</h1>
<p id="e0b1" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Lets look at <code
class="dm hj hk hl hm b">start_sensor_listener()</code>, defined in our application module <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">app_sensor.rs</a></code>...
</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/3fcd274796c5a5c3b4fec674ab091f88.js"></script></p>
<figcaption><p><em>Define the name of the Stub Temperature Sensor
and the polling interval. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs</a>
</em></p></figcaption>
</div>
<p id="275e" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">At the top of <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">app_sensor.rs</a></code>
we define some constants for polling the sensor.</p>
<p id="ef6d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b">SENSOR_DEVICE</code> is defined as <code
class="dm hj hk hl hm b">temp_stub_0</code>, which refers to the <strong class="gr hh">Stub
Temperature Sensor</strong>. The Stub Temperature Sensor works like a regular Mynewt Temperature
Sensor… Except that it always returns a hardcoded raw temperature value <code
class="dm hj hk hl hm b">1757</code>. Useful for testing sensor applications without connecting a
real temperature sensor. (On STM32 this program polls the actual onboard temperature sensor)</p>
<p id="7d2c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b">SENSOR_POLL_TIME</code> is set to 10,000 milliseconds, or 10 seconds. Well
be asking Mynewt to poll our simulated temperature sensor every 10 seconds.</p>
<p id="5e64" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Whats <code
class="dm hj hk hl hm b">Strn</code>? This is a custom string type that I have defined to make
passing of strings safer and more efficient. Mynewt APIs require all strings to be null-terminated;
Rust strings dont need the terminating null.</p>
<p id="36ba" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">If we pass strings back and forth
between Rust and the Mynewt APIs, we could end up creating many clones of the same string, with and
without terminating nulls. Or worse… Mynewt could crash because some Rust code has incorrectly passed
in a string thats not null-terminated. So I have wrapped the Mynewt APIs to accept the safer,
efficient <code class="dm hj hk hl hm b">Strn</code> type thats always null-terminated.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/fbe6082436e81f82222e483581751657.js"></script></p>
<figcaption><p><em>Fetch the Stub Temperature Sensor by name.
From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs</a>
</em></p></figcaption>
</div>
<p id="4a3a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Heres the first clue that Mynewt
has an awesome <strong class="gr hh">Sensor Framework</strong>… Mynewt keeps track of all installed
sensors by name. <code class="dm hj hk hl hm b">sensor_mgr::find_bydevname()</code> is the Mynewt API
that returns a list of sensors (i.e. a Sensor Iterator) that match a name (<code
class="dm hj hk hl hm b">temp_stub_0</code>).</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/b385670a3ba141e0ce9d29acad18c749.js"></script></p>
<figcaption><p><em>Set the polling interval for the Stub
Temperature Sensor. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs</a>
</em></p></figcaption>
</div>
<p id="3168" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Mynewt recognises every sensor
and the type of data that the sensor produces. So lets ask Mynewt to poll the sensor on our behalf!
</p>
<p id="d548" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">By calling <code
class="dm hj hk hl hm b">sensor::set_poll_rate_ms()</code> were kindly asking Mynewt to poll our
simulated temperature sensor every 10 seconds. <em class="hi">Truly awesome!</em></p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/7ce991cc8791de3a88c84fb5945d74b7.js"></script></p>
<figcaption><p><em>Create a Sensor Listener. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs</a>
</em></p></figcaption>
</div>
<p id="1fbd" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Now we fill in the nitty-gritty
polling details…<em class="hi"> What shall we do with the temperature sensor data after Mynewt has
obtained it?</em> Here we ask Mynewt to call our Rust function <code
class="dm hj hk hl hm b">aggregate_sensor_data()</code> with the sensor data.</p>
<p id="2fb5" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><code
class="dm hj hk hl hm b">aggregate_sensor_data()</code> is known as a Sensor Listener Function… Its
a function that listens for updated sensor data and acts on the data.</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/80245e18b0bcb4c24eaac6a47ae4dc6f.js"></script></p>
<figcaption><p><em>Register the Sensor Listener with Mynewt
Sensor Framework. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_sensor.rs</a>
</em></p></figcaption>
</div>
<p id="f399" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">To activate the Sensor Listener
Function, we call the Mynewt API <code class="dm hj hk hl hm b">sensor::register_listener()</code>.
Mynewt will begin polling the simulated temperature sensor every 10 seconds and call <code
class="dm hj hk hl hm b">aggregate_sensor_data()</code> with the polled temperature data.</p>
<p id="4178" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Polling a sensor
in Mynewt is really so easy… in C and in Rust</em>! Thats possible only because Mynewt has a
well-designed Sensor Framework.</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="c3e6" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Handle Sensor Data With Rust
</h1>
<p id="fc7b" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Remember that we dont transmit
sensor data to a server in the nRF52 version of the Rust application (unlike the STM32 version). But
well take a peek to understand how our sensor data could have been easily packaged and delivered to
an IoT server.</p>
<p id="b07f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Earlier we asked Mynewt to call
<code class="dm hj hk hl hm b">aggregate_sensor_data()</code> whenever it has polled our simulated
temperature sensor. Lets see what happens inside <code
class="dm hj hk hl hm b">aggregate_sensor_data()</code></p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/32744126701f2048ed9c4a38c77ac972.js"></script></p>
<figcaption><p><em>Aggregate temperature data with GPS data. From
<a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs</a>
</em></p></figcaption>
</div>
<p id="ae4a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">On the STM32 L476 microcontroller
our Rust application not only handles temperature sensor data… It handles <em class="hi">GPS latitude
/ longitude coordinates as well!</em> The application polls the GPS module for the current
geolocation (just like any Mynewt sensor) and attaches the geolocation to the temperature data before
transmitting to the server.</p>
<p id="4da2" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">On nRF52 well settle for less…
<code class="dm hj hk hl hm b">aggregate_sensor_data()</code> will simply transmit the temperature
data without attaching any GPS coordinates. It calls <code
class="dm hj hk hl hm b">send_sensor_data()</code> to transmit the temperature data…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/9fa6bd52409db33dfaa09f8cb84b35a3.js"></script></p>
<figcaption><p><em>Send sensor data to CoAP server. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs</a>
</em></p></figcaption>
</div>
<p id="790b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This sounds incredulous… But
<code class="dm hj hk hl hm b">send_sensor_data()</code> was designed to transmit <em class="hi">any
sensor data</em> in <em class="hi">any format</em> that will be understood by our server!</p>
<p id="26ab" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">For example, the code here works
perfectly for transmitting temperature data to the server at thethings.io. This server accepts CoAP
Messages with a JSON Payload that contains the geolocated sensor data.</p>
<p id="5ce1" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Yet strangely, <code
class="dm hj hk hl hm b">send_sensor_data()</code> doesnt contain any code thats specific to
thethings.io…<em class="hi"> The sensor data appears to transform itself magically for
thethings.io</em>. How is this possible? Well learn in a while…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/3b35e2b4b4af26ca615323396f05fdd7.js"></script></p>
<figcaption><p><em>Compose an outgoing CoAP message. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs</a>
</em></p></figcaption>
</div>
<p id="e72b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This is the end of the road for
nRF52… We havent started a Network Transport (like NB-IoT) that will deliver the sensor data to a
server, so nRF52 silently drops the sensor data here.</p>
<p id="ece0" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">For STM32, the Rusty trail
continues…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/469382be873bbc49acf5bab0c820cc36.js"></script></p>
<figcaption><p><em>Compose and transmit the JSON Payload
containing the temperature and GPS data. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/rust/app/src/app_network.rs</a>
</em></p></figcaption>
</div>
<p id="973e" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Believe it (or not)… <em
class="hi">Thats all the code we need</em> to transform our geolocated sensor data into this
complicated nested CoAP + JSON format mandated by thethings.io…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="7f4a" class="mi jc ec bk hm b ds mj mk r ml">{ &quot;values&quot;: [<br/> { &quot;key&quot; : &quot;t&quot;, <br/> &quot;value&quot;: 1757, <br/> &quot;geo&quot; : { &quot;lat&quot;: 1.2701, &quot;long&quot;: 103.8078 }},</span><span id="295c" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml"> { &quot;key&quot; : &quot;device&quot;,<br/> &quot;value&quot;: &quot;l476,bf39a9607e1187f6f3d80d6dd43&quot; }<br/>]}</span></pre>
<p id="eae0" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">The secret of the
sensor data transformation?</em> Its in the <code class="dm hj hk hl hm b">coap!()</code> macro!
</p>
<p id="8866" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><strong class="gr hh">Rust
Declarative Macros</strong> are incredibly powerful… A Rust macro can transform a simple JSON object
into a complicated nested CoAP + JSON monster. The <code class="dm hj hk hl hm b">coap!()</code> macro
hides the details of the data transformation. Thats why we can transmit <em class="hi">any sensor
data</em> in <em class="hi">any format</em> that will be understood by the server… Just let the
<code class="dm hj hk hl hm b">coap!()</code> macro handle it!</p>
<p id="b4b7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Thanks to Mynewt, the
transmission of sensor data is highly efficient. The CoAP Message is transmitted (over NB-IoT) by a
background task in Mynewt. So our application may continue processing sensor data without waiting for
the transmission to complete.</p>
<p id="9dc3" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Mynewt and Rust
are perfectly paired for building safe and efficient embedded systems!</em></p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="1b07" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Watch Rust Run On nRF52</h1>
<p id="ff21" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Ready to watch Rust run on nRF52?
All you need is an nRF52 development board and an <a
href="https://www.aliexpress.com/wholesale?catId=0&amp;initiative_id=SB_20180924134644&amp;SearchText=st-link+v2&amp;switch_new_app=y"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">ST-Link V2 adapter</a>.</p>
<p id="72aa" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><a class="at cg hd he hf hg"
target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/install-apache-mynewt-and-embedded-rust-for-nrf52-and-visual-studio-code-on-windows-and-macos">Follow
the instructions in this article</a> to flash and debug your nRF52.</p>
<p id="9c62" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The Output Log in Visual Studio
Code should look like this…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/90ac1dca567c53b00b0877cc47c5ae5e.js"></script></p>
<figcaption><p><em>Output Log from <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/logs/standalone-node.log"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/logs/standalone-node.log</a>
</em></p></figcaption>
</div>
<p id="a646" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Heres a video demo of the
Application Build and Debug on nRF52…</p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="ky kz la lb lc ld ag le ah lf aj ak">
<div class="figure js jt ju jv jw cz">
<div class="dl r dd">
<div class="nm r"><iframe
src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FwqimbvJeGMo%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DwqimbvJeGMo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FwqimbvJeGMo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube"
allowfullscreen="" frameborder="0" height="300" width="400"
title="nRF52 with Embedded Rust and Apache Mynewt" class="cp t u dh ak"
scrolling="auto"></iframe></div>
</div>
<figcaption><p><em>Video demo of the Application Build and
Debug on nRF52</em></p></figcaption>
</div>
</div>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="cz">
<div class="n p">
<div class="ky kz la lb lc ld ag le ah lf aj ak">
<div class="figure js jt ju jv jw cz lh li paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o25.png" /></p>
<figcaption><p><em>Polling sensors in Mynewt: Rust vs C
</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="4799" class="jb jc ec bk bj io ee ln eg lo jf lp jh lq jj lr jl">Why Embedded Rust Instead of
Embedded C?</h1>
<p id="60a5" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Take a look at the above Rust
code thats running on our nRF52 for polling the simulated temperature sensor. Compare that with the
equivalent C code.</p>
<p id="a51e" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Why is Rust better
than C?</em></p>
<p id="7df7" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Yes the Rust code looks more
verbose than C… But thats a good thing! C programming is so terse that it makes C difficult to learn.
Experienced C programmers (like me) are indeed a dying breed.</p>
<p id="545f" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Rust uses sensible keywords (like
<code class="dm hj hk hl hm b">fn</code> to denote functions, <code
class="dm hj hk hl hm b">let</code> for declaring variables), making it easier to learn. Note also
that the Rust code doesnt use any pointers. If you look at the C code, its really easy to misuse
pointers like <code class="dm hj hk hl hm b">listen_sensor</code> and <code
class="dm hj hk hl hm b">listener</code>… causing more problems and frustration to learners.</p>
<p id="dd13" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Error handling in Rust is done
elegantly… We use the <code class="dm hj hk hl hm b">?</code> operator to catch errors and exit early.
Compare that with the unsightly <code class="dm hj hk hl hm b">assert()</code> in C. What if we forget
to check the return code in C? Strange bugs ensue.</p>
<p id="9e4c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Why not code
EVERYTHING in Rust… Including Mynewt OS and NimBLE?</em></p>
<p id="0db9" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Theres an amazing community hard
at work creating <a
href="https://github.com/nrf-rs/nrf52-hal"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Rust on Bare Metal</a>. But it
will take a while to get it running and tested with real-world applications on nRF52, nRF51, STM32
F103, STM32 F476, RISC-V, …</p>
<p id="ca8d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Im solving this problem with a
different approach by applying <strong class="gr hh">Lean Principles</strong></p>
<p id="5a8a" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">You, the reader,
the learner, are my Customer</em>. You wish to build a safe and efficient Embedded Application
(hopefully in Rust). <em class="hi">What Rust APIs shall I provide you?</em></p>
<p id="a5be" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">I could build a Rust OS from
scratch based on Bare Metal Rust, and offer you a Native Rust API. But thats not very Lean.</p>
<p id="28d1" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Or I could take an embedded OS
thats already available, say Mynewt or Zephyr or FreeRTOS. Wrap it up with a clean Rust API, and give
that Wrapped Rust API to you instead.<em class="hi"> You wouldnt know the difference between the
Native and Wrapped Rust APIs!</em> (Unless I told you)</p>
<p id="c5b0" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">The Wrapped Rust API wont be
perfect, because as you create new gadgets with the API, you may find the API cumbersome or hard to
use. So Ill take this opportunity to evolve the API iteratively, till we get the Perfect Embedded
Rust API. (Thats how I evolved the Mynewt Sensor Framework with Rust Iterators)</p>
<p id="af04" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Now were ready to revamp the OS
with Rust and restructure it to implement the Perfect Embedded Rust API in the safest and most
efficient way possible.</p>
<p id="79a4" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This, I think, is the right
approach for solving the Embedded Rust problem. And it needs to happen soon (based on Mynewt or Zephyr
or FreeRTOS or …) so that we may quickly move embedded coders away from unsafe C and onto Rust.</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="c9e5" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Rust Wrappers for NimBLE</h1>
<p id="2bd3" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc"><em class="hi">Where are the Rust
Wrappers for the NimBLE API?</em> Since the Mynewt Sensor Framework already has Rust Wrappers, it
shouldnt be too difficult to create Rust Wrappers for NimBLE right?</p>
<p id="1b2e" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">Thats work in
progress</em>. With the Mynewt Sensor Framework I understand clearly how the API is used to read and
poll sensors under various situations. The Rust Wrappers for the Mynewt Sensor Framework were designed
for these use cases. With the NimBLE API… The use cases are still fuzzy to me.</p>
<p id="2fb8" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Some NimBLE applications appear
to have lots of repetitive code, <a
href="https://github.com/apache/mynewt-nimble/blob/master/apps/blemesh_models_example_2/src/device_composition.c"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">like this Bluetooth Mesh
application</a>. They could be greatly simplified with Rust Macros. Just like the <code
class="dm hj hk hl hm b">coap!()</code> Rust Macro we used for composing CoAP messages.</p>
<p id="d127" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><em class="hi">If you would like
to help out with the design of the Rust Wrappers for NimBLE, drop me a note!</em></p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="26e5" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">Whats Next?</h1>
<p id="2b30" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">Coding the nRF52 was an
incredible experience… Im finishing this tutorial only two weeks after touching nRF52 for the very
first time!</p>
<p id="afb8" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">I got big plans for nRF52 in
upcoming tutorials…</p>
<p id="92db" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">1<strong
class="gr hh">Bluetooth Mesh</strong>: What if we had a mesh network of nRF52 nodes that can relay
IoT sensor data to nearby nodes? One of these nodes could be a WiFi gateway (based on ESP8266) that
forwards the sensor data to an IoT server like thethings.io.</p>
<p id="8a54" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This will be an interesting
application of Bluetooth Mesh, which is <a
href="https://mynewt.apache.org/latest/network/docs/mesh/index.html"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">already supported in NimBLE</a>.
Here is the article…</p>
<div class="hn ho hp hq hr hs"><a rel="noopener"
href="https://lupyuen.github.io/articles/bluetooth-mesh-with-nrf52-and-apache-mynewt">
<section class="hv cl cm ak ce n ar hw hx hy hz ia ib ic id ie if ig ih ii ij ik">
<div class="il n co p im in">
<h2 class="bj io ip bl ec">
<div class="di ht fm fn hu fp">Bluetooth Mesh with nRF52 and Apache Mynewt</div>
</h2>
</div>
<div class="my r">
<div class="np r na nb nc my nd ne nf"></div>
</div>
</section>
</a></div>
<p id="1a9d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">2<strong
class="gr hh">PineTime Smart Watch</strong>: <a
href="https://www.cnx-software.com/2019/09/25/pinetime-smartwatch-specifications-released-availability-scheduled-for-h1-2020/"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">PineTime</a> is an upcoming smart
watch thats powered by nRF52. What if we could run Rust and Mynewt OS on this watch… And allow watch
apps to be built easily with <a
href="https://lupyuen.github.io/articles/visual-embedded-rust-programming-with-visual-studio-code"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Visual Rust</a>?</p>
<p id="c32b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">What if the watches could form a
mesh and relay each wearers vital signs (from the heart rate sensor)? And alert you if any of your
loved ones are uncontactable through the mesh network? No more missing kids / grandparents / friends /
hikers / swimmers / pets / …</p>
<p id="4df5" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">“Herding” sounds like a good name
for such Wearable Mesh apps. I have received the PineTime developer kit… Heres my review!</p>
<div class="hn ho hp hq hr hs"><a rel="noopener"
href="https://lupyuen.github.io/articles/sneak-peek-of-pinetime-smart-watch-and-why-its-perfect-for-teaching-iot">
<section class="hv cl cm ak ce n ar hw hx hy hz ia ib ic id ie if ig ih ii ij ik">
<div class="il n co p im in">
<h2 class="bj io ip bl ec">
<div class="di ht fm fn hu fp">Sneak Peek of PineTime Smart Watch… And why its perfect for
teaching IoT</div>
</h2>
</div>
<div class="my r">
<div class="nq r na nb nc my nd ne nf"></div>
</div>
</section>
</a></div>
<div class="hn ho hp hq hr hs"><a rel="noopener"
href="https://lupyuen.github.io/articles/building-a-rust-driver-for-pinetimes-touch-controller">
<section class="hv cl cm ak ce n ar hw hx hy hz ia ib ic id ie if ig ih ii ij ik">
<div class="il n co p im in">
<h2 class="bj io ip bl ec">
<div class="di ht fm fn hu fp">Building a Rust Driver for PineTimes Touch Controller</div>
</h2>
</div>
<div class="my r">
<div class="nr r na nb nc my nd ne nf"></div>
</div>
</section>
</a></div>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="cz">
<div class="n p">
<div class="ky kz la lb lc ld ag le ah lf aj ak">
<div class="figure js jt ju jv jw cz lh li paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o26.jpeg" /></p>
<figcaption><p><em>nRF52 connected to Raspberry Pi 4
</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="1285" class="jb jc ec bk bj io ee ln eg lo jf lp jh lq jj lr jl">Advanced Topic: Remove nRF52
Flash Protection With Raspberry Pi</h1>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o27.png" /></p>
<figcaption><p><em>From “nRF52832 — Product Specification” <a
href="https://infocenter.nordicsemi.com/pdf/nRF52832_PS_v1.0.pdf"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://infocenter.nordicsemi.com/pdf/nRF52832_PS_v1.0.pdf</a>
</em></p></figcaption>
</div>
<p id="5fdf" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Do you have problems flashing or
debugging your nRF52? Heres how you can fix it…</p>
<p id="9861" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">nRF52 has an <strong
class="gr hh">Access Port Protection</strong> feature that locks the nRF52 flash ROM from any
modification and prevents debugging. Access Port Protection is enabled in production devices, so that
people cant snoop into an nRF52 gadget and tamper with the ROM.</p>
<p id="871b" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Some nRF52 development boards
(including my EBYTE E73-TBB) are shipped with Access Port Protection enabled. Most developers use a <a
href="https://en.wikipedia.org/wiki/Segger_Microcontroller_Systems#J-Link"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">J-LINK</a> USB Programmer to
remove the Access Port Protection, but Ill show you how to use a Raspberry Pi (1, 2, 3 or 4) instead…
</p>
<p id="2744" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Connect your nRF52 board to a
Raspberry Pi 1 / 2 / 3 / 4 (powered off) as follows (refer to the photo above)…</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/8bda3c3fed0abfb96c5556b1b81ad598.js"></script></p>
<figcaption><p><em>Connecting nRF52 to Raspberry Pi. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.ocd"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.ocd</a>
</em></p></figcaption>
</div>
<div class="figure js jt ju jv jw cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o28.png" /></p>
<figcaption><p><em>Connecting nRF52 to Raspberry Pi. Based on <a
href="https://pinout.xyz/" class="at cg hd he hf hg"
target="_blank" rel="noopener nofollow">https://pinout.xyz/</a></em></p></figcaption>
</div>
<p id="e388" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Power on the Raspberry Pi. Open a
common prompt on the Raspberry Pi. Enter into the command prompt…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="1577" class="mi jc ec bk hm b ds mj mk r ml"># Build OpenOCD with CMSIS-DAP and GPIO support</span><span id="3992" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">sudo apt install wget git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev libhidapi-dev libftdi-dev telnet</span><span id="9070" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">git clone https://github.com/ntfreak/openocd</span><span id="854c" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">cd openocd</span><span id="a69c" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">./bootstrap</span><span id="8174" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">./configure --enable-sysfsgpio --enable-bcm2835gpio --enable-cmsis-dap</span><span id="1f2e" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">make</span><span id="3aa7" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml">cd ..</span><span id="8b97" class="mi jc ec bk hm b ds mm mn mo mp mq mk r ml"># Download the OpenOCD script<br/>wget https://raw.githubusercontent.com/lupyuen/stm32bluepill-mynewt-sensor/nrf52/scripts/nrf52/swd-pi.ocd</span></pre>
<p id="d5aa" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Edit the downloaded <code
class="dm hj hk hl hm b"><a href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.ocd" class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">swd-pi.ocd</a></code>
</p>
<p id="93e9" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Comment out the lines (insert
<code class="dm hj hk hl hm b">#</code> prefix) for <code
class="dm hj hk hl hm b">bcm2835gpio_peripheral_base</code> and <code
class="dm hj hk hl hm b">bcm2835gpio_speed_coeffs</code> under <code
class="dm hj hk hl hm b">Pi 4</code></p>
<p id="8c35" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Uncomment the lines (remove <code
class="dm hj hk hl hm b">#</code> prefix) for <code
class="dm hj hk hl hm b">bcm2835gpio_peripheral_base</code> and <code
class="dm hj hk hl hm b">bcm2835gpio_speed_coeffs</code> for your model of Raspberry Pi: <code
class="dm hj hk hl hm b">Pi 1 / 2 / 3 / 4</code></p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/31b53018d50208003a6f4994b68ed22f.js"></script></p>
<figcaption><p><em>OpenOCD script. From <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.ocd"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.ocd</a>
</em></p></figcaption>
</div>
<p id="d9eb" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Enter into the command prompt…
</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="8ddb" class="mi jc ec bk hm b ds mj mk r ml"># Start OpenOCD<br/>sudo /home/pi/openocd/src/openocd \<br/> -s /home/pi/openocd/tcl \<br/> -d4 \<br/> -f swd-pi.ocd</span></pre>
<p id="3b5d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">We should see the following log…
</p>
<div class="figure js jt ju jv jw cz">
<p><script src="https://gist.github.com/lupyuen/4ced61f3a28a4295971e7ce5ba37f409.js"></script></p>
<figcaption><p><em>OpenOCD Log from <a
href="https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.log"
class="at cg hd he hf hg" target="_blank"
rel="noopener nofollow">https://github.com/lupyuen/stm32bluepill-mynewt-sensor/blob/nrf52/scripts/nrf52/swd-pi.log</a>
</em></p></figcaption>
</div>
<p id="66e2" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">While OpenOCD is running, open a
second command prompt and enter…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="2b37" class="mi jc ec bk hm b ds mj mk r ml">telnet localhost 4444<br/>nrf52.dap apreg 1 0x0c</span></pre>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o29.png" /></p>
<figcaption><p><em>Checking the <code
class="dm hj hk hl hm b">APPROTECTSTATUS</code> status register for Access Port Protection
</em></p></figcaption>
</div>
<p id="9d74" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This queries the <code
class="dm hj hk hl hm b">APPROTECTSTATUS</code> status register for Access Port Protection.</p>
<p id="b852" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">It should show <code
class="dm hj hk hl hm b">0</code>, which means protection is enabled.</p>
<p id="4922" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Well now set the <code
class="dm hj hk hl hm b">ERASEALL</code> register to <code class="dm hj hk hl hm b">1</code> to
erase the flash ROM and remove Access Port Protection.</p>
<p id="beb6" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Enter the following commands into
the <code class="dm hj hk hl hm b">telnet</code> prompt.</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="eae9" class="mi jc ec bk hm b ds mj mk r ml">nrf52.dap apreg 1 0x04 0x01<br/>nrf52.dap apreg 1 0x04</span></pre>
<p id="8714" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This should show <code
class="dm hj hk hl hm b">1</code>, which means that the nRF52 is ready to be erased.</p>
<p id="9e4d" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Shut down and power off the
Raspberry Pi and nRF52 board.</p>
<p id="ce87" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Power on the Raspberry Pi and
nRF52 board. This performs the flash ROM erase.</p>
<p id="8f01" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">Start OpenOCD by entering into a
command prompt…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="f4c9" class="mi jc ec bk hm b ds mj mk r ml">sudo /home/pi/openocd/src/openocd \<br/> -s /home/pi/openocd/tcl \<br/> -d4 \<br/> -f swd-pi.ocd</span></pre>
<p id="5027" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">While OpenOCD is running, open
another command prompt and enter…</p>
<pre
class="js jt ju jv jw mf mg mh"><span id="e4cc" class="mi jc ec bk hm b ds mj mk r ml">telnet localhost 4444<br/>targets<br/>halt<br/>nrf52.dap apreg 1 0x0c</span></pre>
<div class="figure js jt ju jv jw cz dr jz cd ka kb kc kd ke ba kf kg kh ki kj kk paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy/o30.png" /></p>
<figcaption><p><em>Checking APPROTECTSTATUS status register for
Access Port Protection.</em></p></figcaption>
</div>
<p id="ffae" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">This queries the <code
class="dm hj hk hl hm b">APPROTECTSTATUS</code> status register for access port protection.</p>
<p id="eb8c" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">It should now show <code
class="dm hj hk hl hm b">1</code>, which means protection has been disabled.</p>
<p id="f8e5" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc">We may now disconnect the nRF52
from the Raspberry Pi and use ST-Link to flash and debug our nRF52!</p>
</div>
</div>
</section>
<hr class="is dy it iu iv dv iw ix iy iz ja" />
<section class="cu cv cw cx cy">
<div class="n p">
<div class="ac ae af ag ah dz aj ak">
<h1 id="19be" class="jb jc ec bk bj io ee jd eg je jf jg jh ji jj jk jl">References</h1>
<p id="5215" class="gp gq ec bk gr b gs jm gu jn gw jo gy jp ha jq hc">My code was tested on the <a
href="http://www.ebyte.com/product-view-news.aspx?id=644"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">EBYTE E73-TBB Development
Board</a>. The board is based on the <a
href="http://www.ebyte.com/en/product-view-news.aspx?id=243"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">EBYTE E732G4M04S1B</a> module,
which embeds the nRF52832 microcontroller.</p>
<p id="68fa" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><a
href="https://drive.google.com/file/d/1PiHg8TyQQ73C9MlE0wuMjKbdqV7xFpAb/view?usp=sharing"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Manual for EBYTE E732G4M04S1B
Module</a></p>
<p id="11ba" class="gp gq ec bk gr b gs gt gu gv gw gx gy gz ha hb hc"><a
href="https://drive.google.com/file/d/12z7ArTpealX9TsCqjVzrHC8ETt40Koib/view?usp=sharing"
class="at cg hd he hf hg" target="_blank" rel="noopener nofollow">Manual for EBYTE E73-TBB
Development Board</a> (Chinese)</p>
</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 20:18:03 Dec 17, 2019 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 23:07:51 Feb 22, 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):
exclusion.robots.policy: 0.272
CDXLines.iter: 24.786 (3)
RedisCDXSource: 0.626
captures_list: 115.484
esindex: 0.011
LoadShardBlock: 86.401 (3)
PetaboxLoader3.resolve: 25.205
PetaboxLoader3.datanode: 115.682 (4)
exclusion.robots: 0.283
load_resource: 96.568
-->