The water’s not that deep - you’ll be fine
You will find tutorials and blog posts telling you how easy it is to get started in Rust on an STM32 platform.
Or at least, they are written by experienced embedded developers who are simply transitioning to Rust.
As an Arduino developer, you are familiar with:
- downloading the IDE
- changing the board type
- copy-pasting some demo code
- change the odd pin assignment
- compile and upload
This is not Arduino
Instead you are now faced with:
- Manual setup of your toolchain
- Manual configuration of your debugging tool/uploader
- No out of the box integration with your IDE
- Blog posts which are outdated, whose code won’t compile anymore
- Libraries at a much lower level than Arduino ones
- Having to be very familiar with your chip’s data sheets
The Wrong Way to Learn
My initial approach to learning, which has usually served me well, was
- Avoid any dusty official documentation, it takes too long to digest all that detail
- Find a respectable looking blog-with-code
- Relicate the steps in the blog; make some trial and error modifictions; add some interesting looking libraries to tinker with peripherals
- Glue together the various bits of experimentation into your actual project
I wasted a lot of time. Rust and the libraries in the ecosystem have changed in the last 3 years, and most of the blog posts were written by seasoned embedded developers who were early adopters in Rust. Although I learned something from every one of them, it was not the right apporoach to learning a whole new language and ecosystem.
Take Your Time, Structure Your Learning
The right way is to take your time and use the official docs - they are excellent, and shouldn’t be rushed. I am using a multi-faceted approach.
- Learn Rust on its own - with no embedded distractions
- Get started with embedded Rust Start at the beginning. Don’t fast forward until you’ve completed the next step, QEMU
- Use the emulator QEMU even if you never plan on using the emulator ever again, it helps you grasp the toolchain and ecosystem.
- Get your first blinky working in a VS Code environment This is my own quickstart code. It is using a HAL, so it is skipping ahead a few steps, but I find it useful to have a ready to go starter project
- Learn the chip
- Learn about SVDs and Peripheral Access Crates using this excellent tutorial from Vivonomicon
- Get to know the 1134 page Reference Manual. This is not optional! But you don’t need to read it cover to cover
- Get to understand the blinky code from the point of view of the Reference Manual. Start at chapter 9 “General-purpose and alternate-function I/Os (GPIOs and AFIOs)”. Comparing the Reference Manual to the code you’ve written using your PAC, will help you grasp how the STM32 registers work for IO.
- Go and get a HAL, and learn to use it But make sure you get the right one. There are deprecated projects out there to catch the unwary.
- After using the Peripheral Access Crate directly, the HAL, to me anyway, is more complex and less intuitive due to it’s use of the inversion-of-control principle. But, getting used to the way it works should help you write code which can be ported to other chips
- Get to know RTFM - Real-Time-For-the-Masses. I’m yet to get into this, but it does feel like the right way to go for most projects.
The above list is not a strict sequence, I am learning a little about each of the 3 top level areas each week. Progress, for me at least, is not particularly fast, which can be frustrating when you have projects in mind. Which is why the next point helps.
Keep a Learning Log
This has helped me to avoid the feeling that I’m not getting anywhere. It helps me see what to study and try out next. I abbreviate book titles.
I use a simple table in OneNote
|Pckt RustIn7days, ch1, ch2 Got a bit stuck on Traits with Generics
|RBE ch1, ch2
|RBE ch3 skipped linked list example
|RBE ch4 variable shadowing. Not sure of the point!
|RBE ch5, ch6, ch7, ch8.3
|RBE ->8.5.1 Refs!! Destructuring. See also RB (RustBook) 4.1,4.2
|RBE 8.5.3, 8.6, 8.7 9, 9.1 Binding… didn’t really get it, but likely don’t need to!
|If…let - stupid syntax, blame Swift
I’ve seen lots of more complex Learning logs online, but for me, just a running virtual bookmark is enough. Notes may be a page or chapter reference. Sometimes I’ll note an immportant topic I convered. I’ll note any code I worked on. My log isn’t well written or consistent in its type of content. I don’t go into great detail about what I’ve learnt, it isn’t a summary. It is more to track progress.
I’ve found it a great help.
So that is my Rust learning story so far. I hope it helps!