I’m in the camp that reckons that there is no greater language than C++. A few years ago I tried out Rust and a few other bits and pieces like Lisp, Haskell, and so on. I sometimes play with Forth, which I consider a highly impractical language, but there’s so many cool tricks you can pull off with it.
Actually, I consider Perl an interesting language. I tried in around 2000, and didn’t much care for it. I then discovered Python, and figured that it was the way things should be done. A couple of years ago I discovered Raku (Perl 6), and it slowly grew on me. It also led me to reconsidering Perl 5 again. I actually rewrote my small accounts package in Perl 5, and I am pleased with the results. For just getting things done, Perl/Raku has a lot to recommend it.
I felt a bit hamstrung with Rust, and criticised its purpose. It seemed to have a few conveniences, but I wasn’t convinced about the whole immutability deal. My argument was: if I want something to be constant, I can just declare it const in C++. Do I really need a new language for that? Constant when I want it, mutable when I don’t.
Nim also struck me as a pretty neat language, and actually better than C++.
The problem is that there’s always a language du jour. I got fed up with the fad-chasing, and decided to standardise on C++. It is industrial strength, stable, high-level, safe (despite the naysayers) and ubiquitous. What more are you expecting?
I have been becoming much more interested in bare-metal embedded development this year. I’ve played with the usual stuff: Arduinos, Raspberry Pi, STM32 blue pills, ESP32. As a sidenote, I should point out that STM8S are great little boards, and a bit of an undiscovered secret. I think of them as souped-up ATTiny chips. If you want a dinky little MCU with low power and a generous number of pins, they really are worth checking out. They’re cheap as chips, too, to coin an old British phrase.
What rekindled my interest in Rust was when I heard that it is good at concurrency. That is something that is sorely lacking in C++ when it comes to embedded systems. Yes there are hacks that work with C/C++, but I wasn’t particularly satisfied with them.
On embedded system, C++ is really just a better C. If you’re wanting to work with bare metal Raspberry Pi development, then you don’t even have a standard C library. I have begun investigations into integrating the nano newlib library into my project. I’ve gotten malloc to work. I have a tiny printf library that I have with my project. I’m aiming to ditch that and try to use nano newlib’s library, which I fully anticipate to be more “feature-complete”. I don’t expect it to be trivial work.
It seems that newlib also offers a C++ library, which is worthy of exploration. I’m expecting that they’ll be a fair amount of effort required to get it to work, mind.
C and C++ bare metal libraries require that you provide a fair amount of foundational structure to be provided in order to get them to work. For example, when you say “stdout”, what do you mean? In Operating Systems, the meaning is clear enough. On embedded systems, well, what is it? I’ve managed to do some integration work so that there’s easy hooking-together of functionality. So if you want to make the uart as stdout, you can just initialise it as “init_uart0_as_stdio()”. I’m likely to rip out that functionality, though, in an effort to migrate to newlib.
But this leads to an obvious question: is there an ecosystem that already provides me with all this? It struck me that Rust might actually fit the bill. Folks seem to be making considerable efforts in providing a good ecosystem for embedded development.
And really, the C/C++ developers don’t seem to be doing that so much. The Arduino environment seems the best out there. It’s always popular to rag on the Arduino library, but I think they have much to offer. I think it’s better than the vendor-supplied offerings that I’ve seen. mbed, for example, I just can’t seem to get on with that.
So what’s resparked my interest in re-evaluating Rust is a potential for a well-developed ecosystem and decent concurrency mechanisms. After all, you could argue that MCUs are all about concurrency and state.
There are some intriguing ideas here. I was reading one article that had a library in Rust where tasks were run solely through interrupts. You could have your interrupt in a blocking delay. But no fear, STM32’s have nested interrupts, so you can give important tasks that must run a higher priority.
So, it has me thinking: Rust’s memory model is either a truly great idea and that non-rusters are missing the point, or else it’s a truly atrocious one. I need to investigate a little more to find out which one is the correct answer. Could it possibly be that instead of being the product of an anal retentive, it is actually a way to simplify code?
So anyway, I got my first blinky light program working, mostly as a cut-and-paste job. I’m using the stm32f1xx-hal crate. I have a vague understanding of the blinking light program, although much of it is a mystery that needs to be explored further.
Leaving aside technical issues, one danger I see is of too much fragmentation in Rust’s embedded space. This is a real danger. The bazaar method has its advantages, but it also has a kind of an “alphabet soup”. Newcomers want one good mature platform, not a dyslexic pot of letters all stirred together which they are free to rearrange as they please.
In conclusion, although my post comes across as somewhat cynical, Rustaceans (Rustafarians?) should take it as a positive. I’m willing to explore further, despite being rather mystified as to how the language works.