C++ Setup in STM32
1. CubeMX Configuration
There is nothing special to do in CubeMX for C++ setup. You can follow the same steps as in C setup. First we see makefile
then cmake
. Also make a pin GPIO_Output
for LED. For example, in bluepill (STM32F103C8)
, pin PC13
is connected to LED.

Note
You can generate code using toolchain as Makefile
, then later migrate to CMake
, and vice versa.
2. Update Makefile to Compile C++ Code
Note
Add the block to Makefile
which have green border at left.
2.1. Add CXX_SOURCES
after C_SOURCES
:
# C sources
C_SOURCES = \
Core/Src/main.c \
Core/Src/gpio.c \
Core/Src/stm32f4xx_it.c \
Core/Src/stm32f4xx_hal_msp.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \
Core/Src/system_stm32f4xx.c \
Core/Src/sysmem.c \
Core/Src/syscalls.c
# CXX sources
CXX_SOURCES =
# ASM sources
ASM_SOURCES = \
startup_stm32f407xx.s
2.2. Add Compiler for C++:
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
CXX = $(GCC_PATH)/$(PREFIX)g++
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
CXX = $(PREFIX)g++
else
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
2.3. Add CXX_INCLUDE
after C_INCLUDES
:
# C includes
C_INCLUDES = \
-ICore/Inc \
-IDrivers/STM32F4xx_HAL_Driver/Inc \
-IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy \
-IDrivers/CMSIS/Device/ST/STM32F4xx/Include \
-IDrivers/CMSIS/Include
# CXX Includes
CXX_INCLUDES = \
$(C_INCLUDES)
2.4. Add CXXFLAGS:
# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
CXXFLAGS = $(CFLAGS) $(CXX_INCLUDES)
2.5. Add list of objects for CXX:
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMM_SOURCES)))
# list of CXX program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CXX_SOURCES:.cpp=.o)))
vpath %.cpp $(sort $(dir $(CXX_SOURCES)))
2.6. Add to build cpp files:
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR)
$(CXX) -c $(CXXFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@
$(BUILD_DIR):
mkdir $@
Makefile
is ready to compile C++
file. We need to add .cpp
file to CXX_sources
. Verify makefile syntax.
make -j
It should not give any warning or error.
3. Create new cplusplus files to project
Navigate to Core > Inc
, create a new file app.h
and copy the following code.
#ifndef __APP_H
#define __APP_H
#ifdef __cplusplus
extern "C" {
#endif
void setup();
void loop();
#ifdef __cplusplus
}
#endif
#endif // __APP_H
Navigate to Core > Src ``, create a new file ``app.cpp
and copy the following code.
#include "app.h"
#include "stm32f1xx_hal.h"
void setup()
{
// executes once
}
void loop()
{
// executes continuesly
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(100);
}
Open main.c
file and include app.h
.
/* USER CODE BEGIN Includes */
#include "app.h"
/* USER CODE END Includes */
Call setup() and loop() function in main()
.
/* USER CODE BEGIN 2 */
setup();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
loop();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
4. Add app.cpp
to Makefile.
# CXX sources
CXX_SOURCES = \
Core/Src/app.cpp
Compile and flash the code. The LED should blink.
5. Migrate to CMake
Open STM32CubeMX
, go to Project Manager > Project
and select Toolchain/IDE
as CMake
. Generate code. CMakeLists.txt
will be generated in the project folder. You donot need to delete Makefile
. You can use both Makefile
and CMake
.
6. Update CMakeLists.txt
6.1. Set C++ standard:
# Setup compiler settings
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
6.2. Enabe CXX support:
Enabe CXX support by editing the line enable_language(C ASM)
.
enable_language(CXX C ASM)
6.3. Add CXX sources:
# Add sources to executable
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
# Add user sources here
${CMAKE_SOURCE_DIR}/Core/Src/app.cpp
)
Compile and flash the code. The LED should blink.