📄 Page
1
Simplified Embedded Rust: ESP Core Library Edition Omar Hiari
📄 Page
2
Simplified Embedded Rust: ESP Core Library Edition Omar Hiari October 13, 2024 v2.0
📄 Page
3
Preface Curiosity in learning can be likened to a journey with four distinct stages, each marked by its own challenges and rewards. In the initial stage, learners grapple with the fundamental question of ”what needs to be done?” It’s a phase characterized by a thirst for clarity and a reliance on clear instructions to navigate through new territories. As they progress to the second stage, the focus shifts towards the content itself. Here, burgeoning interest and growing confidence drive them to delve deeper, craving more knowledge and seeking engaging material to satisfy their curiosity. The transition to the third stage marks a pivotal moment as learners begin to grasp the practi- cal applications of the knowledge they’ve acquired. They yearn to understand not just the ”what” but also the ”how” and ”when” of utilizing their newfound skills. Finally, in the fourth stage, learn- ers embark on a journey of self-reflection, becoming more independent as they explore how this knowledge resonates with their personal experiences and aspirations. Throughout this journey, excitement must be nurtured and tended by educators who under- stand the importance of maintaining high levels of engagement. From my experience as an edu- cator, I’ve observed two distinct types of learners: thosewho are already deeply immersed in their curiosity, and those who are yet to find their passion for learning. The former, often at an advanced stage of curiosity, require less effort to sustain their enthusi- asm. Their innate drive and self-awareness propel them forward, eagerly absorbing content and seekingout challenges to conquer. However, for the latter group,whose curiositymaybedormant, the path to engagement is more involved. It requires better planning and innovative approaches to maintain high engagement levels. Figure 1 depicts how the level of excitement changes over time as a student through the cu- riosity stages over time. An educator would probably target to linearly increase the amount of excitement over time. Though, the target curve although linear probably has its bumps along the way. If the context of a typical embedded systems learning flow is introduced excitement is more difficult to attain. The second curve demonstrates this along with the tasks introduced over time shown in the x-axis. In the first stage of a traditional embedded learning journey, a student faces confusing tasks quite early. In particular, things like selecting a board and setting up environ- ments with different toolchains. This is when a student would have minimal knowledge about microcontrollers, hardware, and embedded tooling. Consider also for some students challenges of hardware accessibility and cost. As such, a student’s interest and curiosity can quickly decay making them hard to retain. 1
📄 Page
4
Le ve l o f E xc ite m en t Time Process Content Transfer Awareness Select Hardware Setup Toolchain Target Reality Knowledge Buildup & Basic Coding Exercise Projects Figure 1: Level of Excitement Over Time in Learning Embedded Systems Contrast this journey in Figure 1 to learning any coding language nowadays, including Rust. Essentially all one has to do is spawn a browser window and type in code that runs right away. A process that’s on the order of minutes or less. This by itself probably instantly raises levels of excitement to encourage one to keep on going. Examining things fromanembeddedRust angle, an additional task is added into themix. For a beginner, there aremany great existing resources. However, inmyopinion, they aremore oriented toward the first type of student who is already self-aware and at an advanced stage of curiosity. This is in the sense that many tackle embedded Rust education from an angle of what Rust adds to embedded as opposed to learning embedded with Rust. This can be tough for a newcomer to the embedded field or even for one already in it. In addition to the latter,within theembeddedRust ecosystem, different approaches/platforms have been evolving for different devices. Terms like std, no-std, HAL, trait HALs, RTIC, Embassy, and the list goes on. All in addition to navigating the different ecosystems, and finding out what is needed from documentation. This adds more stress and intimidation to a beginner in the early stages of curiosity. As a writer and educator, I’ve made it my mission to alleviate the barriers that hinder the early phases of learning embedded Rust. This book is born out of a desire to streamline the process, to eliminate the daunting obstacles that often deter aspiring learners from embarking on their journey into the world of embedded systems and Rust programming. In today’s digital age, we are fortunate to have tools likeWokwi that allowus to dive into coding without the cumbersome setup of toolchains or hardware. Yet, amidst this wealth of resources, I found myself drawn to the appeal of Espressif’s ESP32 devices. Their seamless integration with Rust, coupled with the unwavering support of the Espressif team, presents a compelling gateway for learners to explore the realm of embedded Rust programming. 2
📄 Page
5
Espressif’s commitment to providing standard library access for embedded Rust further sim- plifies the learning curve, offering a familiar environment for beginners to ease into the intricacies of embedded development. It’s a testament to their dedication to fostering a vibrant and inclusive community of learners and creators. In the pages that follow, I aim to demystify the complexities of embedded Rust programming, guiding readers through a journey of discovery that is both enriching and rewarding. Drawing upon my own experiences and insights, I hope to inspire a new generation of learners to embrace the challenge and excitement of mastering this dynamic field and nurture their inner Ferris. In the end, my true belief is that once one becomes accustomed to the elegance and power of Rust, there’s no turning back. It’s a journey of transformation that I hope to facilitate, guiding others along the path to proficiency and igniting a passion for learning thatwill endure far beyond the pages of this book. 3
📄 Page
6
Book Resources Source Code & Project Links All applicationexampleWokwi links and the latest source codearemaintainedon thebookGitHub Repository found at https://github.com/theembeddedrustacean/ser-no-std Software & Hardware Resources This book harnesses the transformative power ofWokwi, an innovative embedded systems & IoT simulator that supports Rust on Espressif devices. It empowers you to code, tinker, and build projects without the need for physical hardware components, providing a seamless and acces- sible learning experience. The book offers pre-wired Wokwi project templates, carefully crafted to allow you to immerse yourself in learning and coding without distractions. By eliminating the complexities of wiring, toolchain installations, and driver configurations, you can focus your en- ergy on mastering the material at hand. To kickstart your journey, it is highly recommended to explore the book’s content usingWokwi before venturing into physical hardware tinkering. This approach ensures a smooth and enjoy- able learning curve, allowing you to grasp the concepts thoroughly before embracing the tangi- ble realm of embedded systems development. Once you gain confidence and proficiency, you’d need to first purchase hardware components. The bill of material, with links to streamline your transition to hands-on projects is conveniently available on the book’s GitHub repository (https: //github.com/theembeddedrustacean/ser-no-std). After acquiring the components, you’d setup a development environment on your PC. This includes installing the necessary toolchains to download code and debug the ESP hardware, in addition to generating projects. The environment setup is covered in both Appendix A and the book GitHub repository. Book Updates The ESP Rust ecosystem is under development and not completely stable yet. This means that abstractions are subject to frequent change and errors might emerge. This is especially if newer 4
📄 Page
7
library or compiler versions are used that are not compatible with the abstractions used in this book. You can minimize this effect by sticking to the crate and compiler versions used for the examples in this book. However, this might not always be feasible since, unless you have your local development environment, the compiler version depends onWokwi. To address the ecosystem stability issue, this book offers an option for an ebook version that will be updated on regular basis. While itmight prove difficult to do the same for hardcopies, each book has a version that is captured on the cover page. One would need to look up the GitHub re- lease that coincides with the same version. Additionally, this book will make you familiar enough to be able to adjust to new crate versions when they emerge. For that, it becomes essential to understand how to navigate HAL documentation. Section 4.5 in this book is dedicated to that purpose. Issue Reporting If you notice or find any issues in the book, please create an issue on the book GitHub reposi- tory (https://github.com/theembeddedrustacean/ser-no-std). Suggestions for enhance- ment or expanding the book are also welcome. Other Useful Resources This book aims to give a good starting point and foundational knowledge in kicking off your em- bedded Rust journey. As with any other resource, it is by no means comprehensive as the world of embedded Rust is constantly growing and changing. Consequently, it becomes necessary to append your knowledge with additional sources to stay on top of things. That being said, here are some other resources that you might find useful: • Awesome Embedded Rust GitHub Repository: This repository is maintained by the em- bedded working group resource team. The repository contains a curated list of resources related to embedded Rust programming. https://github.com/rust-embedded/awesome-embedded-rust • TheRust onESPBook: This book provides a great starting guide for using Rust with Espres- sif devices. Especially updates that have to do with tooling and project templates. https://esp-rs.github.io/book/ • AwesomeESPRustGitHubRepository: This repository ismaintainedbyEspressif andcon- tains a curated list of resources related to embedded Rust programming on ESPs. https://github.com/esp-rs/awesome-esp-rust • The Embedded Rustacean Newsletter: This is a periodical with embedded Rust curated news and resources. https://www.theembeddedrustacean.com/subscribe 5
📄 Page
8
• TheEmbeddedRustaceanBlog: This is ablogmaintainedby theauthorof thisbook. Weekly posts about embedded and/or Rust are posted. This includes insights, tutorials, and code examples. https://blog.theembeddedrustacean.com/ • Wowki Discord: The Wokwi discord has a helpful community and a channel dedicated to Rust. This resource would be particularly useful when running into issues withWokwi. https://wokwi.com/discord 6
📄 Page
9
How to Approach this Book Rust knowledge is required! Ideally, one would be familiar with concepts up to chapter 10 of ”The Book”(https://doc.rust-lang.org/book/). While you might not be coding using many of the advanced concepts in ”The Book”, some terms might emerge. As such, familiarity would be beneficial. This book is divided into three main parts: 1. Chapters 1 to 3 offer a generic overview of the embedded space and microcontrollers. This also includes chapters relative to embedded Rust and ESP hardware. If you feel comfortable with that knowledge, you might just skim through the pages. 2. Chapter 4explains thebasicproject setupandalsoexplainshowthecodeexamples through- out the book are structured. It is highly recommended that you familiarize yourself with this before proceeding with the rest of the book. This is a good starting point if you want to dig straight into coding. 3. Finally, the remaining chapters of the book focus on coding. The chapters either cover a peripheral or a platform/framework. In each chapter, first, a general overview of the theo- ry/concept is given, followed by the abstractions associated, and then a code example. 7
📄 Page
10
Contents 1 Introduction 13 1.1 What’s an Embedded System? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.2 Trends in Embedded Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.3 Why Rust? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2 Microcontroller Concepts 23 2.1 Microcontroller vs Microprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.2 So what’s an SoC? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.3 Microcontroller Processor Architectures . . . . . . . . . . . . . . . . . . . . . . . . 25 2.3.1 The Instruction Set Architecture . . . . . . . . . . . . . . . . . . . . . . . . 25 2.3.2 Memory Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.4 Peripherals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.5 The Pin Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 2.6 Polling & Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.6.1 Polling vs. Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.6.2 A Bit More on Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 2.6.3 SoWhen Do I UseWhich? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.7 Memory Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 2.8 Application Memory Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.9 Clocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.10 Development Environments and Toolchains . . . . . . . . . . . . . . . . . . . . . 41 2.10.1 Bare Metal vs RTOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 2.10.2 Compiler Toolchains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 2.10.3 Debug Toolchains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3 Embedded Rust & ESP 45 3.1 About ESPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.2 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.3 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.3.1 Standard Library vs. Core Library . . . . . . . . . . . . . . . . . . . . . . . 47 3.3.2 The Rust ESP Ecosystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 8
📄 Page
11
CONTENTS 3.4 Development Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 3.5 Book Reference Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4 Programming Embedded Applications 52 4.1 Creating a Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.2 The Basic Project Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.2.1 The main.rs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.2.2 The Cargo.toml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.3 Coding Examples Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.4 Embedded Application Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.5 Navigating Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.6 Debugging Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.6.1 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.6.2 LEDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 4.6.3 In-Circuit Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 4.6.4 Logic Analyzers and Oscilloscopes . . . . . . . . . . . . . . . . . . . . . . . 61 4.6.5 Profilers and Network Sniffers . . . . . . . . . . . . . . . . . . . . . . . . . 62 4.6.6 Combining Debugging Approaches . . . . . . . . . . . . . . . . . . . . . . 62 4.6.7 Debugging inWokwi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5 Programming GPIO 64 5.1 Introduction to GPIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 5.1.1 Active State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 5.1.2 ESP32-C3 GPIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5.1.3 Configuring GPIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5.1.4 Interacting with GPIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.2 Application Example: Blinky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.2.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.2.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.2.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.2.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 5.3 Application Example: Button Controlled Blinking . . . . . . . . . . . . . . . . . . . 79 5.3.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.3.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.3.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.3.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5.4 Application Example: Button Press Counter . . . . . . . . . . . . . . . . . . . . . . 85 5.4.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 5.4.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 5.4.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 5.4.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 9
📄 Page
12
CONTENTS 5.5 Questions & Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 6 Programming ADCs 94 6.1 Introduction to ADCs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.1.1 ESP32-C3 ADCs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 6.1.2 Configuring ADCs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 6.1.3 Interacting with ADCs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.2 Application Example: SimpleVoltmeter . . . . . . . . . . . . . . . . . . . . . . . . 104 6.2.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.2.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.2.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.2.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.3 Application Example: Temperature Sensing . . . . . . . . . . . . . . . . . . . . . . 108 6.3.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 6.3.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 6.3.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 6.3.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 6.4 Questions & Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 7 Programming Timers & Counters 116 7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 7.1.1 ESP32-C3 Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 7.1.2 Configuring Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 7.1.3 Interacting with Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 7.2 Application Example: Timer Based Delay . . . . . . . . . . . . . . . . . . . . . . . 125 7.2.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 7.2.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 7.2.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 7.2.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 7.3 Application Example: Real-time Timer . . . . . . . . . . . . . . . . . . . . . . . . . 129 7.3.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7.3.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7.3.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7.3.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 7.4 Questions & Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 8 Programming PWM 138 8.1 Introduction to PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 8.1.1 ESP32-C3 PWM Peripherals . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 8.1.2 Configuring PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 8.1.3 Interacting with PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 10
📄 Page
13
CONTENTS 8.2 Application Example: LED Fading . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 8.2.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 8.2.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 8.2.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 8.2.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 8.3 Questions & Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 9 Programming Serial Communication 154 9.1 Introduction to Serial Communication . . . . . . . . . . . . . . . . . . . . . . . . . 154 9.1.1 UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 9.1.2 The ESP32-C3 UART Peripheral . . . . . . . . . . . . . . . . . . . . . . . . . 156 9.1.3 Configuring UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 9.1.4 Interacting with UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 9.1.5 I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 9.1.6 The ESP32-C3 I2C Peripheral . . . . . . . . . . . . . . . . . . . . . . . . . . 162 9.1.7 Configuring I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 9.1.8 Interacting with I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 9.2 Application Example: UART Console Printing . . . . . . . . . . . . . . . . . . . . . 164 9.2.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 9.2.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 9.2.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 9.2.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 9.3 Application Example: Interacting with an I2C Real-Time Clock . . . . . . . . . . . 168 9.3.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 9.3.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 9.3.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 9.3.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 9.4 Questions & Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 10 The Embassy Framework 182 10.1 Getting Started with Embassy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 10.2 Syncronization Primitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 10.2.1 Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 10.2.2 Reading/Writing from Multiple Tasks . . . . . . . . . . . . . . . . . . . . . 187 10.2.3 Reading/Writing Across async Tasks . . . . . . . . . . . . . . . . . . . . . . 191 10.2.4 Wait for Value Change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 10.3 Application Example: Blinky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 10.3.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 10.3.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 10.3.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 10.3.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 11
📄 Page
14
CONTENTS 10.4 Application Example: Real-time Timer . . . . . . . . . . . . . . . . . . . . . . . . . 200 10.4.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 10.4.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 10.4.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 10.5 Application Example: LED Cycling . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 10.5.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 10.5.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 10.5.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 10.5.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 10.6 Application Example: UART Echo . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 10.6.1 Hardware Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 10.6.2 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 10.6.3 Code Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 10.6.4 Full Application Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 10.7 Questions & Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 A Setting up a Development Environment 222 A.1 Tool Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 A.2 Project Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 12
📄 Page
15
Chapter 1 Introduction Embeddeddevelopmenthasundergonea remarkable evolutionover the years, transforming from the realm of constrained, mission-specific devices to a landscape of boundless possibilities. Once confined to air-gapped systems operating in isolation, embedded applications now span a spec- trum of functionalities, from edge AI to software-defined hardware, pushing the boundaries of performance and complexity. Traditionally, languages like C and C++ have been the stalwarts of embedded development, adeptly serving the needs of the industry for decades. However, the evolving nature of embedded systems demands a shift from the status quo. As applications grow increasingly sophisticated and the demand for safety and security reaches new heights, the reliance on the status quo becomes untenable. Addressing the demands of future embedded applications necessitates embracing modern, high-performing languages that offer enhanced safety and security features. Among the con- tenders, Rust has emerged as a formidable choice, poised to revolutionize the embedded land- scape with its unique blend of performance, safety, and expressiveness. The embedded Rust space is experiencing rapid growth, with major players frequently join- ing the fray, propelling the ecosystem forward. Simultaneously, educational materials focused on embedded Rust are witnessing significant improvements, providing learners with the resources needed to stay ahead of the curve. This book sets out to equip readers with the knowledge and skills necessary to navigate the evolving landscape of embedded Rust programming, with a particular focus on the ESP devices and the Rust core library. It begins by laying down foundational concepts in embedded systems, offering insights into microcontrollers and providing an overview of the Espressif hardware and software ecosystem. Subsequent chapters delve into programming different peripherals, guiding readers through practical examples and hands-on exercises. Whether you’re a seasoned Rustacean looking to explore theworld of embedded development or an embedded developer venturing into the realm of Rust, this book is tailored to meet your needs. Additionally, individuals who are new to both embedded systems and Rust will find the book to be a comprehensive resource for diving into this exciting intersection of technology. 13
📄 Page
16
CHAPTER 1. INTRODUCTION What’s an Embedded System? With a focus on leveraging the power of the Rust core library, this book aims to bridge the gap between traditional embedded development and modern programming paradigms, making embedded Rust programming accessible and intuitive. Join me on this journey as I embark on a transformative exploration of embedded systems with Rust at its core. 1.1 What’s an Embedded System? Embedded systems are your digital access to the physical analog world. Embedded systems are composed of a computing element at their core just like traditional computers. And while tradi- tional computers focus on interfacing with humans, embedded systems focus on interfacingwith the environment. Because of this, embedded systems can be more focused in nature. This means that embedded systems have a more specific computational focus compared to traditional com- puters. For example, consider a regular personal computer (PC). It needs to focus on providing a seamless user experience, even for tasks thatmay seem lightweight to humans. This includes han- dling word processing while performing an online software update, streaming music, monitoring keyboard and mouse inputs, updating the monitor display, and many other tasks simultaneously. In contrast, an embedded system would be designed to perform a specific, focused task. For in- stance, an embedded system might capture the value from a temperature sensor and adjust the fan speed accordingly. Even if there is user input involved, it would typically be quite simplistic, such as a few buttons to configure a set point. Unlike traditional computers, embedded systems are designed to interface with the physical environment rather than primarily interacting with human users. Embeddedsystemsareoften referred toasmission-specific computingdevices, given the scope of their work. While this definition has changed a bit in recent times, it more or less still holds true for many applications. As Figure 1.1 shows, at the heart of the embedded system, is an electronic control unit (ECU)which typically incorporates amicrocontroller device. On one end, an embed- ded systemreceivesphysical inputs from the environment throughbuttons, sensors, and switches amongothers. These inputs are processedby themicrocontroller andon the other end, themicro- controller in turn controls different actuator outputs like motors, lights, screens, or speakers. An embedded system can run independently but can also interact with a larger system (Ex. in a car). Thismeans that an embedded system can have an interface that enables communicationwith the digital world. The communication interface can be eitherwired like a serial interface (Ex. UARTor USB) or wireless (Ex. WiFi or Bluetooth). This communication interface can enable connections with other input and output devices as well. Some examples of embedded systems are shown in Figure 1.2. Given the nature of such ap- plications and their requirements, embedded systems often operate under several constraints. Embedded systems need to be small in size, not power-hungry, physically lightweight, and cost- efficient. Take for example the game console controller. It needs to be small enough for a gamer to handle comfortably andnot be heavy. Also, the controller needs to be able to run adecent amount of time without needing a charge. Finally, there are probably millions of these controllers man- 14
📄 Page
17
CHAPTER 1. INTRODUCTION Trends in Embedded Systems Communication Interface - Temperature Sensor - Pressure Sensor - On/Off Switch - Motor - LED Light - Speaker - LCD Screen - WiFi - Ethernet - Bluetooth - UART Environment Inputs Electronic Control Unit Control Outputs Examples: Examples: Examples: Figure 1.1: Embedded System Block Diagram ufactured so they cannot be too expensive, and every penny counts. Compare this to a regular non-embedded computer, the considerations are totally different. 1.2 Trends in Embedded Systems Embedded systems are poised for remarkable growth, fueled by the Internet of Things and Indus- try 4.0, but face inherent constraints like limited computational power, storage, and connectiv- ity. While innovative architectural approaches help overcome these limitations, the industry of- ten follows a ”learn, adapt, and optimize” approach, tailoring technological advancements from other domains to meet embedded systems’ unique requirements. This phenomenon, driven by necessity, fosters innovation in areas like power efficiency, hardware acceleration, and optimiza- tion techniques. By embracing continuous learning, adaptation, and innovation, the embedded systems industry can leverage the latest advancements while addressing its unique constraints, enabling the development of increasingly capable and efficient intelligent, connected devices. Some of the current trends in embedded include the following: 1. Artificial Intelligence (AI): As theworld continues to embrace the transformative potential of artificial intelligence (AI), its impact onembedded systems is rapidly gainingmomentum. While non-embedded fields have alreadywitnessed impressive AI applications, the integra- tion of AI capabilities into embedded systems promises to unlock a new realm of possibili- ties, particularly in domains such as the Internet of Things (IoT), edge AI, automotive, and Industry 4.0. However, this integration is not without its challenges. One of the most significant hur- dles lies in the computational power required to train and deploy AI models within the con- straints of embedded systems. Traditional approaches, which involve transmitting raw data 15
📄 Page
18
CHAPTER 1. INTRODUCTION Trends in Embedded Systems Figure 1.2: Examples of Embedded Systems to the cloud for processing, present limitations in terms of power consumption and latency, making them less than ideal for power-constrained devices. To address these challenges, several platforms have emerged to support embedded AI, in- cludingTinyML,Tensor Flow Lite, PytorchMobile, OpenVINO,Nvidia Jetson, Edge Impulse, Caffe 2, and MXNet, among others. These platforms aim to optimize AI models for deploy- ment on resource-constrained devices, enabling a wide range of use cases to benefit from AI capabilities. One of the most promising applications of embedded AI lies in predictive maintenance in manufacturing environments. By leveragingAImodels trained on sensor data,manufactur- ers can anticipate equipment failures and schedule maintenance proactively, minimizing downtime and maximizing operational efficiency. Similarly, smart structure health mon- itoring systems can employ AI to detect and predict structural deficiencies, ensuring the safety and longevity of critical infrastructure. In the realm of agriculture, AI-powered plant health monitoring systems have the poten- tial to revolutionize crop management practices. By analyzing sensor data and visual cues, these systems can identify early signs of disease, nutrient deficiencies, and other potential threats, enabling timely interventions and optimizing crop yields. As the demand for intelligent, connected devices continues to grow, the adoption of em- bedded AI is poised to accelerate. While challenges remain, the ongoing advancements in hardware and software solutions are paving the way for a future where intelligent decision- making and automation are seamlessly integrated into the fabric of our everyday lives. 2. System on Chip (SoC): The System-on-Chip (SoC) trend in embedded systems has been a driving force behind the increased usage of operating systems, virtualization, and the en- ablement of containers. As embedded devices become more complex and feature-rich, the 16
📄 Page
19
CHAPTER 1. INTRODUCTION Trends in Embedded Systems need for sophisticated software architectures and resource management has grown signifi- cantly. Traditionally, embedded systems relied heavily on bare-metal programming, where appli- cations were designed to run directly on the hardware without an underlying operating sys- tem. However, as SoCs integrate multiple processors, specialized hardware accelerators, and vast amounts of memory, the complexity of managing these resources efficiently has become a daunting task. Enter operating systems for embedded devices. Operating systems like Embedded Linux, FreeRTOS, Zephyr, and others provide a layer of abstraction that simplifies resource man- agement, task scheduling, and inter-process communication. By leveraging an operating system, embedded developers can focus on building their applications while relying on the OS to handle low-level hardware interactions and resource allocation. Moreover, the power and scalability of modern SoCs have paved the way for virtualization in embedded systems. Virtualization allows multiple operating systems or environments to run concurrently on a single hardware platform, effectively consolidating resources and enabling efficient workload isolation. This capability is particularly valuable in applications that require robust security, fault isolation, or the ability to run multiple software stacks simultaneously. Virtualization technologies like containerization have also gained traction in the embed- dedworld, driven by the need for lightweight, portable, and scalable software deployments. Containers encapsulate applications and their dependencies into self-contained packages, enabling seamless distribution and execution across diverse hardware platforms. This ap- proach simplifies application deployment, updates, and maintenance, while ensuring con- sistent behavior regardless of the underlying hardware configuration. Furthermore, the combination of SoCs and virtualization has opened up new possibilities for embedded systems to leverage cloud-native technologies and architectures. By running containerized workloads on embedded devices, developers can leverage the same tools, processes, and best practices used in cloud computing, fostering a more seamless integra- tion between edge devices and cloud platforms. While the adoption of operating systems, virtualization, and containers in embedded sys- tems introduces additional complexity, it also unlocks new levels of flexibility, scalability, and efficiency. As SoCs continue to evolve, offering even more powerful and integrated ca- pabilities, these software architectures will become increasingly crucial for harnessing the full potential of embeddedhardware and enabling the development of sophisticated, highly capable embedded applications. 3. Software-Defined Platforms: The tech industry has witnessed a significant shift towards software-definedhardware, aparadigmthat empowers software to exert greater control over hardware functionality. This approach offers numerous advantages, including increased 17
📄 Page
20
CHAPTER 1. INTRODUCTION Trends in Embedded Systems customization, streamlined product updates, and reduced overhead in designing custom hardware for every new application. At its core, a software-defined platform presents a generic hardware platform that can be programmatically controlled and configured through software. This paradigm diminishes the need for designing specialized hardware solutions for each emerging application, pro- moting a more agile and adaptable development cycle. The wireless and networking domains have been at the forefront of adopting this paradigm, with software-defined radio (SDR)andsoftware-definednetworking (SDN) servingaspromi- nent examples. In the case of SDRs, the physical layer of a radio device can be programmed to perform virtually any radio function, rendering the hardwaremore portable, flexible, and maintainable. Moreover, theautomotive industry is exhibiting strong indicationsof embracing thisparadigm through the concept of software-defined vehicles (SDVs). By leveraging software-defined hardware, automakers can potentially streamline the integration of new features, enhance vehicle customization, and facilitate over-the-air updates, thereby future-proofing vehicles and extending their functional lifespans. As the technology landscapecontinues toevolveat a rapidpace, the software-definedparadigm presents a compelling solution to the challenges of hardware obsolescence and limited flex- ibility. By decoupling software from hardware dependencies, this approach empowers de- velopers to create more versatile, adaptable, and future-ready solutions, ultimately driving innovation and accelerating the pace of technological progress. 4. Security: The embedded systems landscape finds itself in a predicament reminiscent of the early days of the internet, where security considerations were an afterthought. Much like the internet’s initial inception as ”a group of mutually trusting users,” embedded devices have historically operated in isolation, with little emphasis placed on implementing robust security measures. This oversight has paved the way for numerous vulnerabilities, such as leaving critical memory content unencrypted and JTAG pins exposed, essentially inviting potential attackers to gain unauthorized access to sensitive data. The advent of the Internet of Things (IoT) and the integration of connectivity into edge de- vices has further exacerbated the security challenges faced by embedded systems. The in- famous Jeep hacking incident in 2015, which led to a 1.4 million vehicle recall by Chrysler, serves as a stark reminder of the embedded industry’s need toprioritize security andaddress vulnerabilities proactively. While the journey towards achieving robust security in embedded systemsmay seemdaunt- ing, the industry can draw inspiration from the well-established security practices devel- oped for web applications. These practices, primarily focused on mitigating software and network-based attacks, offer a solid foundation upon which embedded systems security can be built. 18