
Embedded in Rust: Brave new I/O - kartD
http://blog.japaric.io/brave-new-io/
======
vvanders
This is amazing. Register and peripheral config is so easy to fuck up and
waste a whole day chasing down because of limited debugging capabilities on
these platforms. I've hit just about every one of those scenarios these
compile-time guards now catch on one project or another.

Kudos, can't wait to see where to goes from here.

~~~
jfaucett
I know this has me really exited too. I think there is so much potential for
rust in the embedded space. Personally, I'd be content if the core team just
concentrated on making rust the best platform for doing embedded programming.
IMHO that's where rust can really blow the competition away.

~~~
petra
The hard challenge in embedded is porting to every mcu. Can this be done
without convincing mcu companies to do it themselves ?

~~~
henrikeh
Honestly it depends upon what people expect from "the port". A lot of people
seem to be content with Arduino-like software compatibility: high-level
constructs that offer basic functionality expected across a larger number of
mcu's. Even something as "simple" as a timer peripheral will vary greatly
across manufacturers and families of mcu's -- something you'd care about for
real-time control, but not care about in other cases.

ARM controllers are (relatively) uniform and the svd files do a lot of the
work by providing the mapping for the memory mapped peripherals.

Across other devices it becomes even more complicated. AVR devices, AFAIK, are
not providing memory mapped flash. There are also differences in byte v page
erasable flash and eeprom. How would something like this map to Rust? I don't
know and I'm honestly skeptical of the practical use but there is a quite
serious effort put into making the AVR backend for LLVM ready for use.

\---

It really makes me wonder a lot about "embedded" programming and where it is
heading. If I were to bet I'd say that there is a significant movement to
employ more and more powerful "microcontrollers" in order to allow remove all
the resource constraints typically associated with "embedded" programming.

Stuff like Esprino, MicroPython, huge layers of abstraction etc. are today
kind of nice tools for learning and starting out -- but give it a few years
and somebody will ship a successful product build around this. It doesn't
matter that the BOM cost is higher, the current draw is larger and the
complexity and security understanding decreased -- it enables a faster time to
market and in the end that is what makes the business.

The same is happening in FPGA development.

The old-fashioned hardware folks say that "not how it's done" \-- myself
included. But you know what they say:

> When the wind of change blows, some build walls, while others build
> windmills.

~~~
nickpsecurity
No need to speculate: the market data has been showing a move toward 32-bit
just as you thought would happen.

[https://semiengineering.com/mcu-sales-up-
in-2017-and-2018/](https://semiengineering.com/mcu-sales-up-in-2017-and-2018/)

As vvanders says, the hard data shows plenty of the market is still maximizing
profit by using 8-bitters (33%) and 16-bitters (26%). That's a combined 59% of
microcontrollers a 32-/64-bit-only language would be leaving on the table in
terms of deployment. Even ATS language, much more difficult than Rust, has
already been deployed on 8-bitters.

[http://metasepi.org/doc/metasepi-icfp2015-arduino-
ats.pdf](http://metasepi.org/doc/metasepi-icfp2015-arduino-ats.pdf)

Hopefully, Rust stays adding whatever features are necessary to support this
stuff. If not, the Haskell crowd can always grab it up with DSL's like Ivory:

[https://ivorylang.org/ivory-introduction.html](https://ivorylang.org/ivory-
introduction.html)

EDIT to add: A link about 4-bit MCU market that still exists for anyone
wondering what that part of the pie chart was about.

[http://www.ganssle.com/rants/is4bitsdead.htm](http://www.ganssle.com/rants/is4bitsdead.htm)

~~~
jabl
Knowing very little about the low-end micro-controller manufacturing
economics, isn't there some kind of lower bound limit where the marginal cost
of the chip itself is utterly dwarfed by the cost of the pins and packaging?

Sure, a 32-bit chip is bound to be bigger than an equivalent 8 or 16-bit one,
but e.g. the pulpino project has designed a 32-bit one using only 11.6 kGE.
Not very much nowadays. For comparison, according to someone from Atmel, the
AVR core is 12k gates, and megaAVR is 20k gates
([https://www.embeddedrelated.com/showthread/comp.arch.embedde...](https://www.embeddedrelated.com/showthread/comp.arch.embedded/14362-1.php)
).

~~~
nickpsecurity
I have no idea. They've probably optimized the hell out of it in ways we can't
understand. I mean, I thought about getting academics to cover cost of putting
Leon3 or RISC-V on a cutting-edge node where 32-bit would be so cheap FOSS
could undercut them. They'd need to do peripherals, too, but EE students
always need projects to learn with. :) The MOSIS runs I saw at the time had
packaging alone at $10-20 a chip. I know it goes down for higher volume but
how low can I get it on a new product doing maybe 10,000/units a year?

Well, let me show you how low _they_ get it so you know what your reusable-
for-better-products micro would compete with:

[http://www.microchip.com/ParamChartSearch/chart.aspx?branchI...](http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=1014&popular=1)

The smallest one is designed, masked, printed on silicon, packaged and sold in
5k quantities at _24 cents a chip_ at a profit! That's nuts! I can only
imagine what the 4-bitters cost. The cheapest 32-bitter I found were 32-bit
NXP's at 10,000 units for about 50 cents. So, they're getting there. It's an
understatement, though, to say the manufacturing costs are highly competitive
in this sector. :)

------
mikepurvis
This is super exciting, and it smacks a little bit of the C++11 variadic
template based HW init scheme explored in the stm32plus library, eg:

[https://github.com/andysworkshop/stm32plus/blob/master/examp...](https://github.com/andysworkshop/stm32plus/blob/master/examples/timer_dual_pwm_gpio_out/timer_dual_pwm_gpio_out.cpp#L48-L57)

Though obviously the Rust approach provides a lot more guarantees, especially
at runtime.

The one thing that interests me is how flexible this approach would be at
dealing with cases where you have to hack around a hardware bug. For example,
I had a board on it with an I2C expander whose default I2C address was not one
the STM32 was able to address, but could be changed at runtime with an I2C
command. So this was dealt with in firmware by initializing those pins
initially as GPIO and bit-banging in the message to change the address, then
changing them over to the regular I2C peripheral and taking it from there.

How possible would something like that be with this much more tightly
constrained Rust IO model?

~~~
detuur
Looks to me like this is something that can be added to the take() function.
After all, you're generating the crate yourself with svd2rust. I wonder if
these "auto-crates" would be viable for submission to crates.io. This way you
could solve that HW bug once and for all for everyone.

------
robotjosh
These problems that embedded rust is trying to solve are not a big deal. In C
you try to minimize what happens in any interrupt, usually just set a flag,
save a result, and return. You generally use atomic instructions on gpio. To
set or clear a bit mask is atomic so there is not much reason to read-modify-
write gpio in an interrupt or anywhere. I think these solutions would create
more work than they save.

~~~
vvanders
Keep reading, they also cover dealing with exclusive access to subsystems. I
could totally see this being applied to DMA and other long-running peripherals
to great success.

I'll also disagree that this is a small problem. We had one of these that was
so hard to track down that it involved 100+ devices running in a stress loop
over 24 hours with cameras looking for the regression. Ended up being a timing
sequence that could have been caught by a system like this.

The repro was incredibly infrequent but when you've got millions of units even
0.01% chance of something happening is too often.

~~~
__david__
I think the project is neat, but I've also written stuff to do all of that for
embedded C projects. Where you'd allocate pins on the board for the
peripherals you wanted to enable and it would complain if you double
allocated.

That it's auto-generated is the neat part, but then again, you could auto-
generate C code that was just as robust (though admittedly, a lot of that
robustness would be pushed to run-time checks with C code).

------
Animats
Nice. So how many manufacturers create those XML files which describe all the
registers? Is that common in the Arduino community, for example?

~~~
dbcurtis
AFAIK SVD files are an ARM thing.

~~~
twic
Is it that it would be impossible to write an SVD file for another
architecture, or just that vendors don't do it?

If it's possible, and this tooling makes SVDs a really powerful tool for
porting, then perhaps it would be easier for the community to write SVDs for
non-ARM chips than code.

~~~
kbumsik
Probably, but companies wouldn’t do it since they have their own tooling. And
I don’t think the community would like to write it neither. Look at a SVD file
for a single MCU.

[https://github.com/posborne/cmsis-
svd/blob/master/data/STMic...](https://github.com/posborne/cmsis-
svd/blob/master/data/STMicro/STM32F100xx.svd)

It’s a more than 10k loc XML file. It is too much effort for the community to
do that and verify it. And as an embedded system engineer, I wouldn’t trust
the community-driven register definition because even vendors have some bug on
it and it is almost impossible for the community to write a better register
definitions than the vendors themselves. This is a vendors’ job, not the
community's.

------
Animats
This is, amusingly, a lot like Modula I, circa 1979. That had language support
for device registers, cooperative multiprogramming, and interrupts. A very
nice way to program a PDP-11 at the bare metal level.

------
aidos
OT but I’ve just got into microcontrollers for the first time in the last week
via an Arduino Uno. I’m absolutely in love with it and I now need to go a bit
deeper (I’m working on a synth). I get a lot of the concepts like the
registers to control the timers / interrupts but I’ve found a good guide to be
lacking. I haven’t seen a list anywhere of all the available registers and
what the bits do. I get that it’s different for different chips but I thought
the info for more common ones (like the ATMega328) would be easier to come by.

Any hints on where to look?

~~~
flapjackdan
The manufacturer website is where you usually want to go to find the
documentation. The product datasheet will specify the peripherals and register
set for the chip you're looking at, including a description of each register
and the fields within them. Some companies have a different name for this
document. E.g. ST usually define their registers in a Reference Manual.

Here's the datasheet for the ATMega328:
[http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-...](http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-
AVR-Microcontroller-ATmega328-328P_Datasheet.pdf)

~~~
baobrien
To add, ST has a 'datasheet' and a 'reference manual' for each chip and chip
family. The datasheet is usually under 200 pages and is focused more on
electrical information and is focused on a few chips. The ST reference manuals
are generally over 1000 pages and cover all of the software/register
information for a family of parts.

------
bfrog
I ordered up a stm32f3 discovery to tinker with this

------
kurtisc
This doesn't seem particularly courageous, plucky, fearless, valiant,
valorous, intrepid, heroic, lionhearted, manful, macho, bold, daring,
daredevil, adventurous, or audacious.

