恭喜你挺過了第一階段!前五天我們討論了邊緣運算閘道器的架構選擇、UART 通訊以及 Headless 設備的燈號互動哲學。今天,我們正式進入本系列最硬核的第二階段:Linux 底層與 USB OTG 黑魔法。
在我們的 EdgeNode 架構中,有一個非常魔幻的需求:當我們把 Raspberry Pi 透過 USB 傳輸線插上醫療用的 Windows 電腦時,這台 Pi 必須在電腦上顯示為「一顆 FAT32 的隨身碟」。
這聽起來有點違背常理,因為通常是我們把隨身碟插進 Pi,怎麼會是把 Pi 當成隨身碟插進電腦呢?今天我們就來破解這個魔法的第一步:USB OTG。
[問題情境] 誰是老大?USB 的階級制度
在 USB (Universal Serial Bus) 的世界裡,有著嚴格的階級制度:
USB Host (主機):通常是你的筆電、桌機,或是插著滑鼠鍵盤的 Raspberry Pi。Host 負責供電,並且是所有通訊的發起者。
USB Device (裝置 / Gadget):隨身碟、鍵盤、滑鼠。它們是被動的,只能聽命於 Host 的指揮。
以往的電腦只有 USB Type-A 孔 (Host),而隨身碟只有 Type-A 接頭 (Device)。兩者的身分在出廠時就寫死了。 但隨著行動裝置的普及,人們開始希望手機能當作 Device (插上電腦傳檔案),也能當作 Host (接上 OTG 線插隨身碟看電影)。這就是 USB OTG (On-The-Go) 誕生的背景。
[底層原理] 第 5 根針腳的秘密
傳統的 USB 2.0 有 4 根針腳 (VBUS, D-, D+, GND)。 而支援 OTG 的 Micro-USB 或 USB-C 介面,多了一根神奇的針腳:ID Pin。
當 ID 腳位懸空 (Floating) 時,設備會認為自己是 USB Device (Gadget),等著被別人讀取。
當 ID 腳位接地 (GND) 時,設備會啟動昇壓電路向外供電,並把自己切換成 USB Host。
這就是為什麼你在買給手機用的「OTG 轉接線」時,裡面的線路其實已經把 ID Pin 悄悄接地了,藉此欺騙手機把自己變成 Host。
對於我們的 EdgeNode (使用支援 OTG 的 Raspberry Pi 機型,如 Pi 4 的 Type-C 供電口,或 Pi Zero 的資料口),只要我們用一條普通的 Type-C 傳輸線接上 PC,因為這條線沒有把 ID 接地,Pi 的硬體底層就會預設進入 Device Mode。
[最終解決方案] Linux USB Gadget Framework
既然硬體層面已經進入了 Device Mode,那軟體層面呢? 如果此時你的 Linux 系統沒有準備好,Windows 電腦插上 Pi 之後,只會跳出「無法辨識的 USB 裝置」。
為了讓 Linux 能夠扮演好 Device 的角色,Linux Kernel 社群開發了強大的 USB Gadget Framework。這套框架允許我們將 Linux 偽裝成任何你想像得到的 USB 設備:
g_mass_storage:偽裝成隨身碟
g_serial:偽裝成虛擬序列埠 (COM Port)
g_ether:偽裝成 USB 網卡
g_hid:偽裝成鍵盤滑鼠
只要我們啟用了適當的核心模組 (Kernel Module),當 Windows PC 發出「你是誰?」的 USB 描述符請求時,Linux Kernel 就會乖乖回答:「報告,我是一顆 16GB 的 FAT32 隨身碟!」
預告
聽起來很簡單對吧?但「啟用核心模組」可不是敲幾行 Python 就能解決的。這牽涉到 Linux 核心在開機時是如何認知自己的硬體電路的。 明天,我們將展開一場考古之旅,帶你深入探索 Linux 硬體底層的暗黑魔法:Device Tree 與 MMIO 位址之謎。準備好你的終端機,我們明天見!