3. CEC 引腳框架錯誤注入

CEC 引腳框架是核心 CEC 框架,適用於僅對 CEC 匯流排具有底層支援的 CEC 硬體。如今,大多數硬體都將具有高階 CEC 支援,硬體負責驅動 CEC 匯流排,但一些較舊的裝置沒有那麼高階。但是,此框架還允許您將 CEC 引腳連線到例如 Raspberry Pi 上的 GPIO,並且您現在已經制作了一個 CEC 介面卡。

這樣做如此有趣的原因是,由於我們可以完全控制匯流排,因此很容易支援錯誤注入。這非常適合測試 CEC 介面卡處理錯誤情況的能力。

目前只有 cec-gpio 驅動程式(當 CEC 線直接連線到上拉 GPIO 線時)和 AllWinner A10/A20 drm 驅動程式支援此框架。

如果啟用了 CONFIG_CEC_PIN_ERROR_INJ,則可以透過 debugfs 進行錯誤注入。具體來說,在 /sys/kernel/debug/cec/cecX/ 中現在有一個 error-inj 檔案。

注意

錯誤注入命令不是穩定的 ABI,將來可能會發生變化。

使用 cat error-inj,您可以檢視可能的命令和當前的錯誤注入狀態

$ cat /sys/kernel/debug/cec/cec0/error-inj
# Clear error injections:
#   clear          clear all rx and tx error injections
#   rx-clear       clear all rx error injections
#   tx-clear       clear all tx error injections
#   <op> clear     clear all rx and tx error injections for <op>
#   <op> rx-clear  clear all rx error injections for <op>
#   <op> tx-clear  clear all tx error injections for <op>
#
# RX error injection:
#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK
#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position
#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message
#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message
#    any[,<mode>] rx-arb-lost [<poll>] generate a POLL message to trigger an arbitration lost
#
# TX error injection settings:
#   tx-ignore-nack-until-eom           ignore early NACKs until EOM
#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse
#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse
#   tx-custom-pulse                    transmit the custom pulse once the bus is idle
#
# TX error injection:
#   <op>[,<mode>] tx-no-eom            don't set the EOM bit
#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon
#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message
#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message
#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed
#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed
#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit
#   <op>[,<mode>] tx-short-start       send a start pulse that's too short
#   <op>[,<mode>] tx-long-start        send a start pulse that's too long
#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse
#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit
#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position
#
# <op>       CEC message opcode (0-255) or 'any'
# <mode>     'once' (default), 'always', 'toggle' or 'off'
# <bit>      CEC message bit (0-159)
#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK
# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)
# <usecs>    microseconds (0-10000000, default 1000)

clear

您可以使用 echo 'cmd' >error-injcat cmd.txt >error-inj 將錯誤注入命令寫入 error-injcat error-inj 輸出包含當前的錯誤命令。您可以將輸出儲存到檔案中,稍後將其用作 error-inj 的輸入。

3.1. 基本語法

前導空格/製表符將被忽略。如果下一個字元是 # 或到達行尾,則將忽略整行。否則,將需要一個命令。

錯誤注入命令分為兩個主要組:與接收 CEC 訊息相關的命令和與傳送 CEC 訊息相關的命令。此外,還有一些命令可以清除現有的錯誤注入命令,並在 CEC 總線上建立自定義脈衝。

大多數錯誤注入命令可以針對特定的 CEC 操作碼或所有操作碼 (any) 執行。每個命令還具有一個“模式”,可以是 off(可用於關閉現有的錯誤注入命令)、once(預設值),它將僅針對下一個接收或傳送的訊息觸發一次錯誤注入,always 將始終觸發錯誤注入,toggle 將為每次傳送或接收開啟或關閉錯誤注入。

因此,'any rx-nack' 將 NACK 下一個接收到的 CEC 訊息,'any,always rx-nack' 將 NACK 所有接收到的 CEC 訊息,'0x82,toggle rx-nack' 僅當收到 Active Source 訊息時才會 NACK,並且僅對每隔一個接收到的訊息執行此操作。

在以 once 模式注入錯誤後,錯誤注入命令將自動清除,因此 once 是一次性交易。

<op> 和錯誤注入命令的所有組合都可以共存。所以這是沒問題的

0x9e tx-add-bytes 1
0x9e tx-early-eom
0x9f tx-add-bytes 2
any rx-nack

所有四個錯誤注入命令將同時處於活動狀態。

但是,如果指定了相同的 <op> 和命令組合,但具有不同的引數

0x9e tx-add-bytes 1
0x9e tx-add-bytes 2

那麼第二個將覆蓋第一個。

3.2. 清除錯誤注入

clear

清除所有錯誤注入。

rx-clear

清除所有接收錯誤注入

tx-clear

清除所有傳送錯誤注入

<op> clear

清除給定操作碼的所有錯誤注入。

<op> rx-clear

清除給定操作碼的所有接收錯誤注入。

<op> tx-clear

清除給定操作碼的所有傳送錯誤注入。

3.3. 接收訊息

<op>[,<mode>] rx-nack

NACK 廣播訊息和定向到此 CEC 介面卡的訊息。如果傳送器在第一個位元組被 NACK 後繼續傳送,則訊息的每個位元組都將被 NACK。

<op>[,<mode>] rx-low-drive <bit>

在此位位置強制執行 Low Drive 條件。如果 <op> 指定特定的 CEC 操作碼,則該位位置必須至少為 18,否則尚未收到該操作碼。這將測試傳送器是否可以正確處理 Low Drive 條件並正確報告錯誤。請注意,傳送器也可以將前 4 位中的 Low Drive 解釋為 Arbitration Lost 條件。這是與實現相關的。

<op>[,<mode>] rx-add-byte

向接收到的 CEC 訊息新增一個偽造的 0x55 位元組,前提是訊息長度為 15 個位元組或更少。這對於測試高階協議很有用,因為應該忽略偽造位元組。

<op>[,<mode>] rx-remove-byte

從接收到的 CEC 訊息中刪除最後一個位元組,前提是該訊息至少為 2 個位元組長。這對於測試高階協議很有用,因為應忽略太短的訊息。

<op>[,<mode>] rx-arb-lost <poll>

生成 POLL 訊息以觸發 Arbitration Lost 條件。此命令僅允許用於 <op> 值為 nextall。一旦收到起始位,CEC 介面卡將切換到傳送模式,併發送一個 POLL 訊息。預設情況下,這是 0x0f,但也可以透過 <poll> 引數顯式指定。

此命令可用於測試遠端 CEC 傳送器中的 Arbitration Lost 條件。當兩個 CEC 介面卡同時開始傳送訊息時,會發生仲裁。在這種情況下,前導零最多的發起者獲勝,另一個傳送器必須停止傳送(“Arbitration Lost”)。這很難測試,除非使用此錯誤注入命令。

如果遠端 CEC 傳送器的邏輯地址為 0 (“TV”),則此命令不起作用,因為它將始終獲勝。

3.4. 傳送訊息

tx-ignore-nack-until-eom

此設定更改了傳送 CEC 訊息的行為。通常,一旦接收器 NACK 一個位元組,傳送就會停止,但規範也允許傳送完整的訊息,並且只有在最後,傳送器才會檢視 ACK 位。不建議這樣做,因為沒有必要使 CEC 匯流排佔用時間超過嚴格所需的長度。尤其是考慮到匯流排的速度有多慢。

此設定可用於測試接收器如何處理忽略 NACK 直到訊息結尾的傳送器。

<op>[,<mode>] tx-no-eom

不要設定 EOM 位。通常,訊息的最後一個位元組設定了 EOM(訊息結束)位。使用此命令,傳送將停止,而不會發送 EOM。這可用於測試接收器如何處理這種情況。通常,接收器有一個超時時間,在此之後它們將返回到空閒狀態。

<op>[,<mode>] tx-early-eom

提前一個位元組設定 EOM 位。這顯然僅適用於兩個或多個位元組的訊息。EOM 位將為倒數第二個位元組設定,而不是為最後一個位元組設定。在這種情況下,接收器應忽略最後一個位元組。由於生成的訊息可能由於同樣的理由而太短,因此通常會忽略整個訊息。接收器在傳送最後一個位元組後應處於空閒狀態。

<op>[,<mode>] tx-add-bytes <num>

<num> (1-255) 個偽造位元組附加到訊息。額外的位元組的值是訊息中的位元組位置。因此,如果您傳送一個兩位元組的訊息(例如,一個 Get CEC Version 訊息)並新增 2 個位元組,則遠端 CEC 介面卡接收到的完整訊息是 0x40 0x9f 0x02 0x03

此命令可用於測試接收器中的緩衝區溢位。例如,當它收到超過最大訊息大小 16 個位元組時,它會做什麼。

<op>[,<mode>] tx-remove-byte

從訊息中刪除最後一個位元組,前提是該訊息至少為兩個位元組長。接收器應忽略太短的訊息。

<op>[,<mode>] tx-short-bit <bit>

使此位週期短於允許的長度。位位置不能是 Ack 位。如果 <op> 指定特定的 CEC 操作碼,則該位位置必須至少為 18,否則尚未收到該操作碼。通常,資料位的週期在 2.05 到 2.75 毫秒之間。使用此命令,此位的週期為 1.8 毫秒,這是透過減少 CEC 匯流排處於高電平的時間來完成的。此位週期小於允許的長度,接收器應以 Low Drive 條件響應。

對於位位置 0 到 3 中的 0 位,此命令將被忽略。這是因為接收器還在前四位中查詢 Arbitration Lost 條件,並且如果它看到一個太短的 0 位,會發生什麼情況是未定義的。

<op>[,<mode>] tx-long-bit <bit>

使此位週期長於有效週期。位位置不能是 Ack 位。如果 <op> 指定特定的 CEC 操作碼,則該位位置必須至少為 18,否則尚未收到該操作碼。通常,資料位的週期在 2.05 到 2.75 毫秒之間。使用此命令,此位的週期為 2.9 毫秒,這是透過增加 CEC 匯流排處於高電平的時間來完成的。

即使此位週期長於有效週期,接收器會做什麼也是未定義的。它可能只是接受它,或者它可能會超時並返回到空閒狀態。不幸的是,CEC 規範對此保持沉默。

對於位位置 0 到 3 中的 0 位,此命令將被忽略。這是因為接收器還在前四位中查詢 Arbitration Lost 條件,並且如果它看到一個太長的 0 位,會發生什麼情況是未定義的。

<op>[,<mode>] tx-short-start

使此起始位週期短於允許的長度。通常,起始位的週期在 4.3 到 4.7 毫秒之間。使用此命令,起始位的週期為 4.1 毫秒,這是透過減少 CEC 匯流排處於高電平的時間來完成的。此起始位週期小於允許的長度,當檢測到此情況時,接收器應返回到空閒狀態。

<op>[,<mode>] tx-long-start

使此起始位週期長於有效週期。通常,起始位的週期在 4.3 到 4.7 毫秒之間。使用此命令,起始位的週期為 5 毫秒,這是透過增加 CEC 匯流排處於高電平的時間來完成的。此起始位週期大於有效週期,當檢測到此情況時,接收器應返回到空閒狀態。

即使此起始位週期長於有效週期,接收器會做什麼也是未定義的。它可能只是接受它,或者它可能會超時並返回到空閒狀態。不幸的是,CEC 規範對此保持沉默。

<op>[,<mode>] tx-last-bit <bit>

在此位之後停止傳送。如果 <op> 指定特定的 CEC 操作碼,則該位位置必須至少為 18,否則尚未收到該操作碼。此命令可用於測試當訊息突然停止時接收器如何反應。它應該超時並返回到空閒狀態。

<op>[,<mode>] tx-low-drive <bit>

在此位位置強制執行 Low Drive 條件。如果 <op> 指定特定的 CEC 操作碼,則該位位置必須至少為 18,否則尚未收到該操作碼。這可用於測試接收器如何處理 Low Drive 條件。請注意,如果這發生在位位置 0-3 處,則接收器可以將此解釋為 Arbitration Lost 條件。這是與實現相關的。

3.5. 自定義脈衝

tx-custom-low-usecs <usecs>

這定義了自定義脈衝將 CEC 線拉低的持續時間,以微秒為單位。預設值為 1000 微秒。

tx-custom-high-usecs <usecs>

這定義了自定義脈衝保持 CEC 線高電平的持續時間,以微秒為單位(除非另一個 CEC 介面卡在該時間內將其拉低)。預設值為 1000 微秒。自定義脈衝的總週期為 tx-custom-low-usecs + tx-custom-high-usecs

<op>[,<mode>] tx-custom-bit <bit>

傳送自定義位而不是常規資料位。位位置不能是 Ack 位。如果 <op> 指定特定的 CEC 操作碼,則該位位置必須至少為 18,否則尚未收到該操作碼。

<op>[,<mode>] tx-custom-start

傳送自定義位而不是常規起始位。

tx-custom-pulse

一旦 CEC 匯流排空閒,就傳送一個自定義脈衝。