라즈베리 파이 USB HID 설정 실패 : echo와 printf
라즈베리 파이를 이용해 USB 가젯, 특히 키보드나 마우스 같은 HID 장치를 만드는 프로젝트 진행 중, 모든 단계를 올바르게 따라 했음에도 장치가 PC에서 인식되지 않는 "먹통" 현상을 겪는 경우가 있음.
이 문제의 주범은 기본적인 명령어 echo -ne의 오용일 가능성이 높음.
문제의 코드: echo -ne를 이용한 Report Descriptor 작성
USB HID 장치 설정의 핵심은 **리포트 디스크립터(Report Descriptor)**를 시스템 파일에 기록하는 과정임. 이 디스크립터는 장치가 어떤 데이터를 어떻게 전송할지 정의하는 '설명서'이기에, 반드시 바이너리 데이터 형태로 작성되어야 함.
온라인에서 흔히 발견되는 문제의 코드는 다음과 같음.
# 🔴 문제가 발생할 가능성이 높은 코드
echo -ne "\\x05\\x01\\x09\\x06\\xA1\\x01...\\xC0" | sudo tee functions/hid.usb0/report_desc
위 코드의 본래 의도는 \x05 같은 16진수 이스케이프 시퀀스를 실제 바이트 값으로 변환하여 report_desc 파일에 쓰는 것이지만, 이 코드는 종종 의도대로 동작하지 않음.
실패 원인
echo 명령어는 가장 기본적인 유틸리티지만, 그 동작 방식은 사용하는 셸에 따라 일관되지 않음.
- 셸 의존성:
echo -e옵션은 백슬래시 이스케이프를 해석하라는 의미지만, 이는 POSIX 표준 기능이 아님. 즉, 모든 셸이 이 옵션을 동일하게 지원한다고 보장할 수 없음. bashvsdash: 일반적으로 사용하는bash셸은\xHH(16진수 바이트) 같은 확장 시퀀스를 잘 해석함. 하지만 Raspberry Pi OS를 포함한 데비안 계열 리눅스의 기본 시스템 셸(/bin/sh)은dash임.dash의echo는\xHH형식을 해석하지 못함.- 결과: 손상된 디스크립터:
dash셸 환경에서 위 코드가 실행되면,\x05는 하나의 바이트(0x05)가 아닌, 네 개의 문자('\', 'x', '0', '5')로 파일에 기록됨.- 의도한 데이터 (정상):
05 01 A1 01 ...(바이너리 값) - 실제 기록된 데이터 (손상):
\x05\x01\xA1\x01...(텍스트 문자열)
- 의도한 데이터 (정상):
이처럼 텍스트로 손상된 '설명서'는 USB 호스트(PC)가 해석할 수 없으므로, 결국 장치 인식 실패로 이어지게 됨.
해결책: printf 사용
이 문제를 가장 확실하고 올바르게 해결하는 방법은 echo 대신 printf를 사용.
printf란?:printf는 포맷팅된(formatted) 출력을 위해 설계된 표준 유틸리티,\xHH를 포함한 다양한 이스케이프 시퀀스를 처리하는 방식이 모든 표준 셸에서 일관되게 동작함.
올바른 코드는 다음과 같음.
# 🟢 안정적이고 올바른 코드
printf "\x05\x01\x09\x06\xA1\x01...\\xC0" | sudo tee functions/hid.usb0/report_desc
여기서 더 나아가, sudo 권한과 파일 리디렉션(>) 문제를 가장 확실하게 해결하는 방법은 bash를 명시적으로 호출하는 것임.
# ✅ 가장 확실하고 권장되는 방법
sudo bash -c 'printf "\x05\x01\x09\x06\xA1\x01...\\xC0" > functions/hid.usb0/report_desc'
이 방식은 현재 사용 중인 셸의 종류와 관계없이, printf를 올바르게해석하는 bash를 루트 권한으로 실행하여 명령을 처리하므로 신뢰성이 보장됨.
결론
셸 스크립트에서 단순 텍스트를 출력할 때는
echo를 사용해도 무방하지만,\n,\t또는\xHH와 같은 이스케이프 시퀀스가 포함된 데이터를 다룰 때는printf를 사용하는 것이 좋음.
'인프라' 카테고리의 다른 글
| [Nginx] SSL/TLS 인증서 설정하기 (0) | 2025.05.23 |
|---|---|
| [리눅스 뻘짓 일기] 루트 파티션 변경 하기 (0) | 2025.04.08 |
| [ubuntu22.04] Docker 설치하기 (1) | 2024.10.10 |
| [TInypilot] Tinypilot 도커로 컨테이너화 해보기 (2) | 2024.09.01 |
| [ubuntu 22.04] lxc 설정하기 (1) | 2024.08.31 |