ttySTM이 4개인 이유 — 브링업 검증에서 기대값 세기
지난 글에서 직접 쓴 디바이스 트리로 보드를 부팅시켰다.
root@myir:~# cat /proc/device-tree/model
KNV SC6_0 (MYC-YA157C-V2)
여기까지는 좋았다. 문제는 그다음부터 뭘 봐야 하는지였다.
부팅이 됐다고 페리페럴이 다 사는 건 아니다. 디바이스 트리에 열 몇 개를 적었으니 그게 각각 커널에 어떻게 나타나는지 확인해야 하는데, 숫자를 세다 보니 기대값을 모르면 판단이 안 된다는 걸 알게 됐다.
기대값을 먼저 적는다
DTS에서 활성화한 것들을 목록으로 뽑았다.
| DTS에 쓴 것 | 리눅스에서 어떻게 보일까 |
|---|---|
| uart4, usart3, uart5, uart7, uart8 | /dev/ttySTM* 5개? |
| i2c4, i2c6 (i2c1/i2c2는 끔) | i2cdetect -l 2개 |
| timers1/2/4/8 | /sys/class/pwm/ 4개 |
| gpio-leds 6개 | /sys/class/leds/ 6개 |
| adc1 채널 0,1 | /sys/bus/iio/devices/ |
| sdmmc3 + brcmfmac | wlan0 |
이 표를 먼저 만든 게 결과적으로 잘한 일이었다. 틀린 것과 원래 그런 것을 구분할 기준이 생겼기 때문이다.
사례 1 — 5개를 기대했는데 4개
root@myir:~# ls /dev/ttySTM*
/dev/ttySTM0 /dev/ttySTM1 /dev/ttySTM2 /dev/ttySTM3
DTS에는 시리얼을 다섯 개 열었다. 콘솔(uart4), U3(usart3), U5(uart5), U7(uart7), U8(uart8).
하나가 비었다. 어느 게 안 뜬 건지 찾다가, DTS를 다시 보고 알았다.
&uart7 {
/* ... */
bluetooth {
compatible = "brcm,bcm43438-bt";
};
};
uart7에는 자식 노드로 블루투스 칩이 달려 있다. 이런 경우 커널은 그 포트를 serdev(serial device bus)로 잡아서 블루투스 드라이버에 직접 연결한다. 일반 tty로는 노출되지 않는다.
즉 4개가 정상이었다. 5개가 나왔다면 오히려 블루투스가 안 붙은 것이다.
포트 개수를 셀 때는
aliases에 적은 수가 아니라, 자식 노드가 달린 포트를 뺀 수를 기대해야 한다.
사례 2 — 껐으니 안 나오는 게 맞다
root@myir:~# i2cdetect -l
i2c-0 i2c STM32F7 I2C(0x5c002000) I2C adapter
i2c-1 i2c STM32F7 I2C(0x5c009000) I2C adapter
두 개만 나왔다. 주소로 확인하면 0x5c002000이 I2C4, 0x5c009000이 I2C6이다. 둘 다 우리가 쓰는 버스다.
벤더 BSP는 I2C1과 I2C2도 켜뒀지만, 우리 보드에서 그 핀들은 다른 용도였다.
- I2C2(PH4/PH5) → 우리는 AC 검출 입력
- I2C1(PB6/PD13) → LCD 전용이었는데 패널을 안 씀
그래서 DTS에서 명시적으로 껐고, 안 나오는 게 의도한 결과다.
그런데 만약 기대값 표를 안 만들었다면 “I2C가 두 개밖에 없네, 뭐가 잘못됐나” 하고 한참 뒤졌을 것이다. 끈 것도 적어둬야 한다.
사례 3 — 에러가 났는데 동작한다
WiFi 로그에 빨간 줄이 있었다.
brcmfmac mmc0:0001:1: Direct firmware load for
brcm/brcmfmac43430-sdio.knv,stm32mp157a-sc6.txt failed with error -2
-2는 ENOENT, 파일이 없다는 뜻이다. 그런데 바로 다음 줄을 읽으니 얘기가 달랐다.
brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0:
Sep 11 2018 09:22:09 version 7.45.98.65 (r707797 CY) FWID 01-b54727f
펌웨어가 정상 로드됐다. ip link를 보니 인터페이스도 있었다.
4: wlan0: <BROADCAST,MULTICAST> mtu 1500 ...
link/ether 40:fd:f3:ec:c5:78
brcmfmac은 보드별 설정 파일(<compatible>.txt)을 먼저 찾고, 없으면 일반 파일로 fallback한다. 실제로 디렉터리를 보니 이랬다.
root@myir:~# ls /lib/firmware/brcm/ | grep 43430
brcmfmac43430-sdio.AP6212.txt
brcmfmac43430-sdio.myir,stm32mp157c-ya157c-v2.txt
brcmfmac43430-sdio.txt ← 이걸로 대체됨
brcmfmac43430-sdio.bin
brcmfmac43430-sdio.clm_blob
BCM43430A1.hcd
스캔도 잘 됐다.
root@myir:~# iw dev wlan0 scan | grep -E "SSID|signal"
signal: -67.00 dBm
SSID: KNVISION
signal: -76.00 dBm
SSID: WINIX SMART Air
...
-67 dBm이면 연결에 충분하다. SDIO 배선, 전원 제어(WL_REG_ON), 펌웨어, 안테나까지 전부 정상이라는 뜻이다.
그럼 저 에러는 왜 났나
내가 compatible을 바꿨기 때문이다.
compatible = "knv,stm32mp157a-sc6", "myir,stm32mp157c-ya157c-v2", "st,stm32mp157";
brcmfmac은 보드의 첫 번째 compatible 문자열로 설정 파일 이름을 만든다. 문자열을 바꿨으니 찾는 파일 이름도 바뀌었고, 그런 파일은 당연히 없다.
링크 하나면 정리된다.
cd /lib/firmware/brcm
ln -sf "brcmfmac43430-sdio.myir,stm32mp157c-ya157c-v2.txt" \
"brcmfmac43430-sdio.knv,stm32mp157a-sc6.txt"
동작에는 지장이 없지만, 보드 전용 캘리브레이션 값을 쓰는 게 맞으니 링크를 걸어두는 편이 낫다.
compatible을 바꾸면 커널 안에서만 끝나지 않는다. 펌웨어 파일명, udev 규칙, 유저 공간 설정이 그 문자열을 참조하고 있을 수 있다.
사례 4 — 에러가 없는데 안 된다
앞과 정반대 경우도 만났다. WiFi에 연결하려고 connmanctl을 쳤다.
root@myir:~# connmanctl
Error getting technologies: The name net.connman was not provided by any .service files
connmanctl은 있는데 안 된다. 이건 D-Bus 에러로, net.connman 서비스가 등록되어 있지 않다는 뜻이다. 클라이언트만 있고 데몬이 안 돌고 있었다.
root@myir:~# systemctl status connman
Loaded: loaded (/lib/systemd/system/connman.service; disabled; ...)
Active: inactive (dead)
disabled. 이미지에 설치는 되어 있는데 자동 시작이 꺼져 있었다.
systemctl start connman
systemctl enable connman # 다음 부팅에도 유지
“설치되어 있다”와 “돌고 있다”는 다르다. 명령어가 존재한다고 서비스가 준비된 건 아니다.
기대대로였던 것들
나머지는 표대로 나왔다.
root@myir:~# ls /sys/class/pwm/
pwmchip0 pwmchip4 pwmchip8 pwmchip12
TIM1/2/4/8 네 개. 각각 B_AC_ON, PWM_CP, C_AC_ON, PWM_WDI용이다. 부모 타이머를 status = "okay"로 켜는 걸 빠뜨렸다면 하나도 안 나왔을 것이다.
root@myir:~# ls /sys/class/leds/
bled dout1 dout2 dout3 dout4 rled
여섯 개. 상태 LED 둘과 디지털 출력 넷이다. 이제 유저 공간에서 바로 토글할 수 있다.
echo 1 > /sys/class/leds/dout1/brightness
DOUT1은 PG10 → ULN2803 달링턴 드라이버 → 12V 부하로 나간다. 회로에서 유도한 극성(GPIO_ACTIVE_HIGH)이 맞는지 단자에서 실측할 차례다.
정리 — 검증은 세는 일이 아니다
이번에 네 가지 경우를 만났다.
| 보인 것 | 실제 | |
|---|---|---|
| ttySTM | 5개 중 4개 | 정상 (BT가 serdev로 빠짐) |
| I2C | 4개 중 2개 | 정상 (2개는 의도적으로 끔) |
| WiFi | 에러 로그 | 동작함 (fallback 성공) |
| connman | 에러 없음 | 안 돎 (데몬 미실행) |
개수만 세거나 로그만 봐서는 넷 다 틀리게 판단한다. 각각 “왜 그 값이어야 하는지”를 알아야 맞고 틀림이 갈린다.
그래서 검증 전에 기대값 표를 만든 게 유용했다. 표에 적을 때 이미 한 번 “이건 왜 이 개수지?”를 생각하게 되고, 실제 결과와 어긋나면 어긋난 이유를 찾을 수 있는 상태가 된다.
DTS를 쓸 때 주석에 근거를 남겨두라고 했던 것과 같은 맥락이다. 검증도 기대값을 먼저 글로 적어두면 훨씬 빨라진다.
다음은 PLC 모뎀 드라이버를 모듈로 올리고, DOUT/DIN 극성을 실측으로 확인할 차례다.
댓글남기기