cancel
Showing results for 
Search instead for 
Did you mean: 

Which guidelines should I follow to write C++ code for STM32? (please do not evangelise me on not using C++ on micro controllers)

enhering
Associate III
 
6 REPLIES 6
enhering
Associate III

1 - If you do not need more than one instance of your class, make your methods and member variables static.

2 - UART at 9600baud takes about 1ms per character to transmit data. If the data is not being transmitted completely, increase the HAL_UART_Transmit timeout.

TDK
Guru

No dynamic memory allocation.

If you feel a post has answered your question, please click "Accept as Solution".

2 - how's that related to C++?

And btw, using C++ on the one hand, but on the other hand using a baud rate of 9600... that's a strange mix of hi/lo-tech! 😉

You're bound to 9600 by another device?

Danish1
Lead II

Try not to use inheritance where you don't need to.

The reason I say that is that memory-corruption can occur - most-likely from a bug in your code but also possibly a radiation or ESD event.

With inheritance, your object contains a pointer to a table of the call-addresses of methods that are inherited. And if that pointer gets corrupted, you'll have a jump to a random place in program memory, which is almost-certain to cause a crash (even if you had written your code to be robust against "data" being corrupted).

It took me quite a while to link a "random" crash in my code to such a pointer being corrupted. The "base class" pointer isn't something my IDE exposed, so looking at the object in the debugger didn't show it had been compromised. It was just that a method/function-call caused an immediate crash.

I wasn't expecting that problem because I never used my base class except for the one particular statically-allocated object that derived from it, and that object was only ever referred-to directly (not as a pointer to base class).

Once I know to look for that pointer being corrupted it was relatively easy to put a break-on-write on its location and discover where I was (in my case) writing beyond the end of a buffer.

Danish

DCarr.1
Senior

Many of the classes in the STL library rely on dynamic memory, by default using new/delete, which as a general rule you're typically going to want to avoid. The library provides versions of pretty much everything which allow you to provide your own allocators, although in my experience it's better to just avoid STL as much as possible and leverage the inherent advantages of an object-oriented language where appropriate.

Harvey White
Senior III

Assuming you're using CubeMX to generate code, and then possibly FreeRTOS, which says a complex project.....

I use C++ for most everything, putting a C++ layer over the basic MX drivers. I structure my programs so that the changes to main.c are minimal, and call a bridge routine (written to be able to be called from C). That bridge routine then calls the C++ program that sets up the main FreeRTOS loop.

I do use inheritance where it makes sense, although many of my routines are of the "has a...." rather than is automatically a child of... child of.... child of many.....

Bear in mind that in C++, there's an implied scope of variables that is messed with by FreeRTOS. So a task in FreeRTOS, even if owned by the class, does not have clean access to the variables of that task. Sometimes, it needs to be separate from the task, which works (LED blinking done by a task, each LED is an instance of the task).

Other than one instance of the main.c calling the bridge program, no C++ program is called by a C program. C++ calls the C driver programs without a problem. Make sure you wrap some of the functions you call with semaphores, you may need them. Not sure that the MX drivers are really intended to be used in a multi-thread environment.