嵌入式系統usb開發學習概述

嵌入式系統usb開發學習概述

如未特別說明, 現階段學習的usb主要是指usb從機/設備.

簡單閱讀過一些介紹USB應用基礎和協議棧的文檔之後, 發現協議棧的內容主要是約定要怎樣怎樣, 數據包格式啊, 通信機制啊. 但是, 真正落實到MCU上的程序設計時, 首要要搞清楚的是, 哪些工作是由硬件完成的, 那些工作是由軟件完成的. 需要軟件完成的部分, 可以參考已有的很多優秀且開源的usb協議棧程序, 作爲用戶來講, 這部分代碼就不需要從頭設計編寫了, 直接複用就好. 而硬件部分在各個芯片上各有不同, 而當我們需要某個特定的芯片平臺上使用usb功能時, 就需要使用具體的usb控制器想方設法滿足上層協議棧軟件對數據和事件響應的需求, 完成usb協議最終棧的移植.

這裏以複雜度相當的文件系統fatfs和以太網協議棧lwip作爲類比, 用戶在移植時, 只要實現底層簡單的讀寫操作, 並嵌入到協議棧的底層函數中, 中間關於協議棧的複雜機制對於大多數用戶來講都是黑盒子, 用戶直接調用協議棧的應用層API就能使用. usb相對於這些協議棧來說, 在底層也比較簡單, 但需要明確搞清楚對硬件的需求. 作爲一個通信類的協議棧, usb協議棧的基本操作就是傳數, 全部數據都是通過"端點"傳輸的, 而端點在硬件上就是一段內存的緩衝區, 可以向其中寫數據(發數), 也可以從中讀數據(收數). 另外, usb通信過程中還有一些事件告訴usb協議棧需要分情況處理, 這些事件在硬件上反應在usb的通信包, 有些集成度比較高的usb控制器模塊簡化了軟件判斷的工作, 能夠使用硬件電路自動檢測到這些特殊的通信包, 然後在寄存器上通過一個狀態標誌位告訴軟件, 這樣usb的軟件部分只要安心處理有效數據的收發就好.

但usb相對於fatfs和lwip相對難學一點的主要原因在於:

  • usb從機開發使用典型的從機開發模型. 基本的usb應用是從機部分, 整個通信過程都是受主機控制, 用戶需要編程的從機是需要配合主機進行通信, 主動權不在用戶手裏, 說白了, 不是平時調程序那樣, 想走就走, 想停就停. 這裏的應對思路是, 就是要用通信系統的從機開發模型考慮usb的開發過程. 在通信系統的從機開發模型中, 從機不會主動啓動通信, 都是被動地在任何可能的時間點接受主機的觸發. 這就意味着, 所有的程序執行過程都需要從中斷開始. 這樣看, 就限定了usb從機編程的基本框架, 對於初學者來說, 至少在閱讀現有的usb工程時, 可以找到處理usb實踐的入口了. 相似的編程模型可以參考I2C從機.

  • 從機模型通常只能等待主機讀或者主機寫, 比如u盤設備. 但例如usb鍵盤這樣需要上傳給主機數據的設備, 怎樣主動向主機發送數據呢? 在usb通信機制中, 至少有兩種方法可以處理類似的情況: usb主機會每隔1ms向總線上發一次問詢, 問問有沒有從機要上報數據, 沒錯, 這就是輪詢; 另一種是遠程喚醒, 這是用在低功耗場景中的, 可以以後再看. 所以說, 大體上看, 整個usb系統還是使用輪詢機制從從機讀數或者寫數的, 但具體再usb從機的設計上, 考慮到同時還要執行除usb之外其他的工作, 因此還是將相應主機操作的程序全部放在中斷中. 更進一步, 在有些優化的usb協議棧中, 還將usb中斷服務程序和多線程結合起來, 緊要的回覆先在中斷服務程序中進行, 不緊要的處理通過標誌位傳遞給任務中, 讓任務慢慢去處理.

  • usb協議棧可以支持多種設備的靈活性. usb的功能不向文件系統那麼單一, 它需要支持多種多樣的設備, 可以是輸入設備的鍵盤或鼠標, 還可以是輸出設備的U盤. usb是通過各種各樣的"描述符"讓PC識別成不同設備的, 這就是usb的"枚舉過程". 其實這個"枚舉過程"並沒有那麼神祕, 在本質上還是傳數而已. 我們很多人有使用過LCD屏的經驗, 當使用LCD屏之前需要配置一些參數到LCD屏的控制器中, 才能讓LCD屏正常工作. usb的"枚舉過程"就是向主機初始化的過程, 從機在初始化過程中向主機發送一些信息(或者按照格式填寫登記表格), 讓主機識別自己, 對應地以特定的模式與本機協同工作. 在初始化到不同的工作模式後, 對應的數據包格式也各自不同. 這些"表格"的格式都有模板, 拿現有的樣例程序結合usb協議棧的各種選項表改改, 就能定製自己需要的功能了.

這些就是嵌入式開發者學習usb的基本思路.

建議的學習方式是:

  1. 不要一開始就啃usb協議棧, 可以先了解一些usb的基本概念, 科普一下.
  2. 然後仔細看看自己選用硬件平臺上的usb控制器有什麼功能, 能夠實現哪些基本操作.
  3. 找一款自己傾向的usb協議棧實現代碼, 作爲usb純軟件部分的框架(這部分代碼沒必要自己再敲一遍), 最好應用例程比較豐富, 便於自己後期修改.
  4. 想方設法將自己的硬件平臺同軟件組件對接上.
  5. usb應用層的部分與硬件完全無關, 可以用選用的usb協議棧自帶的程序驗證一下. 大多數情況下, 到這一步就能夠滿足絕大多數初學者的應用需求了, 例如hid鼠標鍵盤, cdc串口, msd大容量存儲設備等, 再複雜一點就是複合類, 也有不少usb協議棧的實現提供了樣例程序.
  6. 閱讀自己移植好的代碼, 再看usb協議棧的文檔, 嘗試定製自己的功能. 例如, 改改設備設備的字符串, 或者定製更復雜的設備等等.

End

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章