iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
佛心分享-IT 人職涯歷練

我從 intern 變菜鳥:30 天學會別再手擀破輪子系列 第 11

Day 11|我看不懂 I²C、SPI,不代表產品缺一套 AT Command

  • 分享至 

  • xImage
  •  

我們用 SMART——Specific(具體)、Measurable(可衡量)、Achievable(可達成)、Relevant(具關聯)、Time-bound(有時限)——把每個故事拆成五天,作為每次動手造輪子前的五個檢查問題。

本篇是故事三「你的 I²C、SPI 我看不懂,先幫我包成 AT Command」的 Specific 篇:現在真正要解決的是什麼問題?

本篇定位:區分「系統需要高階介面」與「某位工程師希望介面長得熟悉」。

當時發生了什麼

上一個故事的教訓還熱著:手邊剛好有的東西,不該反過來定義需求。下一個專案就讓我看見同一種倒置的另一張臉。

新專案要在設備上加一顆感測器晶片,起點好得不可思議:晶片走 I²C(Inter-Integrated Circuit),原廠給了完整的暫存器(register)表、時序圖與參考驅動程式;另一顆周邊走 SPI(Serial Peripheral Interface),文件同樣齊全。以前兩個故事的標準看,天堂開局。

第一次跨組會議,負責應用邏輯的資深工程師翻了翻暫存器表,闔上,說出了本故事的標題:「你的 I²C、SPI 我看不懂,先幫我包成 AT Command。我以前接數據機都這樣打——讀溫度給我 AT+TEMP?,回 OK 或 ERROR 就好。」

丟臉的是我的反應。我不但不覺得奇怪,還隱隱興奮:設計一整套命令格式,比抄參考驅動高級多了。當晚我就開始畫命令總表。直到組長問了一句:「這些命令,要從哪條線送進來?」我張口,答不出來。

真正的問題在哪裡

答不出來的原因很物理:應用端的程式和我們的韌體跑在同一顆 MCU 上,同一份原始碼、同一次編譯,中間沒有任何一條實體通道。而命令協定要解的問題全部長在通道上——位元組怎麼切、對方沒回應是沒收到還是沒做完、兩端各自改版怎麼辦。通道不存在,這些問題就一個都不存在,協定成了一份沒有對象要簽的契約。組長那一問之所以致命,在於它問的不是設計品味,是物理前提。

先講清楚,免得變成獵巫:AT Command 本身沒有錯。行動通訊模組有標準化的命令集可循,Wi-Fi 模組則多半各廠自訂一套;共通點不在語法,在處境——模組與主控端隔著 UART,分屬不同廠商、不同韌體、不同生命週期,需要一份寫得成文件、也靠得久的契約。那位工程師的經驗是真的,只是他把「我熟悉的介面長這樣」升級成了「產品需要這樣的介面」。

放大來看,系統裡有三層東西被混為一談。最底下是匯流排(bus),I²C 與 SPI 把位元組搬進搬出晶片;中間是驅動 API,把暫存器與時序封裝成讀溫度、設取樣率這種函式,兩端同在一顆晶片裡,呼叫就是抵達;最外面才是跨系統整合介面,它要跨越的正是那條通道。應用端需要的是中間那層,開口要的卻是最外面那層。

至於「我看不懂」,在會議裡被無縫翻譯成「所以系統缺一個東西」——陌生感包裝成產品需求,這是本故事最核心的偷換。我則從另一個方向當了共犯:設計協定比讀懂別人的驅動更有成就感。於是不想讀說明書的人和想造輪子的人一拍即合,去解一個不存在的問題。

可以怎麼做

那句要求該還原成什麼?三個問題:誰要用、站在哪個邊界、需要什麼資料契約。

誰要用:使用者是同一份韌體裡的應用模組,不是隔著序列埠的另一台機器。人在邊界之內,就用不到跨邊界的協定。

站在哪個邊界:應用端不想碰匯流排與暫存器,這個訴求完全正當,滿足它的既有手段是驅動 API。原廠參考驅動已把時序處理完,缺的只是照專案慣例補上函式名與型別。

需要什麼契約:把「AT+TEMP?」翻譯回真正的需求,是一個回傳攝氏溫度的函式、一個設定取樣率的函式、一個資料就緒的通知方式。寫成函式原型是三行:

int  sensor_read_temp_c(sensor_t *dev, float *out_celsius);
int  sensor_set_sample_rate_hz(sensor_t *dev, uint16_t hz);
int  sensor_register_data_ready_cb(sensor_t *dev, sensor_cb_t cb, void *ctx);

單位在名字裡,資料流向在參數裡,成敗在回傳值裡,資料就緒用回呼(callback)通知;一頁標頭檔講完,編譯器還會替我們檢查一遍。對面那張以 AT+TEMP? 開頭的總表,光「溫度幾位小數、負值怎麼表示、ERROR 之後怎麼問原因」就得另寫規格書,而規格書沒有編譯器幫忙讀。

命令協定的合理位置是跨系統邊界:兩端隔著通道、各自演進時,它成熟、正確,也值得投資。這個專案不是。

今天學到的事

上一個故事的病是「手上有什麼,決定了要什麼」;這個故事是它的鏡像——「我熟悉什麼,決定了系統該長什麼樣」。兩者都把需求的定義權讓給了與需求無關的東西。

「我看不懂」是完全正當的起點,但接下來有三條岔路,主詞各不相同。查字典——讀懂暫存器表、把時序與錯誤處理掉——是韌體端的分內事,本該由我們做完,不該倒推給應用端自己讀。請翻譯——要韌體端交出一層命名清楚的驅動 API——才是應用端該提、也提得理直氣壯的那條。要求全世界改說自己的母語,也就是為此發明並永久維護一套協定,是本案誤選的那條。三條路成本天差地遠,會議室裡最容易被選中的往往是最貴的那條,因為它最像在做事。

真正讓大家停下來的不是道理,是一個更俗氣的問題:包這一層,到底要多做多少事?這筆帳明天攤開來算。


上一篇
Day 10|選型不能無限試,也不能第一天就被庫存定案
下一篇
Day 12|多包一層字串介面,就要多驗收一整套生命週期
系列文
我從 intern 變菜鳥:30 天學會別再手擀破輪子12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言