
Raspberry Pi Bare Metal Programming with Rust - thiagopnts
https://blog.thiago.me/raspberry-pi-bare-metal-programming-with-rust/
======
jcoffland
As a long time C programmer this is not very convincing. A C program to do the
same requires far less voodoo. All you need to do is take the address of the
GPIO register then toggle the bit. No name mangling. No error handlers to
override. Don't get me wrong I know rust does have some compelling features.
It does seem odd to me that so many of what would be compiler options in C are
hard coded.

~~~
pcwalton
Point by point:

> All you need to do is take the address of the GPIO register then toggle the
> bit.

Yes, and that is unsafe. Rust makes you put that in an unsafe block, to
encourage you to build safe interfaces. This is a good thing.

> No name mangling.

The alternative to name mangling is not having a module system, with all the
fun name conflict issues that come with it. Rust made the right decision here.

> No error handlers to override.

C has no concept of a panic handler because what would be panics in C are
undefined behavior. Undefined behavior is bad for safety and understandability
of the code. Having to declare an error handler is a small price to pay.

> It does seem odd to me that so many of what would be compiler options in C
> are hard coded.

Because Rust is safe by default. That's one of its most important features.
Being more like C in the ways you mention would mean compromising that
principle.

~~~
jeffreyrogers
After having played around with Rust a bit and seeing it used in some non-
trivial applications I've grown to like it a lot, despite being an initial
skeptic. However it's aggravating that in every post about Rust which raises
valid criticisms about the language (in this case having to do with the ease
with which C allows you to do low level programming), those associated with
the Rust project leap to its defense and suggest that Rust's decisions are
right for every situation.

Just because Rust can't easily do things that C can doesn't make it a bad
language, but it does mean that, shockingly, there are somethings that Rust
isn't as well positioned for as other languages are.

Similarly, there are things that C is bad at. Both at the high level and the
low level. At the low level it hides too much of the CPU's features so for
some very low level programming you need to drop to assembly. At the high
level it has obvious deficiencies, many of which Rust addresses, but for
interfacing with the actual hardware it is tough to beat C in terms of
convenience.

~~~
pcwalton
Of those three issues, I see not sectioning off unsafe code as the only real
defensible choice when comparing C to Rust. Whether you should have to type
"unsafe" is a legitimate tradeoff; if all your code is unsafe, the unsafe
keyword adds noise.

Undefined behavior and the lack of namespacing don't fall into this category,
though. C would be a better language all around if it required that null
pointer dereference trap to an error handler (at least on hardware with an MMU
or MPU). It would also be a better language if it had a module system.

Not every engineering decision is a tradeoff. Sometimes certain decisions are
just better all around. I think that modules and error handlers fall into this
category.

~~~
mpweiher
> Not every engineering decision is a tradeoff.

Scratch the "not". For example, if I have a small-enough code-base, a module-
system, is not worth it, unless it has zero cost. Or if the module system
doesn't fit my needs, it will often be easier to create what I need if I don't
have to work around what is there. Same with error handlers.

 _Every_ engineering decision is a tradeoff, though you may be in a space
where the tradeoffs obviously point in one direction.

~~~
pcwalton
A module system is always worth it because every program needs to use library
functions. Even if you think you don't, LLVM will generate calls to library
functions for ordinary code; for example, if you move structures around on the
stack, LLVM might just decide to call memcpy(), even if you didn't ever import
string.h. (Checking your code after the fact to verify there are no library
calls doesn't get around this because a new version of the compiler might add
a library call where there wasn't one before.) Now you want some mechanism to
isolate your code's names from the library's names. That's a module system.

~~~
nitrogen
Does bare metal Rust also use memcpy() or other library functions? If so, how
are those linked into the final binary?

~~~
steveklabnik
Yes, LLVM will assume three or four functions exist regardless. The rlibc
crate provides a Rust implementation of them, so you just add it and you're
done.
[https://github.com/alexcrichton/rlibc](https://github.com/alexcrichton/rlibc)

------
notabot
As a C programmer who fiddles with low level stuff I wonder why people get
exciting about such trivial thing.

Don't get me wrong. Rust is an interesting language. The thing described in
this post is well within its capability, i.e. IMO there isn't really anything
that worths bragging about. Such trivial thing neither demonstrates the real
potential of Rust, nor answers important questions from real world engineering
perspective.

I'm all for having better tool to write low level stuff. I have dabbled with
Rust and the experience was eye-opening. I think Rust still have a lot to
catch up though.

~~~
rdc12
Has hello world ever been exciting, it is only really a building point. You
can't do anything intersting until you know the basics, of building and
flashing the board.

The question is what does Rust have to offer as your embedded program grows.

~~~
notabot
> Has hello world ever been exciting

The HN upvote says otherwise. :-)

But I guess had there been an HN-equivalent in assembly age people would get
excited about C, too.

> The question is what does Rust have to offer as your embedded program grows.

Exactly.

We are aware of the good, bad and ugly bits of C. The industry has built
extensive tooling around it. Rust has a long way to go. I certainly wish to
see more pioneering projects from Rust.

------
Aeolos
I have the perfect project for this! Generate a signal using the GPIO ports to
drive a mirror and camera in a synchronized fashion.

Does anyone know if the RPi GPIOs can be driven at around 80KHz? I've seen
reports that this is possible, but that the USB or video driver tends to lock
the CPU for long times, messing with timings - but hopefully running on bare
metal would take care of that.

~~~
jcoffland
You could do this with much less than an RPi. I would recommend using an AVR
or better yet a 555 timer if all you need is an 80KHz signal. Let me know if
you want help with this I'm looking for projects like this or something much
more complicated.

~~~
IshKebab
I wouldn't recommend an AVR. That is outdated technology. Even Atmel mostly
makes ARM microcontrollers now (and they are much nicer than their AVR ones).

~~~
niccl
horses for courses. If you want a small microcontroller that has a very simple
IO model then avr is great, and if you use something like an attiny they're
cheap as ... chips.

~~~
zokier
At small scale the price difference is pretty meaningless or even non-
existent. For example right now the cheapest AVR at quantity of 10 costs
$0.837, while cheapest ARM is $0.714.

(prices checked from digikey)

------
akerro
Is Rust the future? As a C++ (hobby), Java (full time) developer, should I
invest my time in Rust?

~~~
jacquesm
Rust, Go, Java, Scala, Clojure, Javascript... (leaving out quite a few other
choices for brevity). They say choice is a good thing but too much choice is
actually really annoying and fragments the community across a very large
number of ecosystems.

~~~
akerro
I can't stand JS and Go syntax, I tried a few times... This is the worst thing
that happened to humanity after in XXI century. I feel more comfortable with
Prolog than with JS.

~~~
jacquesm
In a way Go is a step backwards from C towards Pascal. Since a number of
people that had extensive C experience and were in fact present at the birth
of the C language made that decision I figure they are doing it for a good
reason.

I can read Go easily enough, I haven't done any major writing in it (yet),
other than some minor work on Hugo trying to help to nail down/replicate a
bug. It was easy enough that I think I'd pick it up quite fast, the syntax
feels 'weird' to me but that's most likely just unfamiliarity.

------
akhilcacharya
Outside of C, are there any other languages or platforms that can do this? I'd
like something modern, but I haven't liked what I've seen with Rust
personally.

~~~
pjmlp
Still alive: Ada, SPARK, ATS, FreePascal, D

Controversial: Go (if someone ports the runtime to bare metal), embedded JVMs,
embedded, Swift (depending how Apple drives it), .NET Native (if C# gets
missing features from System C#)

Faded away: Algol, PL/I, CPL, Mesa, Modula-2, Modula-2+, Modula-3, Oberon,
Oberon-2, Active Oberon, Component Pascal, Turbo Pascal, Forth, Sing#, System
C#

~~~
jeremyjh
I think he was asking which languages could actually be used to do this today,
without writing a new cross-compiler first.

~~~
akhilcacharya
That's exactly right. I didn't know that D would be an appropriate language
for things like this - I'll have to check it out.

~~~
pjmlp
Check some of the videos here

[http://wiki.dlang.org/Videos](http://wiki.dlang.org/Videos)

Namely "Tiny, Ubiquitous Machines Powered by D" and "x86 Bare Metal and Custom
Runtime Programming".

------
nickysielicki
I remember reading a couple months ago that bare metal using Rust was in a bad
state. If I recall correctly the outputs were prohibitively large, among other
issues.

Has that changed?

~~~
steveklabnik
The real reason that Rust isn't necessarily wonderful for bare metal is that a
lot of the things you need to do aren't stable yet.

Binary size isn't a problem, though. A lot of the threads talking about sizes
aren't doing all the stuff you need to get truly small binaries. That's
because, as this stuff is on nightly, it has much worse (or no) docs, so it's
easy to miss things.

I'm working on a little kernel, the one linked in the first line of the post,
and it's great.

------
kod
If you want to play around with the code in this post that requires nightly,
multirust makes it much more pleasant to use nightly and / or stable rust.

[https://github.com/brson/multirust](https://github.com/brson/multirust)

------
s986s
Very cool! Rust has been impressing me alot these past few months.

------
Animats
Very nice. A few more months and that should be stable.

------
kalimatas
Thanks for sharing!

