I'm just getting started with STM32 and this was very informative. I especially liked that you chose a minimal example and walked through the tool chain in detail. It's important to be able to read the compiler output for debugging and optimization and this presented it well. Thanks!
However, why not mention or explain the widely available and extremely affordable ST-link2 or the ST Discovery boards? I suspect that for people just getting started with STM32 these would be more common.
This is excellent tutorial! I wonder if there is similar tutorials for C++11. It would be great to see more information what to do and don't if you want to run your code on bare metal.
Rule #1: Do not use C++11. (To be fair, this may depend on which metal - the language could be perfectly usable on larger systems, but those could be much, much more difficult to program at the bare metal level in the first place.)
it would help me alot personally if you gave some context here? i'm on a project where i'm tooling along happily in C and a new contributor really thinks we should do it in C++11...and arguably some of the things that we're currently doing would be somewhat cleaner. "I've always thought C++ was a mess" is not useful counter. do you have to bring in more runtime? does it require more messing about with stacks?
I honestly think that, at this point, it's often a matter of taste, rather than technical. What tool do you think will make you more productive and interested in the project?
I personally don't think there's anything wrong at all with using c++11 (or any version) on devices like this, so long as the compiler you need to use provides a stable implementation of it. The new language features of c++11, like constexpr and move semantics, and the static meta-programming contraptions that are readily at hand in the STL can all be very helpful to create manageable and fast embedded systems.
Though it usually isn't a free for all. These things are commonly avoided:
* Exceptions (in many cases this alters the call-return sequence, which can increase code size, and add overhead that may not be acceptable)
* Most of the STL (because either a feature requires exceptions to use safely--like containers, or perhaps because the feature doesn't fit into your code section, or just takes up too much of it to be worthwhile)
In theory C++ is a good language, beautiful, even, with its sheer power of abstraction. But nothing is free, and the mental overhead of using this power is enormous. To avoid it, developers (and designers of other, "easier" languages) transfer the overhead onto the run time. With C++ this is done by heavily relying on the data structures and the algorithms that are provided by the C++ standard library. One problem with this is that the most popular (and useful) standard structures rely, by default, on dynamic memory management. While it is possible to customize the way these structures manage memory so as to make it less taxing, this also would create a mental overhead - the one that the developer is trying to avoid in the first place. Another problem that people rarely think about is that the pervasive adherence to the RAII pattern does not come without a run time penalty, either. Constructors are often redundant and are used for "bureaucratic" reasons; destructors, on the other hand, are always "eager," so they would be used for releasing resources, such as memory, regardless of whether this is actually necessary or not. (In comparison, garbage collection is "lazy.") Yet another problem is that the use of templates (which is one of the biggest attractions in the C++ world) leads to an increase of the code size. Again, this is not to say that C++ is a bad language; it's just that it can be a bad choice.
C++ can allow you to write much more efficient code (in speed or space) than C code, but the key word is can. Unless you really know the hardware and really know what you're doing the opposite is possible.
I have written solid, maintainable c++ code for the AVR, but the writing of it was difficult -- it was the maintenance and use by others was easier (example: what looked like a struct actually laid out its code noncontiguously -- but someone who needed to add a small feature didn't need to know that much less worry about it).
C++ is fundamentally a systems programming language so quite a bit of embedded code is written with it. But it's designed to be span tiny to massive applications, and different features are intended for different points on that curve.
Nice, there aren't really that many guides on bare-metal programming. In general the difficult part is finding the Memory Maps across all the data-sheets and programming manuals. ARMs being SOC's these might change across development boards.
Super appreciate this article, might dust off my of Pandaboard again :)
9 comments
[ 4.0 ms ] story [ 30.8 ms ] threadHowever, why not mention or explain the widely available and extremely affordable ST-link2 or the ST Discovery boards? I suspect that for people just getting started with STM32 these would be more common.
I personally don't think there's anything wrong at all with using c++11 (or any version) on devices like this, so long as the compiler you need to use provides a stable implementation of it. The new language features of c++11, like constexpr and move semantics, and the static meta-programming contraptions that are readily at hand in the STL can all be very helpful to create manageable and fast embedded systems.
Though it usually isn't a free for all. These things are commonly avoided:
* Exceptions (in many cases this alters the call-return sequence, which can increase code size, and add overhead that may not be acceptable)
* Most of the STL (because either a feature requires exceptions to use safely--like containers, or perhaps because the feature doesn't fit into your code section, or just takes up too much of it to be worthwhile)
* RTTI (which can increase the size of a vtable)
https://news.ycombinator.com/item?id=12138374
I have written solid, maintainable c++ code for the AVR, but the writing of it was difficult -- it was the maintenance and use by others was easier (example: what looked like a struct actually laid out its code noncontiguously -- but someone who needed to add a small feature didn't need to know that much less worry about it).
C++ is fundamentally a systems programming language so quite a bit of embedded code is written with it. But it's designed to be span tiny to massive applications, and different features are intended for different points on that curve.
Super appreciate this article, might dust off my of Pandaboard again :)