首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET Micro Framework 實作 USB Mass Storage:從枚舉到 SCSI 指令完整解析

     編輯:關於.NET

架構挑戰與解決策略

.NET Micro Framework (MF) 原生 USB 驅動不支援 Mass Storage,需:

  1. 在 USB 驅動層新增枚舉處理碼(原應屬 PAL 層,為相容性置於驅動層)。
  2. 採用時鐘中斷輪詢 USB 端點資料,避免佔用唯一應用程序執行緒。
  3. 透過 PAL 層 SectorCache 間接存取 Flash/SD,兼具快取加速與裝置抽象化。

功能限制:單一邏輯單元 (LUN=0)、不支援 PC 端格式化(需本地介面)、檔案系統固定 FAT32。

USB 設定調整

  • VID/PID:修改 VID 避免與既有 MF 驅動衝突。
  • 介面描述符:Class=0x08 (Mass Storage)、Subclass=0x06 (SCSI) 或 0x04 (UFI)、Protocol=0x50 (Bulk-Only)。

USB 介面描述符設定

對外呼叫介面

PAL 層 (C/C++)

int UsbMassStorage_Start(UINT32 interval_us); // 啟動,關閉舊介面、載入新 Config、啟動定時中斷
int UsbMassStorage_Stop();                   // 停動,關閉中斷、還原預設 USB 介面

Managed P/Invoke

namespace YFSoft
{
    public static class MassStorage
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        extern static public int Start(UInt32 value);
        [MethodImpl(MethodImplOptions.InternalCall)]
        extern static public int Stop();
    }
}

呼叫 Start() 前務必先 VolumeInfo.FlushAll() 確保快取寫入。

USB 控制端點枚舉處理

在 EP0_ISR() 中新增:

if (Setup->bmRequestType == 0xA1 && Setup->bRequest == 0xFE) // GET_MAX_LUN
{
    usb.FIFO[0] = 0; // 單一 LUN 回傳 0
    usb.Indexed.PERI_CSR0 = TXPKTRDY | DATAEND;
    return;
}
if (Setup->bmRequestType == 0x21 && Setup->bRequest == 0xFF) // MASS_STORAGE_RESET
{
    usb.Indexed.PERI_CSR0 = TXPKTRDY | DATAEND;
    return;
}

Bulk-Only Transport 核心流程

僅需兩個 Bulk 端點:EP1 (IN)、EP2 (OUT),符合 MF 預設驅動。

CBW (Command Block Wrapper) 31 bytes

欄位說明
dCBWSignature0x43425355 ('USBC')
dCBWTag主機發送標籤,CSW 需原樣回傳
dCBWDataTransferLength預期傳輸長度,0 表示無資料階段
bmCBWFlagsBit7: 0=Out/1=In
bCBWLUN邏輯單元號 (0)
bCBWCBLengthCBWCB 有效長度 (1~16)
CBWCBSCSI/UFI 指令區塊

CSW (Command Status Wrapper) 13 bytes

欄位說明
dCSWSignature0x53425355 ('USBS')
dCSWTag對應 CBW 的 dCBWTag
dCSWDataResidue實際與預期傳輸長度差值
bCSWStatus0=Pass, 1=Fail, 2=Phase Error

必須實作的 SCSI/UFI 指令子集

  1. INQUIRY (0x12):回傳廠商、產品、版本。Peripheral Device Type=0 顯示為可移動磁碟,=0x1F 顯示為固定磁碟。
  2. READ_FORMAT_CAPACITIES (0x23):回傳區塊數、區塊長度 (大端序)。
  3. READ_CAPACITY (0x25):回傳最後一個區塊索引與長度 (大端序)。
  4. READ_10 (0x28):讀取指定 LBA 起始、區塊數的資料,直接回傳資料階段。
  5. WRITE_10 (0x2A):接收 CBW 後續資料寫入指定 LBA。注意:資料量大時需分多次中斷處理,不可一次讀完所有扇區。
  6. REQUEST_SENSE (0x03):CSW 非 0 時主機詢問錯誤細節,回傳 Sense Key=0x05 (ILLEGAL REQUEST)。
  7. TEST_UNIT_READY (0x00):主機定期輪詢裝置就緒,直接回傳 CSW Status=0。

命令/資料/狀態流程圖

CBW 結構

CSW 結構

實作關鍵點總結

  • 時鐘中斷輪詢替代背景執行緒,符合單行程限制。
  • SectorCache 抽象化儲存媒體,支援 Flash/SD 免修改程式碼。
  • Bulk-Only 協議簡化端點管理,僅需標準 Bulk IN/OUT。
  • WRITE_10 分批處理避免中斷過長導致 TinyCLR 異常。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved