| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 |
- 라즈베리파이
- robot
- WPF
- AVR
- esp32
- vscode
- Visual Studio Code
- Arduino
- Visual Studio
- C++
- yocto project
- GPIO
- atmel
- nucleo
- Debug
- 리눅스
- Linux
- QEMU
- bare metal
- UART
- yocto
- 문자 장치
- QT
- raspberrypi
- 아두이노
- STM32
- Raspberry
- 디버깅
- buildroot
- c#
- Today
- Total
임베디드를 좋아하는 조금 특이한 개발자?
[STM32] STM32 CubeMX으로 C++ 개발 환경 구축 본문
- 개발 환경
개발 보드 : NUCLEO-F103RB
개발 프로그램
- STM32 CubeMX : 6.18.1
- STM32CubeIDE for Visual Studio Code : 3.10.0
- 소스 코드
https://github.com/MainForm/STM32_cpp_template
GitHub - MainForm/STM32_cpp_template
Contribute to MainForm/STM32_cpp_template development by creating an account on GitHub.
github.com
1. 서론
임베디드 환경에서 C언어로 개발하는 것은 당연하고 신뢰도를 위해서라도 C언어를 사용하는 것은 타당하다고 생각합니다. 학습을 하는 입장에서 C로 개발하기에는 기본적인 자료구조 조차 없어 방대한 코드를 작성하는 것이 힘들 때가 있습니다. 그래서 C++로 개발하여 STL로 다양한 자료구조 및 알고리즘을 사용하면 좋겠다라고 생각했던 적이 많았습니다. 하지만 STM32 CubeMX에서는 C언어로만 프로젝트를 생성할 수 밖에 없으며, main.c를 cpp로 변경한다면 매변 main.c가 생성되는 문제점이 발생하게 됩니다.
그래서 이번 포스트에서는 STM32 CubeMX로 프로젝트를 재생성하더라도 충돌이나 프로젝트에 문제가 발생하지 않도록 STM32 CubeMX로 생성되는 파일(Generated Code)과 Application 파일를 분리하고 C++로 개발 할 수 있는 환경을 구축하는 방법에 대해서 소개하겠습니다.
2. STM32 CubeMX 프로젝트 생성





여기서 중요한 것은 main 함수를 자동 생성하지 않도록 하는 것입니다. 그 이유는 직접 main.cpp 파일을 생성하여 해당 파일 내에서 직접 main 함수를 정의할 것이기 때문입니다. 그러므로 main 함수가 충돌 나지 않도록 자동 생성 설정을 해제합니다.
3. VisualStudio Code 개발 환경 구축
https://littlebitodd-developer.tistory.com/91
[STM32] VisualStudio Code에서 개발 환경 구축
1. 서론 STM32 MCU를 개발 할 때 대부분은 STM32CubeIDE나 IAR EWARM를 사용할 것 입니다. 하지만 저는 Visual Studio Code에서 자주 사용하기 떄문에 다른 개발 환경에서 개발하는 것이 힘들 때가 있습니다. 다
littlebitodd-developer.tistory.com
4. 프로젝트 구조 변경
4.1. main.cpp 파일 생성

먼저 C++ 코드를 작성할 main.cpp 파일을 생성합니다.
4.2. CMake 설정
여기서 프로젝트 최상위에 있는 "CMakeLists.txt"파일을 수정합니다.
https://github.com/MainForm/STM32_cpp_template/blob/main/CMakeLists.txt

CMake에서 C++ 언어를 추가하고 main.cpp 파일을 같이 빌드할 수 있도록 추가합니다.
4.3. main.cpp 코드 작성

https://github.com/MainForm/STM32_cpp_template/blob/main/app/Src/main.cpp
#include "main.h"
#include "gpio.h"
#include "usart.h"
// Defined in Core/Src/main.c
// extern "C" disables C++ name mangling so the C++ linker can find the C function.
extern "C"
void SystemClock_Config(void);
int main(void){
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
while(1){
HAL_UART_Transmit(&huart2, (uint8_t*)"Hello World!\r\n", 14, HAL_MAX_DELAY);
HAL_Delay(1000);
}
}

5. 주의 사항
5.1. C++의 Name Mangling 문제
STM32 CubeMX로 생성된 코드는 C언어이며, Application의 코드는 C++입니다. C++의 하위 호환이 C라고 생각할 수 있습니다. 하지만 2언어는 서로 다른 언어입니다. 단순히 C++에서 C의 문법을 채용한 언어입니다. 여기서 문제가 발생합니다. C++은 함수 오버로딩(Function Overloading)를 지원하기 위해서 함수 매개변수에 따라 함수의 심볼이 자동으로 변경됩니다.

실제 코드로 실습하면 다음과 같습니다.


그러므로 만약 C++ 에서 C의 함수를 extern 하기 위해서는 Name Mangling 으로 자동으로 함수 심볼이 변경되는 것을 방지해야합니다.

그러므로 다른 C언어의 함수를 extern으로 참조또는 C언어 함수의 선언으로 함수를 정의하는 경우 extern "C"를 사용하여함수의 심폴을 같게 해야합니다.
- C++ extern 예약어 문서
https://en.cppreference.com/cpp/language/language_linkage
- 개발 언어 Name mangling 문서
https://en.wikipedia.org/wiki/Name_mangling
5.2. 되도록이면 Generated Code 수정 금지

저희는 Generated Code와 Application를 분리하였기 때문에 Generated Code를 되도록 수정 하는 것을 피해야합니다. 만약 Generated Code를 잘못 수정할시 CubeMX를 통해 코드를 재생성한다면 해당 코드가 사라질 수가 있기 때문입니다.
6. 결론
C++언어는 객체 지향 문법을 가진 언어로써 최신 디자인 패턴을 적용하여 개발 유지 보수성이 올라간다는 장점이 있습니다. 하지만 임베디드는 신뢰성이 중요하면 대부분의 기능이 절차적으로 이루어지기에 C언어가 임베디드 개발에 적절한 언어입니다.
그리고 C++은 생성자, 소멸자, 연산자 오버로딩 등으로 개발자가 의도하지 않은 함수의 호출이 잦아 질 수 있다는 점이 있으며, 특히 예외(Exception)의 경우 임베디드에서 성능이 크게 저하되므로 사용하지 않습니다. 그래서 C++에서는 대부분의 문법을 금지한채로 한정된 기능만 제공하는 Class를 사용해야합니다.
그렇더라도 학습 목적의 저희는 문법적인 이득보다는 객체 구조(Queue, Stack 등)와 알고리즘을 사용할 수 있습니다. 하지만 또 명심해야하는 것은 Vector 내에서 동적 메모리를 사용하므로 메모리 관리를 신경써야 합니다.
'Embedded > STM32' 카테고리의 다른 글
| [STM32] git으로 협업하기 위한 FreeRTOS 기반 프로젝트 구조 (0) | 2026.09.25 |
|---|---|
| [STM32] VisualStudio Code에서 개발 환경 구축 (0) | 2026.03.07 |
| [STM32] PWM를 통한 SG-90 서보 모터 제어 (1) | 2025.04.10 |
| [STM32] 외부 인터럽트(EXTI : EXTernal Interrupt)를 통해 버튼의 입력 감지 (0) | 2025.04.06 |
| [STM32] USART / UART를 통한 데이터 송수신 (0) | 2025.04.06 |
