한동안 high level에서 놀다가 간만에 STM32 펌웨어 작업을 하게 됐다.
복잡한 펌웨어도 아니고 그 high level 코드가 돌아가는 리눅스 보드의 전원을 제어하는 16KB 플래시를 가진 MCU에 올라가는 펌웨어다.
사실, 이 MCU와 상관없이 리눅스 보드 전원 제어용 로드 스위치(active low)에 pull-down 저항을 달아서 전원을 일단 상시 공급하게 설계를 해놔서 당장 안해도 될 작업이었는데, 로드 스위치를 반대(active high) 타입으로 주문해서 조립했다. 아... 진짜...
급한대로 간단하게 펌웨어 만들어서 로드 스위치 입력 신호를 1로 줘야 했다.
오래간만에 STM32CubeIDE를 설치하고 새 프로젝트를 생성해보니... 어라? CubeMX가 없다. 아무리 찾아봐도.
알고보니 STM32CubeIDE 2.0 부터 CubeMX가 빠지게 됐단다.
이제부터 STM32CubeMX는 따로 설치하고 CubeIDE에서 작업하고 싶으면 CubeMX에서 CubeIDE용 프로젝트로 생성한 후 CubeIDE에서 import 하면 된다고...
그래서 윈도에 CubeMX를 설치했다. 다 설정하고 Code Generate 누르기 전에 생각해보니, CubeMX에서는 STM32CubeIDE나 EWARM용 프로젝트를 만들어주기도 하지만, Makefile, CMake 프로젝트도 만들어준다. 음... 안그래도 AI로 코딩하는 시대에 잘 됐다 싶었다.
문제는 나의 모든 개발용 툴들이 WSL2에 있다는 거다. 음. 윈도에서 만든 후 WSL2로 가져가도 큰 문제가 안될 것 같긴 한데... 이미 윈도용 디스크 압박도 심해서 부담스러웠던 터라 CubeMX를 지우고 WSL2에서 설치해보기로 결정.
STM32CubeMX를 다운받아 WSL2에서 압축 풀고 인스톨 실행하면 의외로 CLI로 진행이 된다.
설마 본 프로그램도 CLI로만 도는건가 해서 설치 후 실행해봤더니 역시나 X11 디스플레이를 못잡는다.
$ ./STM32CubeMX
Check exe path on linux
FullExe path1 is: /home/jsjeong/STM32CubeMX/STM32CubeMX
Exe path is: /home/jsjeong/STM32CubeMX
Search java from relative path ----
Checking java in /home/jsjeong/STM32CubeMX/./jre/bin/java
current working dir : /home/jsjeong/STM32CubeMX
av[0] ./STM32CubeMX
chdir to :/home/jsjeong/STM32CubeMX/.
New current working dir /home/jsjeong/STM32CubeMX
Full command: /home/jsjeong/STM32CubeMX/./jre/bin/java
-args[0] java
-args[1] -jar
-args[2] STM32CubeMX
log4j user configuration file not found: /home/jsjeong/.stm32cubemx/log4j2.xml
Configure log4j with default settings from jar:file:/home/jsjeong/STM32CubeMX/STM32CubeMX!/log4j/log4j2.stm32cubemx.xml
2026-05-14 08:07:38,683 [INFO] MicroXplorer:98 - [MX] MX Start == 49483568554686
2026-05-14 08:07:38,687 [INFO] MicroXplorer:653 - Detected Java Version = 21.0.9
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set,
or no headful library support was found,
but this program performed an operation which requires it.
at java.desktop/java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:164)
at java.desktop/java.awt.Window.<init>(Window.java:553)
at java.desktop/java.awt.Frame.<init>(Frame.java:428)
at java.desktop/java.awt.Frame.<init>(Frame.java:393)
at java.desktop/javax.swing.SwingUtilities$SharedOwnerFrame.<init>(SwingUtilities.java:1925)
at java.desktop/javax.swing.SwingUtilities.getSharedOwnerFrame(SwingUtilities.java:2001)
at java.desktop/javax.swing.JWindow.<init>(JWindow.java:183)
at java.desktop/javax.swing.JWindow.<init>(JWindow.java:135)
at com.st.microxplorer.stobjects.STSplash.<init>(STSplash.java:34)
at com.st.microxplorer.maingui.MicroXplorer.main(MicroXplorer.java:189)
at com.st.microxplorer.maingui.STM32CubeMX.main(STM32CubeMX.java:59)
생각보다 간단하게 해결
$ DISPLAY=:0 ./STM32CubeMX
깔끔하게 GUI로 실행된다.
이어서 여러가지 설정을 해준 다음, Makefile 프로젝트로 code generate 후, 프로젝트 디렉토리 가서 make 하니 성공.
아... 드디어 무거운 STM32CubeIDE에서 해방인가...
코딩을 위해 OpenCode를 실행하면서 한가지 걱정되는 점이 있었다. STM32CubeMX로 프로젝트를 생성하면 나름 코딩 룰이 생긴다. USER CODE BEGIN ~ USER CODE END 사이에만 사용자 코드를 넣어야 한다. 그 외에 코드를 넣으면 CubeMX로 재설정 하는 순간 그 블록 밖의 코드는 전부 사라진다. 과연 OpenCode가 이 룰을 감지할 수 있을까?
/init 으로 초기 프로젝트 파악 및 AGENTS.md 파일 생성하게 했더니...
AGENTS.md 생성 완료. 요약:
- 대상: STM32L011F4Ux (Cortex-M0+), 16KB Flash / 2KB RAM
- 빌드: make / make clean, arm-none-eabi-gcc 10.3.1 필요
- 핵심 규칙: USER CODE BEGIN/END 블록 밖은 수정 금지 (CubeMX 재생성 구역)
- 하드웨어 구성: USART2(115200), LPTIM1(LSI 37kHz), GPIO(PA4,PA6 출력 / PA5 입력 / PA1,PB9 EXTI), HSI 16MHz
- 플래싱/디버그: 시스템에 도구 미설치, st-flash/openocd 외부 사용 필요
생각보다 잘 감지한다.
자 이제 작업 시작!
