Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


Using classes/objects with CubeMX project

Dude (hardwareguyvw), C++ is C; just better cool Some of us have been using it in embedded code for a while now...

jrhansen : there are a few things you’ll need to brush up on as you are working at a slightly lower level than for example writing a C++ app on Linux.

You need to go and read about “C++ name mangling” and how the C++ compiler creates type safe linkage and how that affects linking to C code. Note in the example below how extern "C" is used to give C linkage to a C++ function and how a combination of that and #ifdef __cplusplus is used to maintain it if a header is included in C++ that has C functions. Note that the HAL libraries all have this construct already.

You should name your files appropriately so you keep everything straight - so that’s “.cpp” for your C++ source and “.c” for the plain C source. Try not to mix those as you’ll be in trouble.
I’m assuming that’s where your Eclipse says: unknown type name ‘class’ error came from.

Also, while not strictly required, name your C++ headers “.hpp” or something - it’ll help to not include C++ headers in C source (the reverse is easily dealt with - see #ifdef __cplusplus).

As for “calling through” to C++ code from (for example) the CubeMX generated output, you’ll need to make C++ functions with C naming conventions - here’s a simple approach that works fine for a project that you’re reworking from CubeMX side regularly and yet using C++.
Basically you have a C header that you include in the CubeMX main which declares C functions to call from there:


/** @file fred.h
* ie: this is a C lang header
*/

#ifndef APP_FRED_H_
#define APP_FRED_H_

#ifdef __cplusplus
extern "C" {
#endif

//! insert call to this function from CubeMX generated init
void Fred_init();
//! insert call to this function from CubeMX generated loop
void Fred_loop();

#ifdef __cplusplus
}
#endif // __cplusplus

#endif /* APP_FRED_H_ */


You have your C++ headers for declaration of your own stuff:
/** @file Fred.private.hpp
* ie: C++ header file
*/

#ifndef APP_FRED_PRIVATE_HPP_
#define APP_FRED_PRIVATE_HPP_

#include <cstdint> // ie: can include std lib headers
#include <cstddef>

#include "main.h" // ie: safe to include CubeMX C code headers
#include "gpio.h"

/** wrapper class for "application"
*
*/
class Fred
{
private:
//! application singleton - be aware of static initialisation timing & limitations in embedded context etc
static Fred instance;
public:
//! bootstrap C code into C++ class instance init method
static inline void call_init() { instance.init(); }
//! bootstrap C code into C++ class instance loop method
static inline void call_loop() { instance.loop(); }

Fred();

//! initialise application
void init();

//! do application superloop
void loop();
};


#endif /* APP_FRED_PRIVATE_HPP_ */


and then you define that function in a C++ source file (where you get C++ linkage):
/** @file Fred.cpp
* ie: a C++ source file
*/

#include "Fred.private.hpp"
#include "Fred.h"

extern "C" void Fred_init() { Fred::call_init(); }
extern "C" void Fred_loop() { Fred::call_loop(); }

//rest of Fred class definitions go here

Be Aware that you really need to understand the C++ object lifecycle, when are where static initialisation occurs and exactly how much stack space you can blow using some of the fancier STL stuff that does a lot of copies.

Learn about all the good keywords like ‘explicit’ and ‘const’ and how they save you extra copies and make life a bit safer in an embedded context.

There are some pretty good resources out there on the generic concepts involved in calling C from C++ or vice versa.

Oh, and the “weak” linkage functions that HAL provides for various things are also usable from the C++ side if you remember to do the extern C dance.