직렬 통신과 modprobe
송용석 책임
이 글은 다음과 같은 환경의 Raspberry Pi를 다루고 있습니다.
- OS Release : Raspbian GNU/Linux 9 (stretch)
- Kernal : 4.14.98-v7+ #1200 SMP Tue Feb 12 GMT 2019 armv7l
modprobe
modprobe
에 대한 이야기로 시작해야겠습니다. 위키피디아에서는 다음과 같이 정의하고 있습니다.
modprobe
는 리눅스 프로그램으로서 적재 가능 커널 모듈(LKM, Loadable Kernel Module)을 리눅스 커널에 추가하거나 커널로부터 제거하는 데 사용된다.
아주 간단한 설명이지만 결국엔 저게 핵심입니다. 적재 가능 커널 모듈을 커널에 추가하거나 제거하는 데 사용합니다만, 일반적인 경우에는 사용자가 직접 사용할 일이 드뭅니다.
저는 이번에 라즈베리파이
에 모션 센서
(digital compass 등)를 연결해 3차원 공간에서 강체가 놓인 각도(yaw, pitch, roll 등) 데이터를 취득할 목적으로 RS-485
통신을 하게 되었는데, 이렇게 기존에 존재하던 Linux system에 새로운 H/W가 주어지는 상황이 modprobe
에 대해 알아볼 수 있는 가장 흔한 경우인 것 같습니다.
기존 시스템에 새로운 주변 기기가 들어오는 상황! 다들 집에 있는 데스크탑 PC(대개의 경우 Windows
)에 새로 구입한 프린터 드라이버
설치해본 경험들 있으시잖아요? 마찬가지입니다. 😆
modprobe
프로그램은 다음과 같은 이점들을 통해서 더 기본적인 유틸리티들인 insmod
와 rmmod
보다 더 완성된 기능을 제공합니다.
- 어떤 모듈이 로드되어야 할지에 관한 직관적인 결정을 제공하는 능력
- 모듈을 로드하기 위해 언제 요청되어야 할지와 어떤 먼저 요구되는 모듈을 추가할지 같은 모듈 의존성에 대한 인식
- 요구되는 재귀적 모듈 의존성의 해법
이슈
사실 사건(?)의 발단은 이렇습니다. RS-485-to-USB converter를 사용해서 digital compass 센서를 간단하게 Raspberry Pi의 USB port에 물렸는데 그 어떠한 /dev/ttyUSBn
도 자동으로 잡히지 않는 겁니다.
애초에 연결 상에 물리적인 어떤 결함이 있어서 제대로 인식 자체가 되지 않은 것인가? 이를 테면, 센서로 들어가는 파워가 온전치 못하다든지, USB end-points(male-female) 접촉불량이라든지, 그런 문제는 아니었습니다.
lsusb
커맨드로 확인해보면 다음과 같이 device 정보가 잘 잡혔습니다.
pi@raspberrypi:~ $ lsusb
Bus 001 Device 004: ID 046d:c534 Logitech, Inc. Unifying Receiver
Bus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Device 005에 제조사(FTDI)도 보이고, USB-Serial (UART)라고 프로덕트도 아주 잘 언급해주고 있습니다만, /dev/
내부에 아무런 ttyUSB가 잡히지 않는 상황! 😱
조치
다음의 커맨드로 바로 해결될 수(도) 있습니다.
pi@raspberrypi:~ $ sudo modprobe ftdi_sio
pi@raspberrypi:~ $ sudo sh -c "echo 0403 6001 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id"
저기에서 modprobe
뒤의 ftdi_sio
는 모듈명으로서 사용된 것이고요, 저 커맨드를 통해 /sys/bus/usb-serial/drivers/
아래 ftdi_sio
디렉토리가 생성됩니다. 만약 이놈이 자동으로 알아서 척척 잘 잡혔더라면 이미 저 경로에 버젓이 존재하고 있었어야 할 디렉토리가 되겠습니다.
echo
뒤의 두 코드는 각각 제조사 ID와 제품 ID입니다. 제조사 ID는 여기에서도 확인해볼 수 있습니다. lsusb
커맨드를 통해 두 ID 모두 확인할 수 있고, 저 코드를 modprobe
커맨드를 통해 만든 ftdi_sio
디렉토리 내 new_id
라는 파일에 쓰게 됩니다.
또 다른 작은 이슈
바로 해결이 되지 않을 수도 있습니다..
제 경우에는 modprobe
를 실행했을 때도,
pi@raspberrypi:~ $ sudo modprobe ftdi_sio
modprobe: ERROR: could not open directory /lib/modules/4.14.98-v7+: No such file or directory
modprobe: FATAL: could not search modules: No such file or directory
depmod
를 실행했을 때도,
pi@raspberrypi:~ $ depmod
depmod: ERROR: could not open directory /lib/modules/4.14.98-v7+: No such file or directory
depmod: FATAL: could not search modules: No such file or directory
확인해보니 정말 /lib/modules/
경로에 제 파이 커널 버전(4.14.98-v7)에 해당하는 디렉토리가 없었는데요, upgrade하고서 제 때 reboot해주지 않아서 생긴 불상사였습니다.reboot하라고 물어보면 제발 좀 제 때 제 때 해줍시다!
일반적으로는 다음과 같이 linux-headers나 linux-image를 재설치해주면 해결된다고 합니다.
pi@raspberrypi:~ $ sudo apt-get install --reinstall linux-image-`uname -r`
휴.. 진짜 이렇게 해서 없던 /dev/ttyUSB0
이 생기고, 직렬 통신 port open 성공할 때의 희열은 해본 자만이 느낄 수 있는 것 같습니다.
끝! 😎