Merge branch 'main' of github.com:ferrous-systems/embedded-trainings-2020 into edit-book

This commit is contained in:
Mirabellensaft 2020-07-16 10:33:19 +02:00
commit d75b61af56
13 changed files with 132 additions and 56 deletions

View file

@ -2,8 +2,9 @@
Material for the beginner and advanced workshops of Oxidize Global (15.07.2020).
Website for this workshop: [https://embedded-trainings.ferrous-systems.com][book]
[book]: https://embedded-trainings.ferrous-systems.com
## Required hardware

View file

@ -3,6 +3,7 @@
- [Preparations](./preparations.md)
- [Checking the Hardware](./hardware.md)
- [Installation Instructions](./installation.md)
- [Tooling check](./tooling-check.md)
- [Beginner Workbook](./beginner-workbook.md)
- [Parts of an Embedded Program](./parts-embedded-program.md)
- [Building an Embedded Program](./building-program.md)

View file

@ -1,23 +1,28 @@
# Advanced Workbook
# `advanced`
In this workshop you'll learn to:
> Advanced workshop
- work with registers and peripherals from Rust
- handle external events in embedded Rust applications
- debug evented applications
- test `no_std` code
In this workshop we'll build a toy USB device application that gets enumerated and configured by the host.
To put these concepts and techniques in practice you'll write a toy USB device application that gets enumerated and configured by the host. This embedded application will run in a fully event driven fashion: only doing work when the host asks for it.
The embedded application will run in a fully event driven fashion: only doing work when the host asks for it.
You have received two development boards for this workshop. We'll only use the nRF52840 Development Kit, the larger of the two, in the advanced workshop.
## The nRF52840 Development Kit
The board has two USB ports: J2 and J3 and an on-board J-Link programmer / debugger -- [there are instructions to identify the ports in a previous section][id-ports]. USB port J2 is the J-Link's USB port. USB port J3 is the nRF52840's USB port. Connect the Development Kit to your computer using both ports.
[id-ports]: ./hardware.md#nrf52840-development-kit-dk
## The nRF52840
Some details about the nRF52840 microcontroller that are relevant to this workshop.
Both development boards have an nRF52840 microcontroller. Here are some details about it that are relevant to this workshop.
- single core ARM Cortex-M4 processor clocked at 64 MHz
- 1 MB of Flash (at address `0x0000_0000`)
- 256 KB of RAM (at address `0x2000_0000`)
- IEEE 802.15.4 and BLE (Bluetooth Low Energy) compatible radio
- USB controller (device function)
## The nRF52840 Development Kit
The development board we'll use has two USB ports: J2 and J3 -- you can find a description of the board in the top-level README of this repository -- and an on-board J-Link programmer / debugger. USB port J2 is the J-Link's USB port. USB port J3 is the nRF52840's USB port. Connect the Development Kit to your computer using both ports.

View file

@ -1 +1,35 @@
# Beginner Workbook
In this workshop you'll get familiar with:
- the structure of embedded Rust programs,
- the existing embedded Rust tooling, and
- embedded application development using a Hardware Abstraction Layer (HAL).
To put these concepts in practice you'll write applications that use the radio functionality of the nRF52840 microcontroller.
You have received two development boards for this workshop. We'll use both in the beginner workshop.
## The nRF52840 Development Kit
This is the larger development board.
The board has two USB ports: J2 and J3 and an on-board J-Link programmer / debugger -- [there are instructions to identify the ports in a previous section][id-ports]. USB port J2 is the J-Link's USB port. USB port J3 is the nRF52840's USB port. Connect the Development Kit to your computer using the **J2** port.
[id-ports]: ./hardware.md#nrf52840-development-kit-dk
## The nRF52840 Dongle
This is the smaller development board.
The board has the form factor of a USB stick and can be directly connected to one of the USB ports of your PC / laptop. Do **not** connect it just yet.
## The nRF52840
Both development boards have an nRF52840 microcontroller. Here are some details about it that are relevant to this workshop.
- single core ARM Cortex-M4 processor clocked at 64 MHz
- 1 MB of Flash (at address `0x0000_0000`)
- 256 KB of RAM (at address `0x2000_0000`)
- IEEE 802.15.4 and BLE (Bluetooth Low Energy) compatible radio
- USB controller (device function)

View file

@ -8,12 +8,6 @@ From this section on, we'll use the nRF52840 Dongle in addition to the nRF52840
Put the Dongle in front of you, so that the side with the parts mounted on faces up. Rotate it, so that the narrower part of the board, the surface USB connector, faces away from you.
The Dongle has two buttons. They are next to each other in the lower left corner of the Dongle. The reset button (RESET) is mounted sideways, it's square shaped button faces you. Further away from you is the round-ish user button (SW1), which faces up.
✅ Install the `dongle-flash` tool by running the following command from the `tools/dongle-flash` directory.
``` console
$ cargo install --path . -f
```
The Dongle does not contain an on-board debugger, like the DK, so we cannot use `probe-rs` tools to write programs into it. Instead, the Dongle's stock firmware comes with a *bootloader*.
When put in bootloader mode the Dongle will run a bootloader program instead of the last application that was flashed into it. This bootloader program will make the Dongle show up as a USB CDC ACM device (AKA Serial over USB device) that accepts new application images over this interface. We'll use the `nrfutil` tool to communicate with the bootloader-mode Dongle and flash new images into it.
@ -22,13 +16,13 @@ When put in bootloader mode the Dongle will run a bootloader program instead of
When the Dongle is in bootloader mode its red LED will oscillate in intensity. The Dongle will also appear as a USB CDC ACM device with vendor ID `0x1915` and product ID `0x521f`.
You can also use the tool `usb-list`, a minimal cross-platform version of the `lsusb` tool, to check out the status of the Dongle.
You can also use our `usb-list` tool, a minimal cross-platform version of the `lsusb` tool, to check out the status of the Dongle.
✅ Run `cargo run` from `tools/usb-list` to list all USB devices; the Dongle will be highlighted in the output, along with a note if in bootloader mode.
✅ Run `usb-list` to list all USB devices; the Dongle will be highlighted in the output, along with a note if in bootloader mode.
Output should look like this:
``` console
$ cargo run
$ usb-list
(..)
Bus 001 Device 016: ID 1915:521f <- nRF52840 Dongle (in bootloader mode)
```
@ -55,20 +49,17 @@ After the device has been programmed it will automatically reset and start runni
The `loopback` application will *blink* the red LED in a heartbeat fashion: two fast blinks (LED on then off) followed by two periods of silence (LED off). The application will also make the Dongle enumerate itself as a CDC ACM device.
✅ Run `usb-list` tool from the `tools/usb-list` directory to see the newly enumerated Dongle in the output:
✅ Run the `usb-list` tool to see the newly enumerated Dongle in the output:
``` console
$ cargo run
$ usb-list
(..)
Bus 001 Device 020: ID 2020:0309 <- nRF52840 Dongle (loopback.hex)
```
The `loopback` app will log messages over the USB interface. To display these messages on the host we have provided a cross-platform tool: `serial-term`.
✅ Install it by running the following command from the `tools/serial-term` directory.
``` console
$ cargo install --path . -f
```
❗ Do not use serial terminal emulators like `minicom` or `screen`. They use the USB TTY ACM interface in a slightly different manner and may result in data loss.
✅ Run the `serial-term` application. You should see the following output:

View file

@ -1,8 +1,6 @@
# Hello, world!
In this section, we'll set up the integration in VS Code and run the first program.
✅ Open the `tools/dk-run` folder and run `cargo install --path . -f` to install the `dk-run` tool.
In this section, we'll set up the integration in VS Code and run the first program.
✅ Open the `advanced/firmware` folder in VS Code and open the `src/bin/hello.rs` file from the `advanced/apps` folder.
@ -21,4 +19,4 @@ The `firmware` workspace has been configured to cross-compile applications to th
The `dk-run` process will terminate when the microcontroller enters the "halted" state. From the embedded application, one can enter the "halted" state using the `asm::bkpt` function. For convenience, an `exit` function is provided in the `dk` Hardware Abstraction Layer (HAL). This function is divergent like `std::process::exit` (`fn() -> !`) and can be used to halt the device and terminate the `dk-run` process.
Note that when the `dk-run` tool sees the device enter the halted state it will proceed to *reset-halt* the device. This is particularly important when writing USB applications because simply leaving the device in a halted state will make it appear as an unresponsive USB device to the host. Some OSes (e.g. Linux) will try to make an unresponsive device respond by power cycling the entire USB bus -- this will cause all other USB devices on the bus to be re-enumerated. Reset-halting the device will cause it to be electrically disconnected from the host USB bus and avoid the "power cycle the whole USB bus" scenario.
Note that when the `dk-run` tool sees the device enter the halted state it will proceed to *reset-halt* the device. This is particularly important when writing USB applications because simply leaving the device in a halted state will make it appear as an unresponsive USB device to the host. Some OSes (e.g. Linux) will try to make an unresponsive device respond by power cycling the entire USB bus -- this will cause all other USB devices on the bus to be re-enumerated. Reset-halting the device will cause it to be electrically disconnected from the host USB bus and avoid the "power cycle the whole USB bus" scenario.

View file

@ -1,26 +1,29 @@
# Listing USB Devices
In the `tools` folder you'll find `usb-list`: a minimal cross-platform version of the `lsusb` tool.
✅ To list all USB devices, run `usb-list`.
✅ To list all USB devices, run the progam using `cargo run` from `tools/usb-list`.
❗️ If you haven't yet installed `usb-list`; [installation instructions can be found in a previous section][install].
[install]: ./tooling-check.md#more-tools
``` console
$ cargo run
$ usb-list
Bus 002 Device 001: ID 1d6b:0003
Bus 001 Device 002: ID 0cf3:e300
Bus 001 Device 003: ID 0c45:6713
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 010: ID 1366:1015 <- J-Link on the nRF52840 Development Kit
```
The goal of this exercise is to get the nRF52840 SoC to show in this list. The embedded application will use the vendor ID (VID) and product ID (PID) defined in `advanced/common/consts`; the `usb-list` tool will highlight the USB device that matches that VID PID pair.
The goal of this workshop is to get the nRF52840 SoC to show in this list. The embedded application will use the vendor ID (VID) and product ID (PID) defined in `advanced/common/consts`; the `usb-list` tool will highlight the USB device that matches that VID PID pair.
``` console
$ # expected output
$ cargo run
$ usb-list
Bus 002 Device 001: ID 1d6b:0003
Bus 001 Device 002: ID 0cf3:e300
Bus 001 Device 003: ID 0c45:6713
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 010: ID 1366:1015 <- J-Link on the nRF52840 Development Kit
Bus 001 Device 059: ID 2020:0717 <- nRF52840 on the nRF52840 Development Kit
```
```

View file

@ -1,9 +1,9 @@
# Preparations
This chapter contains informations about the course material, the required hardware and an installation guide.
This chapter contains informations about the course material, the required hardware and an installation guide.
## Required Hardware
## Required Hardware
- [nRF52840 Development Kit (DK)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
- [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-Dongle)
@ -14,9 +14,14 @@ In this workshop we'll use both the nRF52840 Development Kit (DK) and the nRF528
For the span of this workshop keep the nRF52840 DK connected to your PC using a micro-USB cable. Connect the USB cable to the J2 port on the nRF52840 DK. Instructions to identify the USB ports on the nRF52840 board can be found in the top level README file.
## Starter code
Project templates and starter code for this workshop can be found at [https://github.com/ferrous-systems/embedded-trainings-2020][repo]
[repo]: https://github.com/ferrous-systems/embedded-trainings-2020
## Required Software
Please install the required software before the course starts.
Please install the required software before the course starts.
## Course Material
This book contains the material for the beginner and the advanced workshop in embedded Rust. It aims to be as inclusive as possible. This means, that some information is available in several forms, for example pictures and text description. We also use icons so that different kinds of information are visually distiguishable on the first glance. If you have accessibility needs that are not covered, please let us know.
@ -28,4 +33,4 @@ We use Icons to mark different kinds of information in the book:
* 🔎 Knowledge, that gets you deeper into the subject, but you do not have to understand it completely to proceed.
* 💬 Descriptions for Accessibility
> Note: Notes like this one contain helpful information
> Note: Notes like this one contain helpful information

View file

@ -1,6 +1,6 @@
# RTIC hello
RTIC, Real Time on Integrated Circuits, is a framework for building evented, time sensitive applications.
RTIC, Real-Time Interrupt-driven Concurrency, is a framework for building evented, time sensitive applications.
✅ Open the `src/bin/rtic-hello.rs` file.
@ -10,7 +10,7 @@ RTIC makes a clearer distinction between the application's initialization phase,
`rtic::app` is a procedural macro that generates extra Rust code, in addition to the user's functions. The fully expanded version of the macro can be found in the file `target/rtic-expansion.rs`. This file will contain the expansion of the procedural macro for the last compiled RTIC application.
✅ Build the `rtic-hello` example and look at the generated `rtic-expansion.rs` file.
✅ Build the `rtic-hello` example and look at the generated `rtic-expansion.rs` file.
The generated code should look like this. Note that interrupts are disabled during the execution of the `init` function:
@ -21,4 +21,4 @@ fn main() -> ! {
rtic::export::interrupt::enable();
idle(idle::Context::new(/* .. */))
}
```
```

View file

@ -2,22 +2,13 @@
Both `cargo-embed` and `cargo-flash` are tools based on the `probe-rs` library. This library exposes an API to communicate with the J-Link and perform all the operations exposed by the JTAG protocol. For this workshop we have developed a small Cargo runner that uses the `probe-rs` library to streamline the process of running a program and printing logs, like `cargo-embed`, while also having better integration into VS code.
✅ Install the Cargo runner.
1. Run the following command from the `tools/dk-run` folder:
``` console
$ cargo install --path . -f
```
2. Open the `src/bin/hello.rs` file in VS Code and click the "Run" button that's hovering over the `main` function.
✅ Open the `src/bin/hello.rs` file and click the "Run" button that's hovering over the `main` function.
> Note: you will get the "Run" button if the Rust analyzer's workspace is set to the `beginner/apps` folder. This will be the case if the current folder in VS code (left side panel) is set to `beginner/apps`.
If you are not using VS code, you can run the program out of your console.
If you are not using VS code, you can run the program out of your console.
Enter the command `cargo run --bin hello` from within the `beginer/apps` folder. Rust Analyzer's "Run" button is a short-cut for that command.
Expected output:
``` console

View file

@ -10,4 +10,4 @@ This program will blink (turn on and off) one of the LEDs on the board. The time
The other time related API exposed by the `dk` HAL is the `dk::uptime` function. This function returns the time that has elapsed since the call to the `dk::init` function. This function is used in the program to log the time of each LED toggle operation.
[❗assignment to chnge something]
✅ Try changing the `Duration` value passed to `Timer.wait`. Try values larger than one second and smaller than one second. What values of `Duration` make the blinking imperceptible?

View file

@ -0,0 +1,46 @@
# Tooling check
## Setup check
✅ First, let's check that you have installed all the tools listed in the previous section.
❗ The first two commands *must* return version `0.8.x`
``` console
$ cargo flash --version
0.8.0
$ cargo embed --version
0.8.0
$ cargo size --version
cargo-size 0.3.0
$ nrfutil version
nrfutil version 6.1.0
```
## More tools
✅ Now let's install some tools shipped with the workshop material.
### Beginner workshop
From the `tools` folder run these commands *from different terminals so they'll run in parallel*:
- `cargo install --path dk-run`
- `cargo install --path usb-list`
- `cargo install --path dongle-flash`
- `cargo install --path serial-term`
- `cargo install --path change-channel`
Leave the processes running in the background.
### Advanced workshop
From the `tools` folder run these commands *from different terminals so they'll run in parallel*:
- `cargo install --path dk-run`
- `cargo install --path usb-list`
Leave the processes running in the background.

View file

@ -99,7 +99,8 @@ if the red LED was blinking and you got this message then the device wasn't corr
ihex
};
let dfu = ihex.with_extension("zip");
// create in temp folder for automatic cleanup
let dfu = dir.path().join(filename).with_extension("zip");
println!("packaging iHex using nrfutil ...");