UCAN 協議

UCAN 是基於微控制器的 USB-CAN 介面卡使用的協議,該介面卡整合在 Theobroma Systems 的片上系統模組上,並且也可以作為獨立的 USB 棒使用。

UCAN 協議的設計與硬體無關。 它的建模方式與 Linux 在內部表示 CAN 裝置的方式非常接近。 所有多位元組整數都編碼為小端序。

本文件中提到的所有結構都在 drivers/net/can/usb/ucan.c 中定義。

USB 端點

UCAN 裝置使用三個 USB 端點

CONTROL 端點

驅動程式在此端點上傳送裝置管理命令

IN 端點

裝置傳送 CAN 資料幀和 CAN 錯誤幀

OUT 端點

驅動程式在 out 端點上傳送 CAN 資料幀

CONTROL 訊息

UCAN 裝置使用控制管道上的 vendor request 進行配置。

為了在單個 USB 裝置中支援多個 CAN 介面,所有配置命令都以 USB 描述符中相應的介面為目標。

驅動程式使用 ucan_ctrl_command_in/outucan_device_request_in 將命令傳遞給裝置。

Setup Packet

bmRequestType

方向 | 供應商 | (介面或裝置)

bRequest

命令編號

wValue

子命令編號 (16 位) 或 0 (如果未使用)

wIndex

USB 介面索引 (裝置命令為 0)

wLength

  • 主機到裝置 - 要傳輸的位元組數

  • 裝置到主機 - 要接收的最大位元組數。 如果裝置傳送的較少,則使用常見的 ZLP 語義。

錯誤處理

裝置透過暫停管道來指示失敗的控制命令。

裝置命令

UCAN_DEVICE_GET_FW_STRING

Dev2Host;可選

請求裝置韌體字串。

介面命令

UCAN_COMMAND_START

Host2Dev;強制

啟動 CAN 介面。

Payload 格式

ucan_ctl_payload_t.cmd_start

mode

UCAN_MODE_* 的掩碼

UCAN_COMMAND_STOP

Host2Dev;強制

停止 CAN 介面

Payload 格式

UCAN_COMMAND_RESET

Host2Dev;強制

重置 CAN 控制器 (包括錯誤計數器)

Payload 格式

UCAN_COMMAND_GET

Host2Dev;強制

從裝置獲取資訊

子命令
UCAN_COMMAND_GET_INFO

請求裝置資訊結構 ucan_ctl_payload_t.device_info

有關詳細資訊,請參見 device_info 欄位,有關 can_bittiming fields 的說明,請參見 uapi/linux/can/netlink.h

Payload 格式

ucan_ctl_payload_t.device_info

UCAN_COMMAND_GET_PROTOCOL_VERSION

請求裝置協議版本 ucan_ctl_payload_t.protocol_version。 當前協議版本為 3。

Payload 格式

ucan_ctl_payload_t.protocol_version

注意

未實現此命令的裝置使用舊協議版本 1

UCAN_COMMAND_SET_BITTIMING

Host2Dev;強制

透過傳送結構 ucan_ctl_payload_t.cmd_set_bittiming 設定 bittiming (有關詳細資訊,請參見 struct bittiming)

Payload 格式

ucan_ctl_payload_t.cmd_set_bittiming.

UCAN_SLEEP/WAKE

Host2Dev;可選

配置睡眠和喚醒模式。 驅動程式尚不支援。

UCAN_FILTER

Host2Dev;可選

設定硬體 CAN 過濾器。 驅動程式尚不支援。

允許的介面命令

合法裝置狀態

命令

新裝置狀態

已停止

SET_BITTIMING

已停止

已停止

START

已啟動

已啟動

STOP 或 RESET

已停止

已停止

STOP 或 RESET

已停止

已啟動

RESTART

已啟動

任何

GET

無變化

IN 訊息格式

USB IN 端點上的資料包包含一個或多個 ucan_message_in 值。 如果多個訊息批次處理到 USB 資料包中,則可以使用 len 欄位跳轉到下一個 ucan_message_in 值(請注意針對實際資料大小對 len 值進行完整性檢查)。

len 欄位

每個 ucan_message_in 必須與 4 位元組邊界對齊(相對於資料緩衝區的起始位置)。 這意味著多個 ucan_message_in 值之間可能存在填充位元組

+----------------------------+ < 0
|                            |
|   struct ucan_message_in   |
|                            |
+----------------------------+ < len
          [padding]
+----------------------------+ < round_up(len, 4)
|                            |
|   struct ucan_message_in   |
|                            |
+----------------------------+
            [...]

type 欄位

type 欄位指定訊息的型別。

UCAN_IN_RX

subtype

從 CAN 匯流排接收的資料 (ID + payload)。

UCAN_IN_TX_COMPLETE

subtype

CAN 裝置已將訊息傳送到 CAN 匯流排。 它使用元組 <echo-ids, flags> 的列表進行回覆。

echo-id 從 (從先前的 UCAN_OUT_TX 訊息回顯 id) 標識幀。 該標誌指示傳輸的結果。 設定的位 0 表示成功。 所有其他位均保留並設定為零。

流量控制

接收 CAN 訊息時,USB 緩衝區上沒有流量控制。 驅動程式必須足夠快地處理入站訊息,以避免丟棄。 在裝置緩衝區溢位的情況下,會透過傳送相應的錯誤幀來報告該情況 (請參見 CAN 錯誤處理)

OUT 訊息格式

USB OUT 端點上的資料包包含一個或多個 struct ucan_message_out 值。 如果將多個訊息批次處理到一個數據包中,則裝置使用 len 欄位跳轉到下一個 ucan_message_out 值。 每個 ucan_message_out 必須與 4 位元組對齊 (相對於資料緩衝區的起始位置)。 該機制與 len 欄位 中描述的相同。

+----------------------------+ < 0
|                            |
|   struct ucan_message_out  |
|                            |
+----------------------------+ < len
          [padding]
+----------------------------+ < round_up(len, 4)
|                            |
|   struct ucan_message_out  |
|                            |
+----------------------------+
            [...]

type 欄位

在協議版本 3 中,僅定義了 UCAN_OUT_TX,其他協議僅由舊裝置 (協議版本 1) 使用。

UCAN_OUT_TX

subtype

要在 CAN_IN_TX_COMPLETE 訊息中回覆的 echo id

傳輸 CAN 幀。 (引數: id, data)

流量控制

當裝置出站緩衝區已滿時,它會在 OUT 管道上開始傳送 NAK,直到有更多緩衝區可用為止。 當一定數量的 out 資料包不完整時,驅動程式會停止佇列。

CAN 錯誤處理

如果啟用了錯誤報告,則裝置會將錯誤編碼為 CAN 錯誤幀 (請參見 uapi/linux/can/error.h),並使用 IN 端點發送它。 驅動程式更新其錯誤統計資訊並轉發它。

儘管 UCAN 裝置可以完全禁止錯誤幀,但在 Linux 中,驅動程式始終對此感興趣。 因此,裝置始終以設定的 UCAN_MODE_BERR_REPORT 啟動。 為使用者空間過濾這些訊息由驅動程式完成。

匯流排 OFF

  • 裝置不會自動從匯流排關閉中恢復。

  • 匯流排 OFF 由錯誤幀指示 (請參見 uapi/linux/can/error.h)

  • 匯流排 OFF 恢復由 UCAN_COMMAND_RESTART 啟動

  • 匯流排 OFF 恢復完成後,裝置會發送一個錯誤幀,指示它處於 ERROR-ACTIVE 狀態。

  • 在匯流排 OFF 期間,裝置不會發送任何幀。

  • 在匯流排 OFF 期間,來自主機的傳輸請求會立即完成,而成功位保持未設定狀態。

示例對話

  1. 裝置已連線到 USB

  2. 主機發送命令 UCAN_COMMAND_RESET,子命令 0

  3. 主機發送命令 UCAN_COMMAND_GET,子命令 UCAN_COMMAND_GET_INFO

  4. 裝置傳送 UCAN_IN_DEVICE_INFO

  5. 主機發送命令 UCAN_OUT_SET_BITTIMING

  6. 主機發送命令 UCAN_COMMAND_START,子命令 0,模式 UCAN_MODE_BERR_REPORT