
Rust on AVR: Safer microcontrollers almost here - mmastrac
http://dylanmckay.io/blog/rust/avr/llvm/2017/02/09/safer-microcontrollers-almost-here.html
======
IgorPartola
Having more programming languages for embedded platforms is always great. If
all you know is Rust or Python or JS, etc. it is great to have it as an
option. But I have to wonder if the specific claim of type safety really
translates here. In my (albeit limited) experience, certain classes of errors
just don't occur on embedded systems because there is not enough room for
them. For example, there is no double free() because heap memory is not a
thing. I suppose you can still have off by one errors, and problems with
referencing/dereferencing, but once again in my experience you usually find
this stuff pretty fast because your code just won't run. Am I wrong here?

~~~
ekidd
I used to work as an embedded systems developer (for systems where a single
failure could cost a quarter million dollars), and I've experimented with
kernel-space Rust just for fun.

Rust is a surprisingly nice language on bare metal.

If you use '#![no_std]' in Rust, it disables the standard library and
substitutes the 'core' library. This has no 'malloc' (unless you supply one,
which is easy) and no OS-level features. But you still get iterators, slices,
traits, "scoped" closures and generic types. You get a lot of abstraction with
basically zero overhead. And don't forget that embedded systems have lot of
state machines, which are nice to implement using Rust's "tagged union"
support and exhaustive 'match' statement.

Here's an example of a Rust I/O port wrapper ([https://github.com/emk/toyos-
rs/tree/master/crates/cpuio](https://github.com/emk/toyos-
rs/tree/master/crates/cpuio)) and an interrupt controller interface
([https://github.com/emk/toyos-
rs/tree/master/crates/pic8259_s...](https://github.com/emk/toyos-
rs/tree/master/crates/pic8259_simple)). These APIs are reasonably pleasant for
something so close to the metal.

Rust would be a very agreeable programming language on an AVR system, IMO. And
not necessarily because of pointer safety, either.

~~~
StavrosK
As a hobbyist and C junior, if I can get anything higher level than C, I'll be
ecstatic. Of course, it's going to be the same as with micropython, which is
fantastic: The entire ecosystem is in C.

I tear my hair out every time I have to wrestle with C for the simplest
things, though, whereas Rust is a joy to write.

~~~
yjftsjthsd-h
On "full size" systems we solve that with FFI, but I don't know whether that
would work here is not.

------
sagebird
Why do programming language maintainers for a front end to LLVM (rust) need to
consider/patch/modify their front end to properly support a llvm backend, like
AVR?

(My mental model was that once you add a backend to Llvm, every programming
language that uses llvm should magically work with it.) Does LLVM's design
fail to capture the full problem space? Are there out of band concerns that do
not lend themselves to be generally expressed?

~~~
RX14
If you want an example of a llvm-based programming language porting to a new
architecture, see [1]. The issues has a checklist of things that were done,
and a readable diff.

Some of the things that needed to be implemented in the frontend was the ABI,
unwind support, C bindings for the new architecture. Some of these don't apply
as much to rust but you can see that LLVM doesn't do a perfect job. The diff
is still quite small however.

[1] [https://github.com/crystal-
lang/crystal/pull/3491](https://github.com/crystal-lang/crystal/pull/3491)

------
jfries
I think that one thing that makes it difficult to write safe microcontroller
code is the interrupts that can interrupt the normal flow at anytime. Does
Rust on AVR help with this at all, or is it an orthogonal issue?

~~~
jononor
Yes, really interested in how interrupts can be modelled with Rust. Preferably
a safe abstraction without going full RTOS?

~~~
steveklabnik
My toy OS project has a partial implementation of interrupts for x86_64:
[https://github.com/intermezzOS/kernel/blob/master/interrupts...](https://github.com/intermezzOS/kernel/blob/master/interrupts/src/lib.rs)

Just enough to get keyboards working, still a lot of stuff to do, but the
foundation is there.

Used like this:
[https://github.com/intermezzOS/kernel/blob/master/src/main.r...](https://github.com/intermezzOS/kernel/blob/master/src/main.rs#L48-L68)

------
pinpelipon
Does this mean that some day I might be able to buy a cell phone that has a
radio chip that is not full of buffer overflows and other types of flaws?

------
boznz
I dont know rust from jack so I am interested to know why it will compile a
safer program than a well written C one and what makes it better than other
safe embedded languages like ADA?

Note it wont affect me as I mainly use PIC micros

~~~
milesrout
It won't. To do anything useful on a microcontroller you would have to drop
into 'unsafe' so often that any idea of safety is out of the window.

~~~
jononor
Unsafe should only be needed at the edges of the program, in dealing with IO.
These parts should always (not just with Rust) be put in some platform layer
used by the application code. This allows the majority of the application code
to be verified easily, with unit-tests, end-to-end tests as well as writing
simulations. Done right the verification can be ran both on host and on-
device. Another key benefit is that this allows to develop majority of the
software before the hardware is ready. When possible, use a platform
abstraction which is already tested. As verification of this code is harder,
typically requiring hardware and external interactions.

I hope that Rust unsafe/safe concept makes the platform/applogic boundary more
visible and explicit, so people follow these practices more often.

------
dopeboy
It's been seven years since I've programmed on embedded systems. I remember C
ruling the day. Has that changed at all?

~~~
boznz
C++ has gained a bit of ground recently but C still rules the roost especially
on smaller micros

~~~
pjmlp
To add to it, this was the issue of a few CppCon talks, namely how to bring C
devs to write safer code.

------
loeg
I'm kind of surprised and impressed that LLVM (and GCC) can target AVR well.
It's a tiny machine with some quirks. Registers and IO ports are mapped into
low memory. The big ones have a weird 24-bit segmented addressing mode. Some
crazy ones have DES intrinsics.

~~~
kosma
It's still a decent machine for C especially when compared with, say, 8051.
I'm currently developing an entire product line based on a '51 derivative and
just seeing what kind of assembly Keil C51 compiler produces is enough to make
my eyes bleed. The amount of kludges required to make C work on that
architecture is horrifying. Want an example? There's no stack when running
under C51.

~~~
vardump
There's certainly a stack when running under C51, for function call returns.
C51 just assigns local variables into 128 byte data segment. But say, PUSH ACC
works just fine when you drop into assembler.

Then again, stack on 8051 might be sometimes pretty small. From 10 to 128+
bytes.

~~~
kosma
Right. Still, the fact that local variables aren't stack- but overlay- based
is enough to blow my mind.

------
ubercow
I'm so happy for this, it's gonna be great to use Rust for Arduino stuff

------
pjmlp
Nice work, although there are already a few options for safer microcontrollers
when one bothers to look beyond C.

More options is certainly even better.

------
Keyframe
Sounds exciting to have options apart from C and asm. How about something for
us PIC plebs though?

~~~
pjmlp
In regard to safety you could use Basic and Pascal compilers, while Rust
doesn't arrive.

[https://www.mikroe.com](https://www.mikroe.com)

------
dbcurtis
Latest commit in the git repo 8 months ago? is this project active?

~~~
jononor
Which repo? Last commit to LLVM AVR git is just marking it as being upstream
in LLVM SVN

------
pmorici
People still use avr?

~~~
ComputerGuru
Yup. You'd be surprised how much functionality people can wring out of an
ATTiny85 or an ATMega328p.

~~~
pmorici
Figured people would be moving on to ARM M0+ chips for new development.

