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

基於 OHCI 的 USB 主機:UFI 寫扇區命令實現詳解

     編輯:關於C語言

功能概述

本文展示基於 OHCI 協議的 USB 主機控制器中,針對 UFI(Uniform Floppy Interface)協議的寫扇區命令實現代碼。該功能用於向 USB 大容量存儲設備(如 U 盤)寫入單個 512 字節扇區數據。

核心代碼實現

/**
 * 寫磁盤扇區命令
 * @param sect 物理扇區號 (LBA)
 * @param *buf 數據緩衝區指針
 * @return 0 - 成功
 */
short ufiWriteSect(DWORD sect, BYTE *buf)
{
    WRITE_10 *write10;
    CBW *cbw;

    // 設置 Bulk-Only 協議參數 (CBW)
    cbw = &ufiCmdRunning.cbw;
    cbw->dCBW_Signature = CBW_SIGNATURE;        // 固定簽名 0x43425355
    cbw->dCBW_Tag = 0x60a624de;                 // 命令標籤,用於匹配 CSW
    cbw->dCBW_DataXferLen = 512;                // 傳輸長度:單扇區 512 字節
    cbw->bCBW_Flag = 0x00;                      // 方向標誌:0 = Data-Out (主機到設備)
    cbw->bCBW_LUN = 0;                          // 邏輯單元號
    cbw->bCBW_CDBLen = 16;                      // CDB 長度

    // 設置 UFI WRITE_10 命令參數 (CDB)
    write10 = &(cbw->cdbRBC.ufiWrite10);
    write10->OperationCode = 0x2A;              // WRITE_10 操作碼
    write10->LBA_0 = byteInInt(sect, 0);        // LBA 位元組 0 (最高位)
    write10->LBA_1 = byteInInt(sect, 1);
    write10->LBA_2 = byteInInt(sect, 2);
    write10->LBA_3 = byteInInt(sect, 3);        // LBA 位元組 3 (最低位)
    write10->XferLen_0 = 0x01;                  // 傳輸扇區數高位元組
    write10->XferLen_1 = 0x00;                  // 傳輸扇區數低位元組 (共 1 個扇區)

    // 設置狀態掃描函數所需參數
    ufiCmdRunning.funUfiCmd = bulkWrite;        // 批量寫入處理函數
    ufiCmdRunning.pBuf = buf;                   // 數據緩衝區
    ufiCmdRunning.state = UFI_STATE_BEGIN;      // 初始狀態

    // 通過 Bulk 端點發送寫命令
    bulkWrite((unsigned char *)&ufiCmdRunning.cbw,
              buf,
              (unsigned char *)&ufiCmdRunning.csw);

    return 0;
}

關鍵數據結構說明

CBW (Command Block Wrapper)

Bulk-Only 協議規定的命令塊包裝結構,包含簽名、標籤、傳輸長度、方向標誌、LUN、CDB 長度及 CDB 本體。

WRITE_10 CDB (Command Descriptor Block)

SCSI WRITE_10 命令結構,OperationCode 0x2A 表示寫入 10 位元組 CDB 格式。LBA 為 4 位元組大端序扇區地址,傳輸長度為 2 位元組扇區計數。

流程要點

  1. 構建 CBW:填充固定簽名、唯一 Tag、數據長度 512、方向 Out、LUN 0、CDB 長度 16。
  2. 構建 CDB:OperationCode 0x2A,將 32 位 LBA 拆分為 4 字節大端序,扇區數設為 1。
  3. 註冊回調:指定批量寫入處理函數 bulkWrite、數據緩衝區、初始狀態。
  4. 發起傳輸:調用 bulkWrite 發送 CBW、數據階段、接收 CSW 的完整 Bulk 事務。

注意事項

  • byteInInt 為輔助宏/函數,用於從 32 位整數提取指定位元組(大端序)。
  • 實際傳輸由 bulkWrite 異步處理,包含 CBW 傳輸、數據傳輸、CSW 接收三個階段,中斷處理程序負責狀態機推進。
  • 錯誤處理(如 STALL、CRC 錯誤、CSW 狀態非 0)在 bulkWrite 及中斷處理中實現,此處略去。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved