2.11. ioctls CEC_RECEIVE 和 CEC_TRANSMIT¶
2.11.1. 名稱¶
CEC_RECEIVE, CEC_TRANSMIT - 接收或傳送 CEC 訊息
2.11.2. 概要¶
-
CEC_RECEIVE¶
int ioctl(int fd, CEC_RECEIVE, struct cec_msg *argp)
-
CEC_TRANSMIT¶
int ioctl(int fd, CEC_TRANSMIT, struct cec_msg *argp)
2.11.3. 引數¶
fdopen()返回的檔案描述符。argp指向
struct cec_msg的指標。
2.11.4. 描述¶
要接收 CEC 訊息,應用程式必須填寫 struct cec_msg 的 timeout 欄位,並將其傳遞給 ioctl CEC_RECEIVE。如果檔案描述符處於非阻塞模式,並且沒有待處理的已接收訊息,則它將返回 -1 並將 errno 設定為 EAGAIN 錯誤程式碼。如果檔案描述符處於阻塞模式,並且 timeout 為非零,並且在 timeout 毫秒內沒有訊息到達,則它將返回 -1 並將 errno 設定為 ETIMEDOUT 錯誤程式碼。
接收到的訊息可以是
從另一個 CEC 裝置接收的訊息(
sequence欄位將為 0,tx_status將為 0,rx_status將為非零)。先前非阻塞傳輸的傳輸結果(
sequence欄位將為非零,tx_status將為非零,rx_status將為 0)。先前非阻塞傳輸的回覆(
sequence欄位將為非零,tx_status將為 0,rx_status將為非零)。
要傳送 CEC 訊息,應用程式必須填寫 struct cec_msg,並將其傳遞給 ioctl CEC_TRANSMIT。僅當設定了 CEC_CAP_TRANSMIT 時,ioctl CEC_TRANSMIT 才可用。如果傳輸佇列中沒有更多空間,則它將返回 -1 並將 errno 設定為 EBUSY 錯誤程式碼。傳輸佇列有足夠的空間容納 18 條訊息(大約 1 秒的 2 位元組訊息)。請注意,CEC 核心框架也會回覆核心訊息(請參閱 核心訊息處理),因此完全填滿傳輸佇列並不是一個好主意。
如果檔案描述符處於非阻塞模式,則傳輸將返回 0,並且一旦傳輸完成,就可以透過 ioctl CEC_RECEIVE 獲得傳輸結果。如果非阻塞傳輸還指定了等待回覆,則回覆將在稍後的訊息中到達。sequence 欄位可用於將傳輸結果和回覆與原始傳輸相關聯。
通常,當物理地址無效時(例如,由於斷開連線),呼叫 ioctl CEC_TRANSMIT 將返回 ENONET。
但是,CEC 規範允許在物理地址無效時從“未註冊”向“電視”傳送訊息,因為某些電視在進入待機狀態或切換到另一個輸入時會將 HDMI 聯結器的熱插拔檢測引腳拉低。
當熱插拔檢測引腳變為低電平時,EDID 消失,因此物理地址也消失,但電纜仍然連線並且 CEC 仍然有效。為了檢測/喚醒裝置,允許從發起者 0xf(“未註冊”)向目標 0(“電視”)傳送輪詢和“影像/文字檢視開啟”訊息。
-
type cec_msg¶
__u64 |
|
訊息的最後一個位元組被傳輸時的納秒時間戳。時間戳取自 |
__u64 |
|
訊息的最後一個位元組被接收時的納秒時間戳。時間戳取自 |
__u32 |
|
訊息的長度。對於 ioctl CEC_TRANSMIT,這由應用程式填寫。驅動程式將為 ioctl CEC_RECEIVE 填寫此項。對於 ioctl CEC_TRANSMIT,如果設定了 |
__u32 |
|
以毫秒為單位的超時時間。這是裝置在超時之前等待接收訊息的時間。如果將其設定為 0,則當透過 ioctl CEC_RECEIVE 呼叫時,它將無限期地等待。如果它為 0 並且透過 ioctl CEC_TRANSMIT 呼叫,則如果 |
__u32 |
|
CEC 框架會自動為所有傳輸的訊息分配一個非零序列號。當 CEC 框架為非阻塞傳輸排隊傳輸結果時,會使用此序列號。這允許應用程式將接收到的訊息與原始傳輸相關聯。 此外,如果非阻塞傳輸將等待回覆(即 |
__u32 |
|
標誌。有關可用標誌的列表,請參閱 struct cec_msg 的標誌。 |
__u8 |
|
訊息有效負載。對於 ioctl CEC_TRANSMIT,這由應用程式填寫。驅動程式將為 ioctl CEC_RECEIVE 填寫此項。對於 ioctl CEC_TRANSMIT,如果設定了 |
__u8 |
|
等待直到此訊息被回覆。如果 如果發射器訊息為 |
__u8 |
|
接收到的訊息的狀態位。有關可能的狀態值,請參閱 CEC 接收狀態。 |
__u8 |
|
傳輸的訊息的狀態位。有關可能的狀態值,請參閱 CEC 傳輸狀態。在非阻塞模式下呼叫 ioctl CEC_TRANSMIT 時,如果傳輸已啟動,則此欄位將為 0;如果立即知道傳輸結果,則此欄位將為非 0。嘗試向自己傳輸 Poll 訊息時就是後一種情況。這會導致 CEC_TX_STATUS_NACK,而無需實際傳輸 Poll 訊息。 |
__u8 |
|
導致 Arbitration Lost 錯誤的傳輸嘗試次數的計數器。僅當硬體支援此功能時才會設定此值,否則始終為 0。僅當設定了 CEC_TX_STATUS_ARB_LOST 狀態位時,此計數器才有效。 |
__u8 |
|
導致 Not Acknowledged 錯誤的傳輸嘗試次數的計數器。僅當硬體支援此功能時才會設定此值,否則始終為 0。僅當設定了 CEC_TX_STATUS_NACK 狀態位時,此計數器才有效。 |
__u8 |
|
導致 Arbitration Lost 錯誤的傳輸嘗試次數的計數器。僅當硬體支援此功能時才會設定此值,否則始終為 0。僅當設定了 CEC_TX_STATUS_LOW_DRIVE 狀態位時,此計數器才有效。 |
__u8 |
|
Arbitration Lost 或 Not Acknowledged 之外的傳輸錯誤數量的計數器。僅當硬體支援此功能時才會設定此值,否則始終為 0。僅當設定了 CEC_TX_STATUS_ERROR 狀態位時,此計數器才有效。 |
|
1 |
如果 CEC 傳輸期望回覆,則預設情況下,該回復僅傳送到呼叫 ioctl CEC_TRANSMIT 的檔案控制代碼。如果設定了此標誌,則回覆也會發送到所有關注者(如果有)。如果呼叫 ioctl CEC_TRANSMIT 的檔案控制代碼也是關注者,則該檔案控制代碼將收到兩次回覆:一次作為 ioctl CEC_TRANSMIT 的結果,一次透過 ioctl CEC_RECEIVE。 |
|
2 |
通常,CEC 訊息在傳輸之前會進行驗證。如果在呼叫 ioctl CEC_TRANSMIT 時設定了此標誌,則不會進行驗證,並且訊息將按原樣傳輸。這在除錯 CEC 問題時很有用。只有程序具有 |
|
4 |
僅當設定了 請注意,這假設 Vendor ID 之後的位元組是供應商特定的操作碼。 此標誌使等待供應商命令的回覆變得更容易。 |
|
0x01 |
訊息已成功傳輸。這與 CEC_TX_STATUS_MAX_RETRIES 互斥。如果在傳輸最終成功之前,先前的嘗試遇到失敗,則仍然可以設定其他位。 |
|
0x02 |
CEC 線仲裁丟失,即另一個傳輸以更高的優先順序同時啟動。可選狀態,並非所有硬體都可以檢測到此錯誤情況。 |
|
0x04 |
訊息未被確認。請注意,某些硬體無法區分“未確認”狀態與其他錯誤情況,即傳輸結果僅為 OK 或 FAIL。在這種情況下,當傳輸失敗時將返回此狀態。 |
|
0x08 |
在 CEC 總線上檢測到低驅動。這表明關注者檢測到總線上存在錯誤,並請求重新傳輸。可選狀態,並非所有硬體都可以檢測到此錯誤情況。 |
|
0x10 |
發生了一些錯誤。這用於不適合 |
|
0x20 |
一次或多次重試後傳輸失敗。此狀態位與 CEC_TX_STATUS_OK 互斥。仍然可以設定其他位來解釋看到了哪些失敗。 |
|
0x40 |
由於 HDMI 斷開連線,或者介面卡已取消配置,或者傳輸已中斷,或者驅動程式在嘗試啟動傳輸時返回了錯誤,因此傳輸已中止。 |
|
0x80 |
傳輸超時。這通常不應該發生,並且這表明驅動程式存在問題。 |
|
0x01 |
訊息已成功接收。 |
|
0x02 |
先前傳輸的訊息的回覆超時。 |
|
0x04 |
訊息已成功接收,但回覆為 |
|
0x08 |
由於 HDMI 電纜已斷開連線,或者介面卡已取消配置,或者等待回覆的 CEC_TRANSMIT 已中斷,因此等待先前傳輸的訊息的回覆已中止。 |
2.11.5. 返回值¶
成功時返回 0,錯誤時返回 -1,並適當設定 errno 變數。通用錯誤程式碼在 通用錯誤程式碼 章節中描述。
ioctl CEC_RECEIVE 可以返回以下錯誤程式碼
- EAGAIN
接收佇列中沒有訊息,並且檔案控制代碼處於非阻塞模式。
- ETIMEDOUT
在等待訊息時達到
timeout。- ERESTARTSYS
等待訊息被中斷(例如,透過 Ctrl-C)。
ioctl CEC_TRANSMIT 可以返回以下錯誤程式碼
- ENOTTY
未設定
CEC_CAP_TRANSMIT功能,因此不支援此 ioctl。- EPERM
CEC 介面卡未配置,即從未呼叫 ioctl CEC_ADAP_S_LOG_ADDRS,或者從沒有
CAP_SYS_RAWIO功能的程序使用了CEC_MSG_FL_RAW。- ENONET
CEC 介面卡未配置,即已呼叫 ioctl CEC_ADAP_S_LOG_ADDRS,但是物理地址無效,因此未宣告邏輯地址。在這種情況下,從發起者 0xf(“未註冊”)到目標 0(“電視”)的傳輸是一個例外。在這種情況下,傳輸將照常進行。
- EBUSY
另一個檔案控制代碼處於獨佔關注者或發起者模式,或者檔案控制代碼處於模式
CEC_MODE_NO_INITIATOR。如果傳輸佇列已滿,也會返回此值。- EINVAL
struct
cec_msg的內容無效。- ERESTARTSYS
等待成功傳輸被中斷(例如,透過 Ctrl-C)。