1. main.c를 복사해서 main.cpp를 만들어 준다.
main.c를 삭제하지 말고 그대로 유지해야 cubeMX 파일의 설정을 변경하더라도 내용을 보존할 수 있다. 즉, Makefile을 이용해서 CPP를 빌드하려고 하며, main.c는 소스코드유지용으로 놔두겠다는 의미이다.
2. Makefile을 아래와 같이 변경한다.
########################################################################################################################## # File automatically-generated by tool: [projectgenerator] version: [3.15.2] date: [Fri Jan 07 11:45:54 KST 2022] ########################################################################################################################## # ------------------------------------------------ # Generic Makefile (based on gcc) # # ChangeLog : # 2017-02-10 - Several enhancements + project update mode # 2015-07-22 - first version # ------------------------------------------------ ###################################### # target ###################################### TARGET = caio ###################################### # building variables ###################################### # debug build? DEBUG = 1 # optimization OPT = -Og ####################################### # paths ####################################### # Build path BUILD_DIR = build ###################################### # source ###################################### # C sources C_SOURCES = \ Core/Src/gpio.c \ Core/Src/freertos.c \ Core/Src/can.c \ Core/Src/spi.c \ Core/Src/usart.c \ Core/Src/stm32f4xx_it.c \ Core/Src/stm32f4xx_hal_msp.c \ Core/Src/stm32f4xx_hal_timebase_tim.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.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_spi.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ Core/Src/system_stm32f4xx.c \ Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ Middlewares/Third_Party/FreeRTOS/Source/list.c \ Middlewares/Third_Party/FreeRTOS/Source/queue.c \ Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ Middlewares/Third_Party/FreeRTOS/Source/timers.c \ Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c \ Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c # ASM sources ASM_SOURCES = \ startup_stm32f417xx.s #jsyoon CPP_SOURCES = \ Core/Src/main.cpp ####################################### # binaries ####################################### PREFIX = arm-none-eabi- # The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) # either it can be added to the PATH environment variable. ifdef GCC_PATH CC = $(GCC_PATH)/$(PREFIX)gcc #jsyoon CPP = $(GCC_PATH)/$(PREFIX)g++ AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp CP = $(GCC_PATH)/$(PREFIX)objcopy SZ = $(GCC_PATH)/$(PREFIX)size else CC = $(PREFIX)gcc #jsyoon CPP = $(PREFIX)g++ AS = $(PREFIX)gcc -x assembler-with-cpp CP = $(PREFIX)objcopy SZ = $(PREFIX)size endif HEX = $(CP) -O ihex BIN = $(CP) -O binary -S ####################################### # CFLAGS ####################################### # cpu CPU = -mcpu=cortex-m4 # fpu FPU = -mfpu=fpv4-sp-d16 # float-abi FLOAT-ABI = -mfloat-abi=hard # mcu MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) # macros for gcc # AS defines AS_DEFS = # C defines C_DEFS = \ -DUSE_HAL_DRIVER \ -DSTM32F417xx # AS includes AS_INCLUDES = \ -ICore\Inc # C includes C_INCLUDES = \ -ICore/Inc \ -IDrivers/STM32F4xx_HAL_Driver/Inc \ -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy \ -IMiddlewares/Third_Party/FreeRTOS/Source/include \ -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS \ -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ -IDrivers/CMSIS/Device/ST/STM32F4xx/Include \ -IDrivers/CMSIS/Include #jsyoon CPP_INCLUDES = \ -ICore/Inc # 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 #jsyoon CPPFLAGS = $(CPP_INCLUDES) -std=c++17 -Wno-register ifeq ($(DEBUG), 1) CFLAGS += -g -gdwarf-2 endif # Generate dependency information CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" ####################################### # LDFLAGS ####################################### # link script LDSCRIPT = STM32F417VETx_FLASH.ld # libraries LIBS = -lc -lm -lnosys LIBDIR = #jsyoon #LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections LDFLAGS = $(MCU) -specs=nosys.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections # default action: build all all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin ####################################### # build the application ####################################### # 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))) #jsyoon OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CPP_SOURCES:.cpp=.o))) vpath %.cpp $(sort $(dir $(CPP_SOURCES))) $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ #jsyoon $(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR) $(CPP) -c $(CFLAGS) $(CPPFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cpp=.lst)) $< -o $@ $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) $(AS) -c $(CFLAGS) $< -o $@ $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile $(CPP) $(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 $@ ####################################### # clean up ####################################### clean: -rm -fR $(BUILD_DIR) ####################################### # dependencies ####################################### -include $(wildcard $(BUILD_DIR)/*.d) # *** EOF ***
참조. 원래의 Makefile 내용
########################################################################################################################## # File automatically-generated by tool: [projectgenerator] version: [3.15.2] date: [Thu Jan 06 17:14:18 KST 2022] ########################################################################################################################## # ------------------------------------------------ # Generic Makefile (based on gcc) # # ChangeLog : # 2017-02-10 - Several enhancements + project update mode # 2015-07-22 - first version # ------------------------------------------------ ###################################### # target ###################################### TARGET = caio ###################################### # building variables ###################################### # debug build? DEBUG = 1 # optimization OPT = -Og ####################################### # paths ####################################### # Build path BUILD_DIR = build ###################################### # source ###################################### # C sources C_SOURCES = \ Core/Src/main.c \ Core/Src/gpio.c \ Core/Src/freertos.c \ Core/Src/can.c \ Core/Src/spi.c \ Core/Src/usart.c \ Core/Src/stm32f4xx_it.c \ Core/Src/stm32f4xx_hal_msp.c \ Core/Src/stm32f4xx_hal_timebase_tim.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.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_spi.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ Core/Src/system_stm32f4xx.c \ Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ Middlewares/Third_Party/FreeRTOS/Source/list.c \ Middlewares/Third_Party/FreeRTOS/Source/queue.c \ Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ Middlewares/Third_Party/FreeRTOS/Source/timers.c \ Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c \ Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c # ASM sources ASM_SOURCES = \ startup_stm32f417xx.s ####################################### # binaries ####################################### PREFIX = arm-none-eabi- # The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) # either it can be added to the PATH environment variable. 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 else CC = $(PREFIX)gcc AS = $(PREFIX)gcc -x assembler-with-cpp CP = $(PREFIX)objcopy SZ = $(PREFIX)size endif HEX = $(CP) -O ihex BIN = $(CP) -O binary -S ####################################### # CFLAGS ####################################### # cpu CPU = -mcpu=cortex-m4 # fpu FPU = -mfpu=fpv4-sp-d16 # float-abi FLOAT-ABI = -mfloat-abi=hard # mcu MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) # macros for gcc # AS defines AS_DEFS = # C defines C_DEFS = \ -DUSE_HAL_DRIVER \ -DSTM32F417xx # AS includes AS_INCLUDES = \ -ICore\Inc # C includes C_INCLUDES = \ -ICore/Inc \ -IDrivers/STM32F4xx_HAL_Driver/Inc \ -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy \ -IMiddlewares/Third_Party/FreeRTOS/Source/include \ -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS \ -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ -IDrivers/CMSIS/Device/ST/STM32F4xx/Include \ -IDrivers/CMSIS/Include # 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)" ####################################### # LDFLAGS ####################################### # link script LDSCRIPT = STM32F417VETx_FLASH.ld # libraries LIBS = -lc -lm -lnosys LIBDIR = LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections # default action: build all all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin ####################################### # build the application ####################################### # 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))) $(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)/$(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 $@ ####################################### # clean up ####################################### clean: -rm -fR $(BUILD_DIR) ####################################### # dependencies ####################################### -include $(wildcard $(BUILD_DIR)/*.d) # *** EOF ***
3. CubeMX 설정 변경에 대응하기
cubeMX에서 설정을 변경하면 main.c가 다시 만들어진다. main.c와 main.cpp는 같은 내용이므로 OK. 복사해서 main.cpp를 만들어 주면된다. 단, Makefile에는 main.c를 컴파일하라는 옵션이 추가되므로 해당라인을 삭제해준다.
그리고, main.cpp에서 불려지는 함수는 MX_FREERTOS_Init(void);가 있는데 이것을 extern “C”로 정의해 주어야 한다.
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
// void MX_FREERTOS_Init(void); <<<<<<< 코멘트처리
/* USER CODE BEGIN PFP */
#ifdef __cplusplus
extern "C" {
#endif
void MX_FREERTOS_Init(void);
#ifdef __cplusplus
}
#endif
/* USER CODE END PFP */
4. make 단계
ifdef __cpusplus를 정의해 놓았기 때문에, 디렉토리에 main.c가 컴파일되더라도 에러메시지를 내보내지 않게된다. CFLAG 옵션에서 작업디렉토리의 모든 .c 파일을 디펜던시 체크하는 옵션이 켜 있어서 그렇타는데… 일단은 코드의 보존이 먼저이기 때문에 윗 조건을 걸어 두었다.