Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • d7018e-special-studies-embedded-systems/are_we_embedded_yet
  • tmplt/are_we_embedded_yet
  • shawnshank/are_we_embedded_yet
  • CuriouslyCurious/are_we_embedded_yet
  • nevvi/are_we_embedded_yet
  • williameriksson/are_we_embedded_yet
  • nannap/are_we_embedded_yet
  • ironedde/are_we_embedded_yet
8 results
Select Git revision
Loading items
Show changes
Commits on Source (75)
Are We Embedded Yet
=====================
## D7018E - Special Studies in Embedded Systems
Disclaimer: This document is in beta state!!!!! Just to give a hint how the course will look like.
The course will be given as a self study course with a set of introductional seminars and accompanying mandatory assignments, followed by a larger assignment (project). The project can be carried out individually or in groups dependent on size. Grading will be individual, based on agreed requirements between the student and the teacher, showing understanding and abilities regarding:
The course will be given as a self study course with a set of introduction seminars and accompanying mandatory assignments, followed by a larger assignment (project). The project can be carried out individually or in groups depending on size. Grading will be individual, based on agreed requirements between the student and the teacher, showing understanding and abilities regarding:
1. The Rust ecosystem.
1. The Rust ecosystem. [ecosystem](doc/Ecosystem.md)
Rustup (stable vs nightly), crates and toml files, cargo, rustc, llvm, gdb/lldb (and additional tooling rls, rustfmt, racer, xargo etc.) The Rust core and standard library. Building, bebugging/testing, documenting and publishing Rust applications and libraries.
Rustup (stable vs nightly), crates and toml files, cargo, rustc, llvm, gdb/lldb (and additional tooling rls, rustfmt, racer, xargo etc.) The Rust core and standard library. Building, debugging/testing, documenting and publishing Rust applications and libraries.
2. Simple applications in Rust
......@@ -21,7 +20,7 @@ The course will be given as a self study course with a set of introductional sem
4. The Rust Memory Model
Theoretical underpinning, as well as impact to both memory safatey and code generation. Exterior (inherited) and interior mutability (Cell). Move vs. copy semantics, relation to Clone and Copy traits. Lifetimes and scoping. Static lifetimes, and the relation to the Sync trait.
Theoretical underpinning, as well as an impact on both memory safety and code generation. Exterior (inherited) and interior mutability (Cell). Move vs. copy semantics, relation to Clone and Copy traits. Lifetimes and scoping. Static lifetimes, and the relation to the Sync trait.
6. Memory Safe Concurrency
......@@ -33,7 +32,7 @@ The course will be given as a self study course with a set of introductional sem
8. Building and debugging embedded code in Rust
Hardware abstractions using svd2rust (autogenerated from vendor provided SVD specifications). Compiling using xargo. Setting up openocd and gdb.
Hardware abstractions using svd2rust (auto-generated from vendor-provided SVD specifications). Compiling using xargo. Setting up openocd and gdb.
9. Pre-processing
Custom build.rs build scripts, and the RTFM Concurrent Reactive Component model.
......@@ -41,7 +40,7 @@ The course will be given as a self study course with a set of introductional sem
## Course Format
Please fill out the [doodle](http://doodle.com) so we can arrange for a first scheduled seminar. We will use telegram [telegram](http://telegram.com) in order to confirm the preferred date. On the first seminar we will schedule 10 sessions for covering the above topics.
Please fill out the [doodle](http://doodle.com) so we can arrange for a first scheduled seminar. We will use telegram [telegram](http://telegram.com) in order to confirm the preferred date. On the first seminar, we will schedule 10 sessions for covering the above topics.
Each topic will be accompanied by a set of small illustrative examples and assignments that each student should master (learning goals). On the following session, each student should prepare to discuss and demonstrate their solutions.
......@@ -51,17 +50,17 @@ Each project should be reported in terms of a git Rust crate, with sufficient do
There will be two presentation rounds (at end of LP2 and LP3). Students taking (too many other) courses during LP2 may choose to present their project at end of LP3 (instead of LP2). Presentations will be oral, where the student(s), will present and demonstrate their work.
Projects should be related to embedded programming, either on the target side (some application using the RTFM-core or CRC model), or on the host side, communicating with an embedded target running Rust RTFM. E.g., two groups can work together with building a system, e.g., with back-end processing of data collected by the embedded system, or proividing a front-end to the embedded system. Alternatively, host side project could relate the development of the RTFM-core/ RTFM-CRC frameworks or related tools (e.g. LLWM-KLEE as a backend for analysis of Rust code).
Projects should be related to embedded programming, either on the target side (some application using the RTFM-core or CRC model), or on the host side, communicating with an embedded target running Rust RTFM. E.g., two groups can work together with building a system, e.g., with back-end processing of data collected by the embedded system, or by providing a front-end to the embedded system. Alternatively, host side project could relate the development of the RTFM-core/ RTFM-CRC frameworks or related tools (e.g. LLVM-KLEE as a back-end for analysis of Rust code).
## Resources
Students will carry out the assignments on their personal laptops (in case you don't have a working laptop we will try to lend you one). Tools used are available for linux and osx, but with a bit of trickery windows based installations should be possible (but you are on your own here). In case you don't run osx/linux native, virtual box or wmware is possible, though debugging of target MCUs are feasible it is a bit more tricky.
Students will carry out the assignments on their personal laptops (in case you don't have a working laptop we will try to lend you one). Tools used are available for Linux and OSX, but with a bit of trickery windows based installations should be possible (but you are on your own here). In case you don't run OSX/Linux native, virtual box or VMware is possible, though debugging of target MCUs are feasible it is a bit more tricky.
Embedded targets STM32F401RE/411RE (Nucleo-64) will be made available to all students. You will need to get an mini-usb cable yourselves. If you prefer to work with some other ARM Cortex M processor, let us know and we will have a look at available support.
Embedded targets STM32F401RE/411RE (Nucleo-64) will be made available to all students. You will need to get a mini-USB cable yourselves. If you prefer to work with some other ARM Cortex M processor, let us know and we will have a look at available support.
Teaching material will be made available through git (this project), build and refined throughout the course.
We encourage all sorts of collaborations in between the students. Rust is not the easiest language to learn, and we will cover a lot of ground. Use the seminars to try to get as much as possible by being well prepared in order to succeed. We will use telegram as the main means of communictation and support from teachers as well as other fellow students, (this way information will reach everyone, keeping support as efficient as possible).
We encourage all sorts of collaborations in between the students. Rust is not the easiest language to learn, and we will cover a lot of ground. Use the seminars to try to get as much as possible by being well prepared in order to succeed. We will use telegram as the main means of communication and support from teachers as well as other fellow students, (this way information will reach everyone, keeping support as efficient as possible).
# Course in detail
......@@ -75,27 +74,26 @@ Seminars
About the course. Scheduling further seminars. Introduction to the Rust [ecosystem](doc/Ecosystem.md), and basics of Rust programming.
We will cover the Rust book [Rustbook Second Edition](https://doc.rust-lang.org/book/second-edition.html) sections
We will cover the Rust book [Rustbook Second Edition](https://doc.rust-lang.org/book/second-edition/) sections
* [1 - Introduction](https://doc.rust-lang.org/book/second-edition/ch01-00-introduction.html),
* [2 - Guessing Game Tutorial](https://doc.rust-lang.org/book/second-edition/ch02-00-guessing-game-tutorial.html), and
* [3 - Common Programming Concepts](https://doc.rust-lang.org/book/second-edition/ch03-00-common-programming-concepts.html).
* Assignment 1
Extend the guessing game application such to give an error message on ill formated input, (use the Restult::Err type). Add a counter to the number of tries and write the number of tries for each iteration and on "winning".
Extend the guessing game application such to give an error message on ill-formatted input, (use the Result::Err type). Add a counter to the number of tries and write the number of tries for each iteration and on "winning".
Make a github account (if you don't have it). Make a github project whith your code, along with a README.md for usage instructions.
Make a GitHub account (if you don't have it). Make a GitHub project with your code, along with a README.md for usage instructions.
Prepare to present your development for the next seminar.
2. Basic Programming
* Preparation
Solve and be prepared to present Assignment 1.
* Assessment
We will in class install, test and comment on one of Your solutions. That is, make sure your `crate` on git actually works, and that the accompanying `readme.md` is sufficient for your follow students in order to recreate the result.
We will in the class install, test and comment on one of Your solutions. That is, make sure your `crate` on git actually works, and that the accompanying `readme.md` is sufficient for your fellow students in order to recreate the result.
Later in the course, you will assess each others assignments by creating an `issue` to their development. More on that later.
* Topic
......@@ -103,7 +101,7 @@ Seminars
Using the Rust ownership model.
Data structures, structs, enums, String (relation to slices) etc. Containers, Vec, and HashSets/Maps. Iterators. Using the Rust module system. Handling errors.
We will cover the Rust book [Rustbook Second Edition](https://doc.rust-lang.org/book/second-edition.html) sections
We will cover the Rust book [Rustbook Second Edition](https://doc.rust-lang.org/book/second-edition/) sections
* [4 - Understanding Ownership](https://doc.rust-lang.org/book/second-edition/ch04-00-understanding-ownership.html),
* [5 - Using Structs to Structure Related Data](https://doc.rust-lang.org/book/second-edition/ch05-00-structs.html),
......@@ -115,16 +113,19 @@ Seminars
* [9 - Error Handling](https://doc.rust-lang.org/book/second-edition/ch09-00-error-handling.html).
* Assignment 2
a. Break out the line input into a function returning a `Result<Ok<u32>>, Err<String>>`. In case of a parsing error prepend the `Err<String>` with the text `"in parsing u32, "`.
a. Extend the guessing game with a tuple holding `(u32, String)`, store each input `(counter, guess)` in a vector. Iterate (`for`) to print the history at exiting.
b. Extend the guessing game with a tuple holding `(u32, String)`, store each input `(counter, guess)` in a vector. Iterate (`for`) to print the history at exiting. You may solve this in many ways (perhaps your first attempt would be a C like approach), however make use of `Iterator`s in Rust (they will do the indexing for you).
b. Instead of vector use a 'HashMap', with a key `u32` and a value `String`. Again iterate (`for`) to print the history at exiting. (Explain the result.)
c. Change the program so that it prints the history twice.
c. Break out the line input into a function returning a `Result<Ok<u32>>, Err<String>>`. In case of a parsing error prepend the `Err<String>` with the text `"in parsing u32, "`.
d. Change the program so that it prints only the last 3 entries in backwards order (the last entry first). If winning with less than 3 entries, print all (still in backwards order). Use iterators (not C-like indexing).
d. Optional, find a way to print the `HashMap` in a sorted way.
e. Instead of vector use a 'HashMap', with a key `u32` and a value `String`. Again iterate (`for`) to print all entries at exiting. (Explain the result.)
Make three new branches (`2a, 2b, 2c`) whith your code, along with a README.md for usage instructions, and expected behavior.
f. Optional, find a way to print the last 3 entries of the `HashMap` (output similar to d).
Make new branches (`2a, 2b, ..., 2f`) with your solutions, along with a README.md for usage instructions, and expected behavior.
*During development you may want to limit the number of tries so you can test without having to bother with answering correctly (the game gets boring after a while.)*
......@@ -134,12 +135,12 @@ Seminars
* Preparation
Finish Assignment 2.
* Topic
* Topic [Memory](doc/Memory.md)
In deapth discussion of underlying theory, linear types (relation to functional programming). The *Affine* type system of Rust, requirements on the programmer, and guarantees offered by the compiler. Lifetimes, of stack allocated and global variables. Relation to C++ `unique pointers`.
* Assignment
In-depth discussion of underlying theory, linear types (relation to functional programming). The *Affine* type system of Rust, requirements on the programmer, and guarantees offered by the compiler. Lifetimes, of stack allocated and global variables. Relation to C++ `unique pointers`.
* Assignment 3
a. Recall the D0013E course lab2/4, where you decrypted an message in assembler (lab2) and C (lab 4). Now, let's re-implement the lab in Rust (base your development on group number [1's](http://www.sm.luth.se/csee/courses/smd/D0013E/labs/lab1underlag/grupp_01.lab1_underlag.s ) lab assignment).
a. Recall the D0013E course lab2/4, where you decrypted a message in assembler (lab2) and C (lab 4). Now, let's re-implement the lab in Rust (base your development on group number [1's](http://www.sm.luth.se/csee/courses/smd/D0013E/labs/lab1underlag/grupp_01.lab1_underlag.s ) lab assignment).
You have to be careful about the signed/unsigned operations and use `wrapping` arithmetics to avoid panics due to unsigned *carry* and signed *overflow*.
......@@ -147,41 +148,42 @@ Seminars
The `seed`, `abc`,`coded` and `plain` should be stack allocated. The decoded string should be printed when decryption is finished.
b. Make the `seed`, `abc`,`coded` and `plain` heap allocated. Accessing those will require some `unsafe` code. (Keep the unsafe blocks as local as possible.)
b. Make the `seed`, `abc`,`coded` and `plain` static (heap) allocated (i.e., as global variables). Accessing those will require some `unsafe` code. (Keep the unsafe blocks as local as possible.)
c. Safety analysis. Provoke the implementation, by omitting the `'\0'` (null termintation). Observe the result and motivate the behavior in terms of your understanding of the Rust memory model. Under which circumpstances do you consider 3a and 3b to have same/different memory safety.
c. Safety analysis. Provoke the implementation, by omitting the `'\0'` (null termination). Observe the result and motivate the behavior in terms of your understanding of the Rust memory model. Under which circumstances do you consider 3a and 3b to have same/different memory safety.
Update your git with two new branches (`3a, 3b`), and update docmentation to cover usage and analysis (`3c`).
Update your git with two new branches (`3a, 3b`), and update the documentation to cover usage and analysis (`3c`).
4. Cortex-M, are we embedded yet
* Preparation
Finish assignment 3. Bring a USB mini cable, and/or your Cortex M dev board of choice.
Finish assignment 3. Bring a USB mini cable, and/or your Cortex M dev board of choice. We will provide Nucleo 64s (STM32f401re/STM32f411re if you do not have a board.)
* Topic
Embedded programming in Rust.
Embedded programming in Rust. Check this [document](doc/Quickstart.md)
* xargo for building non-`std` (bare metal) systems
* [cortex-m-quickstart]
* [cortex-m]
* ([bluepill/nucleo] crates)
* `cortex-m-quickstart`, project template
* `cortex-m`, crate common to all Cortex-M devices
* `stm32f103xx` and `stm32f40x`, device crates
* `blue-pill` and `nucleo` board support crates
* Building and debugging your first application.
* Assignment
* Assignment 4
a. Backport assignment `3b` to your choosen target. Use semihosting in order to `write` the resulting string to the host. You may need to use `--release` for decoding the long (`coded`) message, as being deeply recursive unoptimized code may run out of stack memory.
a. Backport assignment `3b` to your chosen target. Use semi-hosting in order to `write` the resulting string to the host. You may need to use `--release` for decoding the long (`coded`) message, as being deeply recursive unoptimized code may run out of stack memory.
b. Discuss from a memory safety perspective the outcome.
c. Compare for the short message (`abc`), the number of cycles required for `decode` in `--dev` vs. `--release`. As a comparison my straightforword C implementation took 2200 cycles in best optimized mode using `gcc` (-o3), while my (transation) to Rust code took 1780 cycles. (Both executed on a bluepill board at 8MHz with flash memory wait states).
c. Compare for the short message (`abc`), the number of cycles required for `decode` in debug (standard) vs. `--release`. As a comparison my straightforward C implementation took 2200 cycles in best optimized mode using `gcc` (-o3), while my (translation) to Rust code took 1780 cycles (--release). (Both executed on a bluepill board at 8MHz without (flash) memory wait states).
Make a new git for your embedded development. Make three branches (`3a, 3b, 3c`) with updated documentation according to the above.
Make a new git for your embedded development. Make three branches (`4a, 4b, 4c`) with updated documentation according to the above.
5. Advanced Rust Concepts
* Preparation
Be prepared to present the progress on assignment 3.
Be prepared to present the progress on assignment 4.
* Topic
Advanced Rust features, trait system and closures.
......@@ -190,12 +192,12 @@ Seminars
* [13 - Functional Language Features in Rust](https://doc.rust-lang.org/book/second-edition/ch13-00-functional-features.html).
* Assignment
Continue working on assignment 3.
Continue working on assignment 4.
6. Memory Safe Concurrency
* Preparation
* Finish lab 3 and be prepared to show your solution.
* Finish assignment 4 and be prepared to show your solution.
* Topic
* UnsafeCell, and synchronization in the RTFM model.
......@@ -205,55 +207,54 @@ Seminars
* [cortex-m-rtfm](https://github.com/japaric/cortex-m-rtfm) The RTFM-core (task and resource model) in Rust for the Cortex-M family
* [svd2rust](https://github.com/japaric/svd2rust) Generating
* Assignment 4
* Assignment 5
Implement a simple system with 3 tasks
Implement a simple system with two tasks
* A periodic task executing each Xms (free of accumulated drift, and with minimal jitter), that blinks the on-board LED, and
* A USART task receiving commands (pause, start, period 1-1000ms), received commands should be parsed and corresponding responses generated and sent over the USART. (Come up with a nice and simple user interface.)
* A a logging task, run each second (period 1s), that prints statistics of CPU usage over the ITM port
* Idle should gather statics on sleep/up time, (there is a sleep counter in the cortex core)
* Use shared resources (data structures) to ensure race free execution
* a perodic task executing each 10ms, that blinks the onboard LED, and
* usart task receiving commands (pause, start, period)
* a shared resource (data structure) protecting the command and period
You may use the core systic timer (relative) and the dwt cycle counter (absolute) in combination to achieve drift free timing. Alternative you look into the stm32f4xx timer peripheral. There is a support crate for the [STM32F3DISCOVERY](https://github.com/japaric/f3) board. Peripherals are similar so you may "borrow" code from there.
Make a new git with the development and documentation.
7. Macros
* Preparation
Optional:
Find a way to measure the power consumption. A possible solution is to power the board externally and use a power cube with current measuring capability. Alternative use an external power source with known charge (e.g., a "capacitor"), and measure the discharge time (start and residue charge at brown-out voltage), at least a precise relative measure is possible to obtain.
Be prepared to present the progress on assignment 4.
* Topic
Operation without being connected to the USB port: in this case the serial IO and ITM needs to be connected externally (e.g., using some ftdi serial-USB).
We will cover implementation of the RTFM-core crate.
Super optional:
Try to minimize power consumption while maintaining desired operation. Lowering supply voltage and using aggressive power modes of the processor might be applied. (Not sure how USART/ITM communication can be made possible at sub 3.3v voltages. Also you have to make sure not to source the board over the communication interfaces.)
Special focus to `macro_rules` and `procedural macros`.
8. Concurrent Reactive Objects
7. Macros and Projects (Monday Nov. 20th)
* Preparation
Be prepared to present assignment 4.
Be prepared to present the progress on assignment 5.
* Topic
A component model for reactive real-time programming.
We will cover the programming model and the implementation, including the `build.rs`, parsing of model files and generation of Rust code.
* Assignment 5
* port the assignment 4 to the RTFM-CRC model.
- We will cover the implementation of the rtfm-core and the cortex-m-rtfm crates. For details see [RTFM](doc/RTFM.md).
Make a new git for the development and documentation.
Special focus to `macro_rules` and `procedural macros`.
- RTFM-CRC A component model for reactive real-time programming.
9. Presentation of project ideas
* Preparation
We will cover the programming model and the implementation, including the `build.rs`, parsing of model files and generation of Rust code.
Be prepared to present progress of assignmont 5.
* Topic
Discussion of projects
- Discussion of project ideas
* Assignment
Write a project specification including individual grading assessment criteria.
Write a project specicification including individual grading assessment critera.
10. Wrap-up
8. Wrap-up (Monday Dec. 4th)
* Preparation
* Be prepared to present assignment 5.
* Be prepared to present your project.
* Be prepared to present your project, 10 minutes per project.
* A good idea is to prepare a git for the project with a `README.md` and use that as supporting material for your presentation. Its advicable to have a section (or in a doc sub folder) where you collect references to the material you will use, i.e., links to data sheets, links to other related crates and projects of importance to your project.
This type of reference section will be largely helpful to both you (during the project and afterwards maintaining it, but also to other users and people interested in your work). Moreover, from a "course" perspective it shows that you have done the necessary background studies BEFORE you "hack away". Of corse this will be a living document, updated throughout the project, but its a very good thing to start out NOW, then it can be used for your 10 minutes of fame!
assets/cortex-m-layers.png

23.6 KiB

assets/vscode-build.png

118 KiB

assets/vscode-debug.png

161 KiB

......@@ -7,31 +7,84 @@ The `rustc` compiler is at heart of the Rust Ecosystem. Other tools of great hel
* [cargo-update](https://crates.io/crates/cargo-update), cargo sub-command to manage crate updates
* [xargo](https://crates.io/crates/xargo) Systoot manager to build for non-`std` targets
Various other Rust tools you might find useful
* [rls](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust), Rust support for Visual Studio Code
The Rust ecosystem also provides support to program development, in terms of external `crates` for code completion formatting and formatting
* [racer](https://crates.io/crates/racer/), Code completion for Rustbuild system and package/crate manager
* [rustfmt](https://crates.io/crates/rustfmt), Tool to find and fix Rust formatting issues
* [itm](https://crates.io/crates/itm) Tool to parse and dump ITM packets
* add here your favorite crates
* [rls-preview](https://github.com/rust-lang-nursery/rls), Rust Language Server (RLS). RLS is a server that runs in the background, providing IDEs, editors, and other tools with information about Rust programs. The `rls-preview` is in alpha state, meaning that it's not guaranteed to compile/work. (You may check under build/passing, the latest changes that passed compilation.)
Rust support for various IDEs and editors
* [rls](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust), Rust support for Visual Studio Code, based on the `rls-preview`. This is the reference implementation for `rls` support (currently in alpha/preview state).
* [rustdt](http://rustdt.github.io/), Rust support for the Eclipse platform (currently not further maintained)
* Atom, Sublime, Code::Blocks support is also available
Other tools and packages
* [rls](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust), Rust support for Visual Studio Code
* [rustdt](http://rustdt.github.io/), Rust support for the Eclipse platform
* add here your favorite tools supproting Rust development
Other tools that come in handy for embedded development
* [itm](https://crates.io/crates/itm) Tool to parse and dump ITM packets
* add here your favorite tools supporting Rust development
# Installation
We suggest a linux or OSX development environment, though Rust related tools are also available under Windows. Install [rustup](https://www.rustup.rs/), Rust tool-chain manager using the link, and go from there.
We suggest a Linux or OSX development environment, though Rust related tools are also available on Windows. Install [rustup](https://www.rustup.rs/), Rust tool-chain manager using the link, and go from there.
# Rustup
The [rustup](https://www.rustup.rs/), tool manager allows you to manage multiple tool chain installations. Nightly tool chains allow for the development of libraries and applations including `unsafe` code (which will be necessary for the later excercises). For some tools to work (rls/rustfmt) you need to install the Rust sources. By default your Rust related tools will be stored in `~/.rustup`.
The [rustup](https://www.rustup.rs/), tool manager allows you to manage multiple tool chain installations. Rust is distributed in three channels (`stable`, `beta` and `nightly`). You may set the default toolchain:
```
rustup default nightly-2018-01-10-x86_64-unknown-linux-gnu
```
and get information on the status of `rustup`
```
rustup show
```
Nightly tool chains allow for the development of libraries and applications including `unsafe` code using features not available on the `stable channel` (which will be necessary for the later exercises). For some tools to work (`rls/rustfmt`), you need to install additional components. For this to work, you should use a nightly toolchain for which all tools and components work (currently `nightly-2018-01-10` is the latest). Here is an example:
```
rustup default nightly-2018-01-10
rustup component add rls-preview
rustup component add rust-analysis
rustup component add rust-src
```
`rls-preview`, `rust-analysis` and `rust-src` are required for RLS support (including cross-referencing to the standard library, code completion and formatting).
# Cargo
Cargo is the go-to tool for managing Rust application and your own Rust developments (see [cargo](https://crates.io/) for detailed documentation).
By default your Rust related tools will be stored in `~/.cargo`, this directory should be added to your `$PATH` environment. `cargo` and `rustup` works closely together, e.g., you may tell `cargo` to use a specific toolchain for the build.
In order to get formatting to work you need to install `rustfmt-nightly`.
```
cargo install rustfmt-nightly
```
There is also another (old) crate named `rustfmt`, that can be compiled with the `stable` Rust compiler. The `rustfmt-nightly` is the *new* and improved formatter, that will eventually replace the old stable `rustfmt` (the generated binaries have the same name so do *not* install the stable version).
# Rust Crates
A crate is a unit of compilation, being either a library or an application. Crates are managed (compiled, installed, removed, updated, etc.) by the [cargo](https://crates.io/) tool.
A *crate* is a unit of compilation, being either a *library* or an executable *application* (binary). Crates are managed (compiled, installed, removed, updated, etc.) by the [cargo](https://crates.io/) tool.
`*.toml` files are used throughout Rust developments for giving configuration (meta) information (essentially replacing the need of Makefiles). The `Cargo.lock` file shows the cashed dependencies (you may delete the `Cargo.lock` file to force updating dependencies, `cargo clean` may not be enough).
Dependencies (may) include a minimal version, following the [semver](http://semver.org/) versioning standard.
# VSCODE support
## RLS
[vscode](https://wiki.archlinux.org/index.php/Visual_Studio_Code) is the official integration test platform for the RLS development, and hence likely also to provide the best user experience.
See [rls](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust) for installing the RLS extension.
You will need to pin the specific toolchain version used, by setting the `"rust-client.channel": "nightly-2018-01-10"` in your `vscode` *user* settings (this will be stored in a file `~/.config/Code/User/settings.json` and used for all your `vscode` projects. Settings may be set individually for each *workspace*, overriding the defaults. Regarding the `"rust-client.channel"` setting, a *workspace* setting would force the specific version (overriding the default), and may not work when the code is distributed (as other developers may be on other toolchains).
For RLS to work, `vscode` need a path to the `rls-preview` library (using the environment variable `LD_LIBRARY_PATH` (Linux), `DYLD_LIBRARY_PATH` (OSX ?)).
```
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
```
You may add this to your `~/.bash_profile`, and start vscode (`code` is the name of the executable) in a new terminal (to ensure that the `LD_LIBRARY_PATH` (Linux) `DYLD_LIBRARY_PATH` (OSX?) is correctly set). If `code` is run from your window manager (e.g., `plasma`), make sure that the environment is set correctly.
Under the hood: `rustc --print sysroot` gives you the path to the root of the current toolchain. So its important that the toolchain is set correctly by `rustup` for this to work.
`*.toml` files are used throughtout Rust developments for giving configuration (meta) information. The `Cargo.lock` file shows the cashed dependencies (you may delete the `Cargo.lock` file to force updating dependencies, `cargo clean may not be enough).
## GIT
You may choose to use the [gitlens](https://github.com/eamodio/vscode-gitlens) extension, to get integrated git support.
Dependencies (may) include a minimal version, eg `itm = "0.1.1"` indicates that at least version `0.1.1` in required (so `0.1.1`, `0.1.2`, `0.2.3` is Ok, while `0.1.0` will not suffice, and a version `1.0.0` would be considered a breaking change (major number changed) and not considered. Rust follows the [semver](http://semver.org/) versioning standard.
\ No newline at end of file
## Native Debug
The [Native Debug](https://github.com/WebFreak001/code-debug) extension allows for debugging Rust application from within `vscode`. Native Debug supports both `lldb` (LLVM) and `gdb` (GNU)
debuggers. For embedded development, you will use the latter. See Embedded.md (TODO) for further details.
# Embedded Programming in Rust
# ARM Toolchain
Rust relying on LLVM is already a cross compiler, however currently linking to embedded targets are done using `binutils`. Under arch you can install the complete GNU toolchaion for ARM using the package `arm-none-eabi-gcc`, which also installs `arm-none-eabi-binutils`. (The package also installs `arm-none-eabi-gdb`, which you will use later for debugging.)
Rust relying on LLVM is already a cross-compiler, however currently linking to embedded targets are done using `binutils`. Under arch you can install the complete GNU toolchain for ARM using the package `arm-none-eabi-gcc`, which also installs `arm-none-eabi-binutils`. (The package also installs `arm-none-eabi-gdb`, which you will use later for debugging.)
# Openocd
In order to debug code on the ARM target you need to establish a connection, e.g., using [openocd](http://openocd.org/), available under arch as `openocd`. Later you will start `openocd` in the background using e.g.:
......@@ -17,7 +17,7 @@ In order to debug code on the ARM target you need to establish a connection, e.g
(Assuming that this is a `nucleo stm32f401re` target, programmed using the onboard `stlink-v2-1` interface.)
## port configuration
By default `openocd` listens at port `3333` for incoming gdb connections. If you want to program/dubug multiple targets using SWD (Serial Wire Debug) like offered by the `stlink` based interfaces you need one interface per target. In that case you may run several instances of `openocd` listening in on different ports. To that end the target configuration is defined in the `target/*.cfg`
By default `openocd` listens at port `3333` for incoming gdb connections. If you want to program/debug multiple targets using SWD (Serial Wire Debug) like offered by the `stlink` based interfaces you need one interface per target. In that case you may run several instances of `openocd` listening in on different ports. To that end the target configuration is defined in the `target/*.cfg`
```
......@@ -51,7 +51,7 @@ For compiling embedded targets install the `xargo` crate.
```> cargo install xargo```
(Your top level module should give the crate-wide attribute `#![no_std]` in order to use `core` instead of `std` as the default library.)
(Your top-level module should give the crate-wide attribute `#![no_std]` in order to use `core` instead of `std` as the default library.)
# Using VS Code
......@@ -61,7 +61,7 @@ Install the latest version of Visual Studio Code using your packet manager, unde
## Rust support
Install the `Rust(rls)` plugin (just search for `Rust` in the extensions, chose the plugin and install). Assuming you already have `rustup` and the Rust tools installed the required crates will be installed autematically. The RLS plugin is experimental but already quite useuful. If it fails installing you may check the [RLS git](https://github.com/rust-lang-nursery/rls), for further instructions (actually you can run the plugin from `java script` source.)
Install the `Rust(rls)` plugin (just search for `Rust` in the extensions, chose the plugin and install). Assuming you already have `rustup` and the Rust tools installed the required crates will be installed automatically. The RLS plugin is experimental but already quite useful. If it fails to install you may check the [RLS git](https://github.com/rust-lang-nursery/rls), for further instructions (actually you can run the plugin from `javascript` source.)
## Debugging
......@@ -97,7 +97,7 @@ Install the latest version of Visual Studio Code using your packet manager, unde
It launches `/usr/bin/arm-none-eabi-gdb` and attach the target on port `:3333`, the `:` indicates that the connection to be on the local host). It assumes `openocd` is running and has established a connection to the target.
Similarly a launch confirguration for release (optimised) builds:
Similarly a launch configuration for release (optimised) builds:
```javascript
{
"type": "gdb",
......@@ -127,7 +127,7 @@ An optimized build is generated by
You may set specific settings in the `Cargo.toml` for each build type (`dev` for debug, `release` for release). Notice debugging of optimized code may be difficult as many symbols are *optimised out* and setting breakpoints may not give the desired results. To that end you may choose to use `asm::bkpt()` (defined in the [contex-m](https://github.com/japaric/cortex-m) crate) in the code instead of breakpoints in the debugger.
## Compilation and Linking
The `xargo/cargo` build system will look into your `.cargo/config` for flags. The first example builds for the `m3` architecture while the second for the `m4` with *hard float* code. Notice, to use the *hard floats*, they need to be enabled in the ARM-core (not enabled at reset by default to save power...). You may have several configurations in the `.cargo/config`, and the `[build] = "..."` determintes the default configuration, it may be overridden e.g, by
The `xargo/cargo` build system will look into your `.cargo/config` for flags. The first example builds for the `m3` architecture while the second for the `m4` with *hard float* code. Notice, to use the *hard floats*, they need to be enabled in the ARM-core (not enabled at reset by default to save power...). You may have several configurations in the `.cargo/config`, and the `[build] = "..."` determinates the default configuration, it may be overridden e.g, by
```
> xargo build ... --target thumbv7m-none-eabi
......@@ -163,9 +163,6 @@ target = "thumbv7em-none-eabihf"
## A note on WFI
If your code hits a `WFI` (Wait For Interrupt), the MCU is put into a low power mode, and by default not accepting new debug request. Thus if trying to connect a new `gdb` session, it will fail (or even worse partially work, while not behaving correctly). To remedy this you may try:
* close `openocd` and restart it
* unplug the the debugger (`stlink` probe), and re-plug it, you may need to hold the `reset` at startup to force the debugger and MCU into a correct state
If we want to overcome this problem alltogether, there is a setting in the ARM-core debug unit that allows incoming connections on `WFI` (this feature is disabled by defauld to save power).
* unplug the debugger (`stlink` probe), and re-plug it, you may need to hold the `reset` at startup to force the debugger and MCU into a correct state
If we want to overcome this problem altogether, there is a setting in the ARM-core debug unit that allows incoming connections on `WFI` (this feature is disabled by default to save power).
\ No newline at end of file
# Rust Memory Model
The memory model is one unique feature that makes Rust stand out from other similar languages.
At heart, is uniqueness of references to mutable resources (memory locations). I.e., in *safe* Rust, one can either have a single mutable reference, or (one or) many immutable references to a resource, but never both (mutable and immutable references at the same time).
This property is enforced by the *borrow checker* in the `rustc` compiler, i.e., code which breaks these properties will be rejected with a compilation error.
There are several advantages with the Rust memory model. To name a few:
* Foremost the Rust memory model is safe, i.e., for programs (written in *safe Rust*) that passes compilation the generated code will be free of unsafe memory accesses (and thus *memory safe*);
* The Rust memory model allows for "fearless programming", i.e., as a programmer you don't have to focus efforts on memory safety, the compiler will stop you if you do something potentially dangerous;
* Programming errors that indirectly lead to memory errors can be spoted at compile time. (E.g, attempting to change the lenght of an array `a` inside an iterator over `a` will be spotted by the compiler and yielt an error.);
* The Rust memory model allows for aggressive optimization, i.e., the compiler will host detailed information regarding the mutability of references and make *safe* assumpitions leading to efficient implementations.
## A bit of history
### Linear Types
Linear types has been studied in works of e.g., Wadler. Linear types and linearity can be used towards memory models.
In the Wadler type system, a linear value:
* is used exactly once;
* to which there exists exactly one pointer
This has gives the properties:
* no duplication: there exists at most one pointer to a linear value, so destructive update is safe;
* no discarding: every linear value has a use, which represents an explicit deallocation site, so garbage collection is not required;
* the real world (e.g., the state of the file system, or some I/O) can be modeled as a linear value.
In effect, linear values are *read/write*.
Wadler noted that the type system is
extremely restrictive. For instance, reading one element out of a linear array constitutes a use of the array, which forbids any further use of the array!
A workaround is to have the “get" operation return a (linear) pair of the value that was read and the (unchanged) array. This leads to a programming style where linear values are explicitly threaded. This style is heavy and over-sequentialised.
(Here, recall the *move* semantics of Rust, very similar.)
Moreover Wadler made a clear distinction between linear and non-linear types/values.
### Uniqueness types in Clean
Barendsen and Smetsers introduced type modes (*unique/non-unique*) in the `Clean` programming language, where *unique* is similar to Wadlers *linear*.
Also here the real world is considered *unique/linear*.
### C++ unique_ptr
More recently, C++ has adopted *unique pointers*, as a library extension.
However in comparison to the Rust memory model, analysis is out of reach to the compiler, and checked at run-time. Moreover, `move` is always expilict in C++. In effect what `move` does is to create a new pointer to the allocated resource and set the original pointer to `NULL`. If the user tries to access the old pointer, the run-time will abort withe a `NULL` deref error. (A poor-mans solution in comparison to Rust static checking).
## Rust Affine Type System
In comparison to a pure *linear* type system, Rust implements an *Affine*, where a resource *may* be used as most once (compared to the *must* be used exactly once.)
Rust also implemnets the concept of *shared* (borrowed immutable pointers). These are *non-Affine*, and we can have *0* or *N* pointer instance pointing to the same resource (these can be seen roughly as Wadlers *non-linear* types).
Furthemore Rust provides *mutable* pointers, with *Affine* behavior. However, ownership is borrowed (and implicitly returned on exit), in contrast to *move* semantics (under which a moved value is not returned implicitly).
TODO: Some nice examples here....
## Limitations to Static (Compile Time) Analysis
The Rust compiler checks *safe* Rust code according to the safety invariants. However, it cannot deduce safety of all operations statically. In effect that would require full blown program analysis and proof over Rust programs. Instead the `rustc` compiler induces code for run-time verification to cases out of reach for the *borrow checker*.
A prominent example of this is the case of (raw) array indexing. In the general case proving that `i` is in range of an arry access `[i]`, is out of reach for the *borrow checker*, thus code for run-time bounds checknig is introduced by the compiler. Notice, this being a memory safety property, even in *realease* mode (enabling optimization), the generated code will contain bounds check. The only way to prevent this is by expclicit `unsafe` code reading/setting the index by `unchecked` code.
It should be noticed that raw indexing is not *ideomatic* Rust in most cases, a combination of *iterators, zip, etc.* suffice (. The compiler will for such abstractions have sufficient information to conclude correctness by static analysis, and hence the generated code will have no overhead due to run-time verification. In fact, abstractions like *iterators* are considered zero-cost, meaning that there is no additional cost inferred to the execuion in comparison to a hand coded low-level implementation (which by no means imply that there is no execution cost of the operation).
Thus, only for cases when *true* random access is desired/required, raw indexing should be used.
## Code Generation
In short, the complilation process can be broken down to the following steps:
1. Parsing input
* this processes the .rs files and produces the AST ("abstract syntax tree")
* the AST is defined in syntax/ast.rs. It is intended to match the lexical syntax of the Rust language quite closely.
2. Name resolution, macro expansion, and configuration
* once parsing is complete, we process the AST recursively, resolving paths and expanding macros. This same process also processes `#[cfg]` nodes, and hence may strip thingsout of the AST as well.
3. Lowering to HIR
* Once name resolution completes, we convert the AST into the HIR, or "high-level IR".
* The HIR is a lightly desugared variant of the AST. It is more processed than the AST and more suitable for the analyses that follow.
4. Type-checking and subsequent analyses
* An important step in processing the HIR is to perform type checking. This process assigns types to every HIR expression, and also is responsible for resolving some "type-dependent" paths, such as field accesses (`x.f`)
5. Lowering to MIR and post-processing
* Once type-checking is done, we can lower the HIR into MIR ("middle IR"), which is a very desugared version of Rust.
Here is where the borrow checking is done!!!!
6. Translation to LLVM and LLVM optimizations
* From MIR, we can produce LLVM IR.
LLVM then runs its various optimizations, which produces a number of .o files (one for each "codegen unit").
7. Linking
Finally, those .o files are linked together.
### LLVM
LLVM (Low Level Virtual Machine) implements a target independened assembly language, LLVM-IR (with infinite number of registers, etc.).
LLVM-IR, assembly is on a "Static Single Assigmnet" form (SSA), i.e. each LLVM "variable" is assigned only once.
There is a neat coupling to Rusts *Affine* types, allowing information (e.g., regarding mutability) derived at MIR level to be propagated into the LLVM-IR, in order to allow for aggressive optimization by LLVW. (There are still room for further improvement here regarding inner mutability, which is currently overapproximated by LLVM.)
## References
* [ Pottier - Slides, 2007](http://pauillac.inria.fr/~fpottier/slides/fpottier-2007-05-linear-bestiary.pdf)
"Wandering through linear types, capabilities, and regions."
A set of slides on type systems and memory managent.
* [Wadler, P. 1990](http://homepages.inf.ed.ac.uk/wadler/papers/linear/linear.ps).
"Linear types can change the world!"
In Programming Concepts and Methods, M. Broy and C. Jones,Eds. North Holland.
* [Barendsen, E. and Smetsers, S. 1995](http://dx.doi.org/10.1007/BFb0026821)
"Uniqueness type inference."
In Programming Languages: Implementations, Logics, and Programs (PLILP). Lecture Notes in Computer Science, vol. 982. Springer Verlag, 189–206.
* [Achten, P. and Plasmeijer, M. J. 1995](ftp://ftp.cs.kun.nl/pub/Clean/papers/1995/achp95-InsOuts.ps.gz).
"The ins and outs of Clean I/O."
Journal of Functional Programming 5, 1, 81–110.
* [rustc, 2017](https://github.com/rust-lang/rust/tree/master/src/librustc)
An informal guide to reading and working on the `rustc` compiler.
* [llvm, 2017](https://llvm.org/)
The LLVM Compiler Infrastructure
# Nucleo 64
A collection of documentation, tricks and tips regarding the ST Nucleo 64 development kit.
# STM32 Nucleo-64 Board
A collection of documentation, tricks and tips regarding the STM32 Nucleo-64 Board (development kit).
We will mainly cover the `stm32f401re` and `stm32f411re` as these models.
We will mainly cover the `stm32f401re` and `stm32f411re` as these models (main difference is the higher maximum clock frequency of the `stm32f411re`).
---
## Stlink inteface
The nucleo-64 platform has an onboard `stlink-v2.1` SWD interface (programmer) supported by `openocd`. By default the programmer is connected to the target (`stm32f401re` or similar).
---
### Programming external targets
You may use the board as a programmer (connector `CN4` SWD), in that case you should remove the `CN3` jumpers, and optionally desolder `SB15` (SWO) and `SB12` (NRST). See board documentation for details.
## Links
* [Nucleo-64 board](http://www.st.com/content/ccc/resource/technical/document/user_manual/98/2e/fa/4b/e0/82/43/b7/DM00105823.pdf/files/DM00105823.pdf/jcr:content/translations/en.DM00105823.pdf)
Board documentation.
* [Firmware Upgrade](http://www.st.com/en/development-tools/stsw-link007.html)
Standalone java program.
# Clocking
* [Note on Overclocking](https://stm32f4-discovery.net/2014/11/overclock-stm32f4-device-up-to-250mhz/)
......@@ -12,6 +25,6 @@ We will mainly cover the `stm32f401re` and `stm32f411re` as these models.
# ITM
# Add on boards and supporting crates
# Add-on boards and supporting crates
## BLE
\ No newline at end of file
# Course description
In order to be officially enrolled for the course each student need to write (and submit) an individual course plan including grading goals and assessments based on this document.
Assignments are mandatory (as detailed in the README.md).
- Each student should for each assigment 2, .., 5 comment (make an `issue` and/or `pull request` to one other `git`). Comments should be meaningful and constructive. For the assigment 2, .., 5 you should comment on different groups. Strive to spread comments so that each group will get at least one comment for each assignment.
- Each student/group should attend `issues`/`pull request`
Projects should aim to further cover the learning goals as stated in the README.md.
## Blooms taxonomy
Blooms taxonomy assess the (increasing) level of understanding as:
- Remember
- Understand
- Apply
- Evaluate
- Create.
(In the original taxonomy Evaluate was set at a higher level than Create.)
Well its not the only one.
## The SOLO taxonomy
The SOLO taxonomy can be summarised:
- Prestructural - Incompetence: fail, incompetent, missing the point
- Unistructural - One relevant aspect: identify, name, follow simple procedure
- Multistructural - Several relevant inedendent aspects: combine, describe, enumerate, perform serial skills, list
- Relational - Aspects integrated into a structure: analyze, apply, argue, compare/contrast, critisze, explain causes, relate, justify,
- Extended Abstract - Asprects generalized to new domain: create, formulate, generate, hypothesize, reflect, theorize
The advantage of the SOLO taxonomy is that you have progression towards generalization (while the Bloom taxonomy allows progression in isolation).
How can such "mumbo jumbo" be useful towards setting the goals and assessment criteria for Your project? Project assessment is not an easy task and there is no single correct answer to it, so let's study an example.
---
## Example HW AES Support for cortex-m.
- Grade 5. The project aims to `create` an API and library allowing end user memory safe access to the underlying AES hardware of the target platform. The API will provide the features A, B, C, and D, with correcness argued from the evaluation.
- Grade 4. The API/library will be based on an `evalution` (analysis) or requirements and possible solutions based on the Rust Memory model and the `cortex-m-rtfm` task/resource model.
- Grade 3. Low level access to the AES hardware, by `applying`, provided primitives by the Rust language and the `cortex-m-rtfm` library.
---
## Grading
So basically for grade 3 you show that you understand and can apply known methods and provided material. For grade 4, you show that you can make judgements on designs choices. And for grade 5, you put it all together, practical understaning and theoretical judgements. For the example for grade 5, you will show to combine knowledge and understanding of both software and hardware architecture and the theoretical concerns of a sound implementation.
Assessment/evalutation is individual. If you work together in a group, you should detail the description, e.g., student X will focus on the features A and B, while studen Y will focucs C and D.
## Amount versus quality.
The amount of work required to make a complete solution is VERY hard to predict (even industry stuggles with such questions). However in industry a track record of previous projects serves as a baseline, here we face a much harder problem, You are likely new to the topic.
Thus, if you along the project see that covering a complete solution (in this case features A-D) is out of reach (or that when doing the grade 3 you find that B and D is not possible for some reason) you are free to make restrictions (meaning that its ok to drop features provided a motivation). However quality is not to be compromised. Shortcutting the design/evaluation in favour of more features is NOT getting you a higher grade. Ultimatetely, you can still get a grade 5, even if the project fails to meet its goals (provided that the quality of the work done holds up). This is where industry and academia largly differs!
## Engineering
You are becoming engineers, to that end I believe Bloom's taxonomy to a good fit (simle to apply), you will become experts at engineering in your field. Of course this does not prohibit generalization, but the point here is NOT to show the socioeconamical impact and political issues of AES encryption, but rather to engineer a solution. (Actually, we are subject to political issues regarding AES - due to US export restrictions the Nucleo boards are shipped without HW AES, but thats another story.)
# Instructions, what to turn in
For each student
Create a git with a README.md with
- Course name : "d7018e - special studies in embedded systems"
- name, mail address and personal number
- title of your project
- project description (here you may share text with your partner) and grading goals (individual)
I will give feedback to the git (an issue). When we have an agreement you will print the READE.md as a `pdf` and send to edusrt@ltu.se (with the title "d7018e - special studies in embedded systems", so you can be officially admitted and enrolled.
# Suggested projects
---
## Printing device (William)
- Rotating stick with LEDs at the end of the stick that can "print" text by switching the LEDs on and off with the right timings.
---
## Seer (Nils)
Symbolic execution engine for MIR internal format
- Study and understand the Z3 API
- Study and understand the user API (maybe add more functionalty)
- Study outsets for program verification based on seer
---
## LED Audio (John)
- Modulate LED colors and intensity according to audio input
---
## Drivers for NXP (Axel)
---
## WCET analysis for RTFM models using KLEE (Henrik)
- Automated testebed, integrated as cargo sub-command
---
## USB-Hid (Johannes)
---
## ETM Tracing
- Develop an API for setting up ETM trace
[ARM](https://www.arm.com/files/pdf/AT_-_Advanced_Debug_of_Cortex-M_Systems.pdf)
---
## AES Encryption in hardware (Viktor)
- Develop on API for hardware supported AES encryption
---
## CAN bus API and Wheel Sensor implementation
- Develop a CAN bus API for cortex-m0
- Implement a wheel sensor for existing model car
---
## Stack Memory Analysis
- Seer or KLEE based path/call graph extraction
- Target code analysis, per function stack usage
- Static worst case stack analysis for RTFM and/or RTFM-TTA
---
## Ethernet driver for TCP/UDP/IP stack (Jonas)
- Develop driver and integrate to existing TCP/UDP/IP stack
---
## Nucleo 64 support crate
- Drivers for the Nucleo 64, stm32f401re/stm32f411re, similar to the f3/bluepill support crates
---
## Time Triggered Architecture (RTFM-TTA)
- Periodic timers
- Communication channels/message buffers
- Static analysis (for safely bound buffers)
- Static analysis for data aging (opitmal ordering?)
---
## Your ideas...
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.