콘텐츠로 이동

Troubleshooting — FAQ & 문제 해결

XM10 개발 중 자주 발생하는 문제와 해결 방법을 정리한 문서입니다.


빌드 오류

경로 길이 문제 (Windows MAX_PATH)

증상: 빌드 시 No such file or directory 또는 file name too long 오류 발생

원인: Windows의 기본 경로 길이 제한(260자)을 초과하는 경우 발생합니다. 프로젝트가 깊은 경로에 위치하거나, OneDrive 동기화 폴더 안에 있을 때 빌드 출력 경로가 260자를 초과할 수 있습니다.

해결 방법:

방법 1: 짧은 경로에 SDK 압축 해제 (권장)

본 SDK 는 GitHub Releases 의 ZIP 으로 받습니다. 압축 해제 위치를 드라이브 루트에 가깝게 잡으면 경로 길이 문제를 피할 수 있습니다.

# Releases 페이지에서 본인 Rev ZIP 다운로드 후
Expand-Archive -Path "$HOME\Downloads\Rev2.0.zip" -DestinationPath C:\XM_SDK\ -Force
구분 경로 예시 빌드 최대 경로
권장 C:\XM_SDK\ ~130자
일반 C:\Users\Name\Documents\GitHub\Extension_Module\ ~190자
위험 C:\Users\...\OneDrive - Company\...\Extension_Module\ 260자 초과 가능

방법 2: Windows Long Path 지원 활성화 (근본 해결)

Windows 10 (1607+) / Windows 11에서 260자 제한을 해제할 수 있습니다.

PowerShell (관리자 권한):

New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force

또는 그룹 정책: 컴퓨터 구성 > 관리 템플릿 > 시스템 > 파일 시스템 > Win32 긴 경로 사용 → 사용

설정 후 PC 재시작이 필요합니다. 이 설정은 1회만 하면 되며 Git, CMake, GCC 등 모든 도구에 적용됩니다.


한글/공백 경로 오류

증상: 빌드 시 No such file or directory 또는 인코딩 관련 오류

원인: 프로젝트 경로 또는 STM32CubeIDE 설치 경로에 한글, 공백, 특수문자가 포함된 경우

해결: * 프로젝트를 영문 경로로 이동 (예: C:\XM_SDK\) * STM32CubeIDE를 영문 경로에 설치 (예: C:\dev\STM32CubeIDE) * Windows 사용자 이름이 한글인 경우: 프로젝트를 사용자 폴더가 아닌 드라이브 루트에 배치


nano.specs 중복 오류

증상: fatal error: nano.specs: attempt to rename spec 'link' to already defined spec 'nano_link'

원인: CMake 빌드 설정에서 --specs=nano.specs 플래그가 중복 적용

해결: CMakeLists.txt에서 CMAKE_C_FLAGS와 CMAKE_C_FLAGS_DEBUG/RELEASE가 동일한 플래그를 중복 포함하지 않는지 확인하세요. CMAKE_C_FLAGS에 공통 플래그를 넣고, DEBUG/RELEASE에는 빌드 타입별 플래그만 설정합니다.


redefined 경고 (Rev 1.1 SDK, CMake 빌드)

증상: warning: "AGRB_IOIF_FDCAN_ENABLE" redefined 처럼 ..._ENABLE 이름의 값이 다시 정의되었다는 경고 (Rev 1.1 SDK 를 CMake 로 빌드할 때만 나타납니다 — STM32CubeIDE 빌드나 Rev 2.0 SDK 에서는 나타나지 않습니다)

원인: SDK 안에서 같은 설정 값이 두 군데에 정의되어 있어서 나오는 경고입니다.

해결: 동작에는 영향이 없으니 무시해도 됩니다. STM32CubeIDE 로 빌드하면 나타나지 않습니다.


implicit declaration of function 오류 (Rev 2.0 SDK)

증상: 빌드가 error: implicit declaration of function '함수 이름' 으로 멈춤 (Rev 2.0 SDK, v2.9.0 이상)

원인: v2.9.0 부터 Rev 2.0 SDK 는 헤더에 선언이 보이지 않는 함수를 부르면 경고가 아니라 오류로 처리합니다. 함수 이름의 오타, 빠진 #include, 헤더에서 없어진 선언이 원인입니다. Rev 1.1 SDK 는 이전과 같습니다.

해결: 1. 그 함수를 선언한 헤더를 #include 합니다. SDK 함수는 보통 #include "xm_api.h" 하나면 됩니다. XM_LOG_* 매크로를 쓰는 .c 파일은 xm_api_logging_raw.h 도 #include 합니다. 2. 함수 이름이 맞는지 API 레퍼런스에서 확인합니다. 이전 버전에서 쓰던 이름이면 v2.9.0 릴리스 노트를 보세요. 3. 직접 만든 함수라면 부르기 전에 원형(prototype)을 선언합니다.


보드 리비전 / SDK ZIP 불일치

가운데·우측 버튼이 안 눌리거나, 누르지 않은 버튼이 항상 눌린 것으로 잡힘

증상: - XM_GetButtonEvent(XM_BTN_2) 가 가운데 버튼을 눌러도 반응 없음 - 한 버튼만 동작하고 나머지는 다른 ID 로 잡히거나 stuck (XM_PRESSED 가 고정) - XM_GetButtonState 와 HAL HAL_GPIO_ReadPin 비교 결과 매핑이 한 칸씩 어긋남

원인: Rev 1.1 보드와 Rev 2.0 보드는 내장 버튼 3 개의 MCU 핀이 다릅니다 — Rev 2.0 으로 가면서 외장 SRAM (PSRAM) 자리를 만들기 위해 버튼 핀이 한 칸 시프트되었습니다.

BTN 1 (좌) BTN 2 (중) BTN 3 (우)
Rev 1.1 PC10 PC11 PC12
Rev 2.0 PC11 PC12 PC13

API 이름 (XM_BTN_1/2/3) 은 양쪽 Rev 에서 좌·중·우 의미를 그대로 유지하지만, 그 안에서 어느 MCU 핀을 읽을지는 SDK 가 본인 Rev 의 main.h 핀 정의를 따라갑니다. 따라서 보드 Rev 와 다른 ZIP 으로 빌드하면 빌드는 통과해도 라이브러리가 잘못된 핀을 읽어 매핑이 어긋납니다.

해결: 1. 보드 라벨에서 Rev 1.1 또는 Rev 2.0 확인. 라벨이 모호하면 외관상 RJ45 Ethernet 포트의 유무로 구별 (Rev 2.0 만 있음). 자세한 비교는 docs/hardware/README.md - 보드 리비전 비교. 2. Releases 에서 본인 Rev 와 같은 ZIP 을 받아 STM32CubeIDE 에 다시 import. 3. 재빌드·플래시 후 Ex.01 (Button & LED Basic) 의 세 버튼 모두 정상 동작 확인.

진단 코드 (선택사항): 본인 보드의 실제 핀을 직접 확인하고 싶다면:

// Run_Loop 안에서 PC10~PC13 을 동시에 읽어 비교
uint8_t pc10 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_10);
uint8_t pc11 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_11);
uint8_t pc12 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_12);
uint8_t pc13 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13);
// 좌·중·우 버튼을 한 번씩 눌러 어느 핀이 떨어지는지 확인
// → Rev 1.1 보드면 PC10/11/12, Rev 2.0 보드면 PC11/12/13 이 떨어짐

⚠️ HAL 로 직접 읽는 코드는 진단용입니다. 정상 동작이 확인되면 XM_GetButtonEvent / XM_GetButtonState 로 돌아오세요 — 디바운싱과 클릭/롱프레스 인식은 라이브러리가 처리합니다.


Ex.36 (OnDevice Kinesthetic Learning) — Rev 1.1 빌드 실패

증상: Rev 1.1 SDK 로 Ex.36 을 빌드하면 link 단계에서 다음 에러가 출력됨(지금 Rev 1.1 SDK 에는 Ex.36 이 들어 있지 않습니다 — 예전 SDK 나 다른 곳에서 가져와 빌드한 경우).

control_task.c:(.text.Active_Entry+0x2a): undefined reference to `XM_UserNV_Read'
control_task.c:(.text.Active_Loop+0x284): undefined reference to `XM_UserNV_Erase'
control_task.c:(.text.Active_Loop+0x292): undefined reference to `XM_UserNV_Write'
collect2.exe: error: ld returned 1 exit status

원인: Ex.36 은 학습된 NN 가중치를 전원 OFF/ON 사이에 보존하기 위해 Internal Flash UserNV API (XM_UserNV_Read/Write/Erase) 를 사용합니다. 이 API 는 Rev 2.0 SDK 의 libXM_Lib.a 에만 포함되어 있고 Rev 1.1 lib 에는 없습니다.

해결: - 본인 보드가 Rev 2.0 → Rev 2.0 SDK ZIP 으로 다시 import 후 빌드. - 본인 보드가 Rev 1.1 → Ex.36 은 진행 불가. Ex.35 (MultiLayer_Transparent_Control) 까지 학습한 뒤, Rev 2.0 보드를 확보하면 Ex.36 로 넘어가세요. Ex.36 의 NN + LQR 부분만 보고 싶다면 BTN1 long-press (Flash 저장) 동작을 제거하고 RAM 상에서만 학습/재생하도록 임시 수정해 학습용으로 활용 가능.

본인 보드 Rev 가 헷갈리면 라벨 또는 docs/hardware/README.md - 보드 리비전 비교 의 RJ45 / PSRAM / 버튼 핀 매핑 표로 구분.


USB 연결 문제

USB-CDC가 PC에서 인식되지 않음

체크리스트: 1. USB-C 케이블이 데이터 전송용인지 확인 (충전 전용 케이블은 불가) 2. Windows 장치 관리자에서 Ports (COM & LPT) 아래에 STMicroelectronics Virtual COM Port 확인 3. 드라이버가 없는 경우: STM32 Virtual COM Port Driver 설치 4. XM10 펌웨어에서 USB CDC 초기화가 정상적으로 완료되었는지 확인 5. (Rev 2.0) USB 메모리가 꽂혀 있으면 PC 와 연결되지 않습니다 — 아래 참고

USB 메모리가 꽂혀 있으면 PC 와 연결되지 않음 (Rev 2.0)

🟢 Rev 2.0 전용 — Rev 1.1 에는 USB 메모리 저장이 없습니다.

XM10 의 USB-C 포트는 하나입니다. USB 메모리를 꽂아 두는 동안에는 PC 와 USB 로 연결할 수 없습니다. PhAI Studio · xm10 도구 · USB 로 하는 펌웨어 업로드를 쓸 수 없습니다.

해결: USB 메모리를 뽑고 PC 를 연결하세요. (보드 확인 전)

USB 메모리 저장이 시작되지 않음 (Rev 2.0)

🟢 Rev 2.0 전용 — 사용법은 USB 메모리 저장 과 USB 메모리에 저장하기 를 보세요.

체크리스트: 1. USB 메모리가 FAT32 인지 확인 (exFAT · NTFS 는 인식하지 않습니다). 할당 단위는 32 KB 를 권장합니다. 포맷하면 안의 파일이 모두 지워지니 필요한 파일은 먼저 옮기세요. 2. USB 메모리의 빈 공간이 파일을 나누는 크기(기본 10 MB)보다 큰지 확인 3. XM_IsUsbLogReady() 가 true 인지 확인 (Ex.10 · Ex.34 는 LED 1 이 켜집니다) 4. XM_StartUsbDataLog() 가 false 를 돌려주면 XM_GetUsbLogLastStartError() 로 이유 확인 — 시작 실패 이유 5. 시작은 됐는데 곧 끝나면(Ex.10 · Ex.34 는 LED 3 이 켜집니다) XM_GetUsbLogLastStartError() 를 읽어 보세요. 파일을 여는 중에 실패했거나(빈 공간 부족 · 같은 이름의 폴더가 다른 설정), 저장 중에 USB 메모리가 빠졌거나 내부 버퍼가 넘친 경우 등이 있습니다. 6. 폴더 이름이 날짜가 아니거나 이전 저장과 같다면 시계를 맞추지 않아서일 수 있습니다. XM_RTC_SetDateTime() 으로 맞추거나 세션 이름을 직접 정하세요.

디코더 판정이 RE-COLLECT 로 나옴 (Rev 2.0)

🟢 Rev 2.0 전용 — 판정 읽는 법은 USB 메모리에 저장하기 에 있습니다.

RE-COLLECT 는 표본이 많이 빠졌거나 공백이 길어서 다시 저장하기를 권한다는 뜻입니다.

해결 순서: 1. USB 메모리를 FAT32(할당 단위 32 KB)로 전체 포맷한 뒤 다시 저장 2. 다른 USB 메모리로 바꿔 보기 3. 저장 주기를 낮추거나 구조체를 줄이기 4. 계속되면 Angel Robotics(엔젤로보틱스) CS팀에 문의


CAN-FD 통신 문제

KIT H10과 통신이 안 됨

체크리스트: 1. XM10 ↔ KIT H10 케이블이 단단히 연결되었는지 확인 2. KIT H10의 전원이 켜져 있는지 확인 (24V 전원 공급) 3. 커넥터 핀맵 확인: CAN HIGH(5번), CAN LOW(6번)이 올바르게 연결되었는지 검증 4. CAN-FD 보레이트 설정이 일치하는지 확인

센서 허브 모듈 연동 오류

체크리스트: 1. 센서 허브 모듈의 전원과 CAN-FD 케이블이 제대로 연결되었는지 확인 2. 센서 허브가 XM10 에 자동으로 인식(연결)되는지 확인 3. 센서 허브 모듈의 펌웨어 버전이 XM10 SDK와 호환되는지 확인

IMU Hub·EMG Hub 는 내부에서 개발 중인 모듈입니다. 사용하려면 https://huphailab.com/contact 로 문의해 주세요.


디버깅 관련

체크리스트: 1. ST-Link 디버거의 USB 연결 상태 확인 2. SWD 4핀 케이블의 핀 배치가 올바른지 확인 (SWDIO, SWCLK, GND, 3.3V) 3. STM32CubeIDE의 Debug Configuration에서 ST-Link가 감지되는지 확인 4. ST-Link Firmware를 최신 버전으로 업데이트 (Help > ST-Link Upgrade)

디버깅 시 변수 값이 Optimized Out

원인: Release 빌드 설정(-O2)에서 컴파일러 최적화로 변수가 제거됨

해결: Debug 빌드 설정(-Og -g3)으로 빌드하세요. Project > Properties > C/C++ Build > Settings > Optimization 에서 확인할 수 있습니다.

디버그 시작 시 main() 에서 멈춤 / Break at address "0x800xxxx" with no debug information 팝업

정상 동작입니다 — 버그가 아닙니다. XM10 은 부트로더(AGR_BOOT)와 앱 펌웨어가 하나의 칩에 두 개의 독립 이미지로 올라가는 구조라, 디버거에서 다음 두 가지가 보일 수 있습니다.

  1. Thread #1 suspended: breakpoint main() 로 멈춤 — STM32CubeIDE 기본 설정 Set breakpoint at: main 때문입니다(모든 CubeIDE 프로젝트 공통). Resume(F8) 를 누르면 실행됩니다. 매번 멈추는 게 싫으면 Debug Configuration > Startup 탭에서 Set breakpoint at: main 체크를 해제하세요.
  2. Break at address "0x0800xxxx" with no debug information available, or outside of program code — 0x0800xxxx(예: 0x0800bf14)는 0x08040000(앱 시작) 아래 = 부트로더 영역입니다. 부트로더는 앱과 별개 바이너리라 앱 프로젝트에 디버그 심볼이 없으므로, 디버거가 "심볼 없음"을 정확히 알리는 것뿐입니다. Resume(F8) 로 진행하면 됩니다.

참고: 디버그 중 리셋(Restart 버튼의 Software system reset / Hardware reset)을 누르면 CPU 가 실제 부트로더부터 다시 실행하므로 위 2번이 더 자주 보일 수 있습니다. 이게 거슬리면 Debug Configuration > Startup > Reset Behaviour 를 Core reset 또는 None 으로 바꿔보세요. (벡터 테이블 미설정으로 signal handler 에 빠지는 것과는 다른, 정상 정지입니다 — 부트로더 디버그 설정 참고.)


자주 마주치는 함정

코드 작성 패턴

sprintf("%.2f", val) 결과가 정수처럼 출력됨

원인: newlib-nano (기본 ARM 라이브러리) 가 float 형식 미지원

해결: STM32CubeIDE → Project > Properties > C/C++ Build > Settings > MCU Settings → "Use float with printf" 체크.

static 누락으로 변수가 매 호출 0 으로 초기화

증상: 토글 동작이 안 되거나, 타이머가 매번 reset

원인: 함수 내부 변수는 매 호출 스택에 새로 생성. static 키워드로 보존 필요.

// ❌ 잘못된 예
static void Run_Loop(void) {
    bool toggle = false;          // 매 호출 false 로 reset
    if (clicked) toggle = !toggle;  // 절대 true 가 안 됨
}

// ✅ 올바른 예
static void Run_Loop(void) {
    static bool toggle = false;    // 다음 호출까지 유지
    if (clicked) toggle = !toggle;
}

XM_TSM_Run() 누락으로 상태 콜백 미실행

증상: Add_State 등록했는데 on_loop 함수가 호출 안 됨

해결: Control_Loop() 안에서 반드시 XM_TSM_Run(handle); 호출.

Active Low vs Active High 혼동

증상: 외부 스위치 누름인데 LED 가 반대 동작

규칙: - 풀업 (INPUT_PULLUP) + 스위치 한쪽 GND → 눌림 = XM_LOW (Active Low) - 풀다운 (INPUT_PULLDOWN) + 스위치 한쪽 3.3V → 눌림 = XM_HIGH (Active High)

본 SDK 의 내장 버튼 (XM_GetButtonState) 은 추상화되어 항상 XM_PRESSED.

Edge Detection 누락

증상: 버튼 한 번 눌렀는데 토글이 여러 번 발생

해결: 직전 상태 (s_btn_prev) 와 현재 상태 비교로 "방금 막 눌린 순간" 만 감지.

bool btn_now = (XM_DigitalRead(BTN) == XM_LOW);
bool pressed = (btn_now && !s_btn_prev);  // Leading edge
s_btn_prev = btn_now;
if (pressed) { /* 1회만 실행 */ }

또는 XM_GetButtonEvent() 의 read-clear 동작 활용 (Ex.02 참조).

USB / 통신 함정

USB-CDC 텍스트 메시지가 터미널에 안 보임

XM_SendUsbDebugMessage 로 보낸 텍스트는 일반 시리얼 터미널에서 읽는 용도입니다.

원인 1: 다른 PC 프로그램이 동일 COM 포트 점유 (PhAI Studio · xm10 도구 · 다른 터미널 — PC 프로그램은 한 번에 하나만 연결하세요)

원인 2: USB-C 케이블이 데이터 전송 불가 (충전 전용)

원인 3: Windows 장치 관리자에서 STMicroelectronics Virtual COM Port 미인식

원인 4 (Rev 2.0): USB 메모리가 꽂혀 있음 — 꽂혀 있는 동안에는 PC 와 USB 로 연결되지 않습니다 (설명)

해결 순서: 1. 모든 시리얼 클라이언트 종료 → 하나만 단독 실행 2. 데이터 전송 가능 USB-C 케이블 (가능하면 PC 후면 USB-A 직결, 허브 X) 3. STM32 VCP 드라이버 설치 4. (Rev 2.0) USB 메모리가 꽂혀 있으면 뽑고 PC 를 연결합니다 (설명). (보드 확인 전)

KIT H10 / 로봇 제어 함정

XM.status.h10.* 가 모두 0

forwardVelocity, footContact 등 보행 분석 데이터가 항상 0

원인: Body Data 전제조건 미충족 — XM_SendUserBodyData() 미호출

해결: examples/README.md — Body Data 안내 참조.

SetAssistTorque 호출했는데 H10 안 움직임

  • XM_SetControlMode(XM_CTRL_CONTROL) 누락 → Active 진입 시 1회 호출
  • 안전 스위치 트리거 상태 → ERROR 상태 점검
  • H10 본체 모터 활성화 안 됨 → 본체 LED / 토크 큐 확인

환경 / 시스템 함정

Windows 사용자명에 한글 포함

증상: C:\Users\홍길동\... 경로에서 빌드 시 한글 인코딩 또는 MAX_PATH 문제

해결: 사용자 폴더 대신 드라이브 루트 에 SDK 압축 해제:

Expand-Archive -Path "$HOME\Downloads\Rev2.0.zip" -DestinationPath C:\dev\ -Force

클라우드 동기화 폴더 (OneDrive, iCloud) 에 압축 해제

증상: 빌드 중 파일 잠금 충돌, 동기화 충돌 파일 생성

해결: 클라우드 비동기 폴더 (예: C:\dev\) 로 이동.


문제가 해결되지 않으면 GitHub Issues에 문의해주세요.

🤖 Claude Code 사용자: "Ex.XX 가 안 돼" 또는 "빌드 에러 났어" 한 줄로 example-helper 스킬이 본 페이지의 해당 항목 + 예제 README 의 ⚠️ 섹션을 인용해 답합니다.