The tooling is nearly always C, so it's interesting to see Rust moving into this space. Memory management is not so much of an issue, but multitasking correctness is; perhaps there will be some new micro-RTOS framework with provably correct interrupt handling. (We have sel4, but that's not quite the same thing)
As you get more low level, the tutorials get sparser. You move into FPGAs, where you have a choice of two languages with 1970s design principles, or third-party tools which work despite the manufacturer's total closedness. As you go deeper into actual IC design, nobody will attempt it without supervision from someone experienced to tell you all the little tricks. And then there's analog IC design, which is basically black magic.
Basically whether it's going to deadlock or miss interrupts. Deadlock is immediate disaster, but at least the JTAG will help you .. if the device hasn't self-destructed. Missing interrupts is worse because it's extremely hard to debug.
Forcing DMA to behave would also be great, although this isn't strictly a microcontroller issue. I've seen a few war stories where people are trying to debug memory corruption where the program is completely correct - but some other device has simply DMA'd over it. I think this was involved in https://googleprojectzero.blogspot.co.uk/2017/04/over-air-ex... too.
Checking interrupt priorities sounds like an interesting problem. What is the state of the art in deadlock prevention? It would also be cool if you could tell the compiler "I need this interrupt handler to return in less than n clock cycles." I wonder if someone could write a rust compiler plugin to check that.
https://embeddedgurus.com/blog/2010/12/top-10-causes-of-nast...
it would be great if all those would be easy issues, or solved.
Give Céu a look[0]. It was specifically designed for embedded computing, and compiles to C, making it very easy to interface with existing libraries. It requires no manual memory management, and has very nice structured synchronous reactive concurrency primitives.
(EDIT: I realise that multitasking and concurrency aren't quite the same thing; it also has experimental interrupt support though)
Here's a made-up example for Arduino (for which it has support out of the box[1]). It creates two concurrent fading LEDs at different frequencies, and resetting at the push of a button:
#include "arduino/arduino.ceu"
input int PIN_02; // button input
output int PWM_05; // LED outputs, remember that pins 5 and 6
output int PWM_06; // have a higher PWM frequency on the UNO
// a code block that concurrently fades an LED in and out
// `pin` the output pin of the LED
// `min` min value of the fade
// `max` max value of the fade
// `delay` number of milliseconds to wait between increasing/decreasing `analogWrite`
code/await Fade_forever(var u8 pin, var u8 min, var u8 max, var uint delay) -> void do
loop do
var int i;
loop i in [min->max] do // fade in loop
if pin == 5 then
emit PWM_05(i);
else/if pin == 6 then
emit PWM_06(i);
end
await delay ms;
end
loop i in [min<-max] do // fade out loop
if pin == 5 then
emit PWM_05(i);
else/if pin == 6 then
emit PWM_06(i);
end
await delay ms;
end
end
end
loop do //endless loop
// if *any* of these three code blocks (trails) end, all of the remaining trails in
// a `par/or` are aborted and code resumes (in this case, the loop restarts).
// By comparison, a `par/and` construct would require *all* of the trails to
// terminate before continuing.
par/or do
await PIN_02; // .. meaning that if a button is pressed, we reset the loop
with
// fade the LED at pin 5 quickly between 64 and 192
await Fade_forever(5, 64, 192, 5)
with
// fade the LED at pin 6 slowly between 0 and 255
// note that because it fades over almost twice range (255 vs 128)
// but not exact, it's around eight times slower, not four, and it
// will slowly go out of sync.
// We can push the button to reset however!
await Fade_forever(5, 0, 255, 20)
end
[0] http://ceu-lang.org/, http://fsantanna.github.io/ceu/out/manual/v0.20/With the esp8266 and low end arm controllers, there has been an explosion of languages for embedded applications; micropython, lua, es, basic, even lisp. Particularly for beginners, this is a good thing. Having said that, the dev environments are somewhat lacking at this stage, and I'm wondering if we'll soon be at a point where they'll be enough resources to just put Linux or other OS straight onto the microcontroller.
I wonder how easily one can link C libraries with MicroPython, that'd be the best of both worlds.
I'm assuming you're referring to VHDL and Verilog. There are plenty of other hardware definition languages out there. Chisel, CλaSH, MyHDL, etc... Can see a more complete list here:
https://www.mikroe.com/products/#compilers-software
http://www.astrobe.com/default.htm
http://www.microej.com/resources/supported-platforms/
http://www.adacore.com/press/8-bit-avr-microcontroller/
As for source for information, for me it used to be the Elektor magazine, available in a few languages.
Up to a few years, it was still common to occasionally see Pascal listings on it.
But you are right, the embedded culture is mostly C, and using alternatives, even C++, tends to end in culture clash, as Dan Saks referred to it in his CppCon 2016 talk.
But not single cycle ;)
This is important!
Still a lot faster than a bunch of shift+add!
Oh for the day when RV32IMAF can be considered low end.
This is where Rust's safety helps. Debugging embedded code on small machines is a huge pain. The more problems caught at compile time, the better off you are. A compile time error beats JTAG debugging every time.
The article gets kind of vague once they get beyond LED-blinking and busy-waiting. They implement a brute-force CPU dispatcher and call it "async" programming. They never get to interrupts at all.
Rust on little machines makes sense, but it needs more support underneath to deal with timers, interrupts, and concurrency. There are projects working on this.[1]
[1] https://users.rust-lang.org/t/rust-for-embedded-development-...
NB. the OP is part of that project, from the same author.
It's better to have one good one CPU dispatcher than making users roll their own crappy one for each application.
If you mean every Rust program requires a dispatcher to run, then no, Rust does not need a CPU dispatcher. Thread and locks are not primitives: they're implemented in the standard library (the std part, specifically). The 'thread' safety guarantees don't rely on that functionality, instead the arrows go the other way: the spawning and locking constructs build on the guarantees (driven by the Send and Sync traits, which are purely compile-time constructs) to provide expressive yet safe API. For instance, there's numerous operating systems built in Rust, for instance intermezzOS seems to be pure Rust except for the single file https://github.com/intermezzOS/kernel/blob/master/src/asm/bo... .
If you mean that it would be really nice if there was a general purpose dispatcher library available, then sure, that seems like something that would be great on crates.io.
In any case, I don't see how your comment relates to mine.
It uses new , cheap multi-die assembly techniques, which microchip also used in their ~$1 Bluetooth chip. So I think with time, and with an attractive software ecosystem,we'll see interesting new mcu's and price points.
...and a long list of errata, some of them quite serious: http://ww1.microchip.com/downloads/en/DeviceDoc/80000736A.pd...
(note that if you look for it on Microchip website, the official link to the errata is also wrong at the moment!)
Some people also reported a few heat issues, since it's got to dissipate heat from the memory and heat from the MCU, which starts being a bit large and a bit fast (for an MCU). Nothing extreme, but it has has to be considered in some setups.
IMO, it's better to wait for other revisions of this chip, other versions in this family, or something else.
YMMV though. People in my class who lacked the experience I had with C and C++ from before had to struggle quite a lot.