One of the biggest fears of embedded systems developers are stack overflows. FreeRTOS includes a cool feature to monitor and catch task stack overflows. But what about the MSP (Main Stack Pointer) on ARM, or the interrupt stack? What if not using an RTOS and running a bare-metal application?
Checking stack size used
There is a simple way monitoring stack usage at runtime, and for this I want to share the routines and what is now available inside the McuArm module.
Every embedded system developer should know by now, that using printf() is not a good thing for smaller systems. Printf() and the like are not only problematic from a code and data size perspective, they are infamous for vulnerability attacks too.
In this article I’ll show you multiple ways how to ban printf() or anything similar you want to avoid.
I’m in the final stage of finishing a electrical vehicle (EV) charger controller, which optimizes battery loading using the available PV system: use as much as possible the solar energy and not the grid.
The ARM Cortex M architecture has many features which are underused, probably simply because engineers are not aware of it. SWO (Single Wire Output) is a single trace pin of the ARM Cortex-M CoreSight debug block. trace pin uses the ITM (Instruction Trace Macrocell) on ARM Cortex. It provides a serial output channel, at a high speed higher than the usual UART, because it is clocked at half or a quarter of the core clock frequency, depending on the core and implementation.
As such, it is an ideal high speed output channel to send text or data to the host. This is how it is usually used, but what is unknown to many: it can be used in a bidirectional way with the help of the debugger.
The topic of this article: how to redirect standard I/O like printf() or scanf() using the SWO ITM console: means both sending *and* receiving data over the SWO debug channel: that way I can use it as a kind of UART with a single pin only.
When developing with C or C++ an application, then you mostly focus on your own code. You don’t want to bother with the details how input/output functions like printf() or scanf(), and you might just use these functions and helpers and that’s it.
The implementation is part of the ‘C Standard Library’ (or C++ Standard Library). In the world of Linux, this is usually the ‘glibc’ or ‘GNU C Library, and one usually link with ‘libc’. That provides the implementation of printf(), or use ‘libm’ if using math functions like sin() or cos().
In the embedded world, things are much more complex, with plethora of choices, for example in the MCUXpresso IDE:
One little nasty assertion in the GNU standard library appeared a few days ago, kind out of nowhere, reporting “REENT malloc succeeded”:
Obviously it was caused by the call to srand() which sets the ‘seed’ for the standard library (pseudo) random number generator. The assertion happens as well later for calling the rand() function.
With the war in the Ukraine, energy prices in Europe reached new record levels. This initially affected the gas price which does not affect me directly. But it had a big impact on the price for electrical energy too. In my village, the price for electrical energy is now at 0.45 CHF/kWh, starting October 1st 2022. It is twice as much as what it used to be, and three times more what it used to be the price for the energy at night time.
Saving energy always makes a lot of sense, now even more, both for the environment and directly saving money. Luckily, I started thinking about optimizing the electrical energy used in my house back in 2021, and now in 2022 it really pays off: The daily average of 16 kWh/day (including heating and cooling) came down to 7 kWh/day, or from 4.5 MWh/year down to 2.4 MWh/year, or a reduction of 47%.
There were different areas contributing to this very positive result:
The above graph shows the changes in the different categories, from 2021 (blue, 4.5 MWh) to 2022 (orange, 2.4 MWh).
Sometimes it can be a challenge to update or add plugins to older software or Eclipse versions. The ‘CodeWarrior for MCU’ from NXP is legacy and replaced by the newer MCUXpresso IDE and tools, but I continue to use CodeWarrior for our older projects, and it still works fine after all the years and Windows host updates. However, trying to install from the standard eGit Update site fails:
In many embedded applications, it is mandatory that memory allocation is static and not dynamic. Means that no calls to things like malloc() or free() shall be used in the application, because they might fail at runtime (out of memory, heap fragmentation).
But when linking with 3rd party libraries or even with the C/C++ standard libraries, how to ensure no dynamic memory is used? The problem can occur as well for C++ objects, or a simple call to printf() which internally requires some dynamic memory allocated.