Cube++ simplifies the process of creating a C/C++ codebase for an STM32 microcontroller in STM32CubeIDE while fully supporting CubeIDE's native code generation. This project is intended to be a submodule in a CubeIDE project to give access to some useful C++ wrappers and a method of routing control from the C main.c file to the C++ codebase located in one dedicated folder to support cleaner code compared to mixing it with code generation, and preventing the need for constantly renaming main.c
to main.cpp
every time code generation happens. Please refer to the Setup Instructions below for a guide on how to setup the project with Cube++
Cube++ is based on the core code of the Student Organization for Aerospace Research's Avionics Software. As the codebase was originally intended for use in a specific way there are still updates to be made to improve compatability and capabilities.
- Create a new project for your specific chip and select C++ when it asks you for Language
Open the .ioc
file by double clicking on it inside the project
- Under
Middleware and Software Packs
enable FreeRTOS usingCMSIS_V1
(unless you are using a multi-core CPU in which caseCMSIS_V2
may be preferred) - Change the following values in config parameters
- FreeRTOS Heap Size to fairly large (eg. 64KB on a 90KB RAM chip)
- MINIMAL_STACK_SIZE to at least 192 Words
- Under Software Timer Defines "USE_TIMERS" should be enabled
- Under
Middleware and Software Packs
> FreeRTOS > Advanced Settings- Enable USE_NEWLIB_REENTRANT
- Under Computing > CRC
- Enable Activated
- Under
System Core
> SYS > Timebase Source- Change the timebase source to a timer instead of SysTick (CubeIDE will recommend you do this upon code generation)
(if not defining DEBUG_DISABLED
as mentioned in the Codebase Setup section below)
- Inside Pinout and Configuration > Connectivity
- Select a UART/USART line for debug (if you choose to enable it) and set to Asynchronous mode with hardware flow control off
- At the top select Project Manager tab, go to the Advanced Settings and select the UART line for debug under Driver Selector
- Change this UART line driver from
HAL
toLL
- Change this UART line driver from
Add the Cube++ repository into the root folder as a submodule using one of these commands
SSH
git submodule add [email protected]:cjchanx/CubePlusPlus.git Cube++
HTTPS
git submodule add https://github.com/cjchanx/cubeplusplus-examples.git Cube++
Please add the following to include paths:
(right click on the folder and select Add/Remove Include Path...
)
- Cube++/Core
- Cube++/Drivers/Inc
- Cube++/Libraries/embedded-template-library/include
Please ensure the following folders are not in the exclude from build option:
(right click on the folder, select properties, select configuration 'all configuration' and untick "select Exclude Resource from Build
")
- (none for this version)
An example project utilizing Cube++ with basic CUBE_PRINT support, in addition to a Debug receive task for parsing input data on the debug line can be found at https://github.com/cjchanx/cubeplusplus-examples/tree/main/Basic_Debug
- It is recommended to setup a new folder called
Components
orModules
in the root where all the code goes. - There are a few files that you should have in
Components
/Modules
:- SystemDefines.hpp : An example can be found here
- main_system.cpp : This can be named anything you want, but should contain the run_main() function that is the entry point for your codebase, example here
- main_system.hpp : Header file for main_system.cpp, example here
- SysCore/Inc/RunInterface.hpp : Header file for the run interface which allows C code to call into the C++ codebase without errors, example here
- SysCore/RunInterface.cpp : Code file for the run interface, example here
- Setup Debug UART
- Setup one UART line as the UART debug line by following theinstructions uder Cube++/Drivers/UARTDriver_README.md, this should correspond to UART Driver linked to the
constexpr UARTDriver* const DEFAULT_DEBUG_UART_DRIVER = UART::Debug;
line that is required to be in the SystemDefines.hpp file - In the case that you do not want a UART line dedicated to debug, then set DEFAULT_DEBUG_UART_DRIVER to nullptr, and
define the macro DISABLE_DEBUG using
#define DISABLE_DEBUG
inside SystemDefines.hpp
- Setup one UART line as the UART debug line by following theinstructions uder Cube++/Drivers/UARTDriver_README.md, this should correspond to UART Driver linked to the
- Setup main.c
- Under Private includes in the first USER CODE BEGIN section, add the run interface as an include
RunInterface.hpp
- Inside the int main(void) function definition, add the following inside
USER CODE BEGIN 2
:
- Under Private includes in the first USER CODE BEGIN section, add the run interface as an include
run_interface();
#if 0
- Then inside `USER CODE BEGIN 3` after the `}` you want to put an `#endif`
- This ensures that the only tasks that will be started up are the ones you add to your run_main() function
- CubeIDE may exclude newly added folders from the build, to include it right click on the folder, go into Properties > C/C++ Build (on the left bar) > Select Configuration:
[All Configurations]
in the dropdown box, and then untick "Exclude Resource from Build"
- The included etl_profile is set for C++17 and up, change the C/C++ build settings to use the GNU++17 language standard
- Right click the project in the project explorer > Properties > Expand C/C++ Build > Settings > General under MCU G++ Compiler > Language Standard
- Change to GNU++17 (ISO C++17 + gnu extensions)(-std=gnu++17) or up
- Recommended to add the following build flags
-Wno-register
-Wno-volatile
- Right click the project in the project explorer > Properties > Expand C/C++ Build > Settings > Miscellaneous under MCU G++ Compiler