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. 参数¶
fd
由
open()
返回的文件描述符。argp
指向
struct cec_msg
的指针。
2.11.4. 描述¶
要接收 CEC 消息,应用程序必须填写结构体 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 消息,应用程序必须填写结构体 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 规范允许在物理地址无效时从“未注册”向“TV”发送消息,因为某些电视在进入待机状态或切换到其他输入时会将其 HDMI 连接器的热插拔检测引脚拉低。
当热插拔检测引脚变低时,EDID 消失,因此物理地址也消失,但电缆仍然连接,并且 CEC 仍然有效。为了检测/唤醒设备,允许从发起者 0xf(“未注册”)向目标 0(“TV”)发送轮询和“图像/文本视图开启”消息。
-
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 |
|
导致仲裁丢失错误的传输尝试次数计数器。仅当硬件支持此功能时才会设置此计数器,否则始终为 0。此计数器仅当设置了 CEC_TX_STATUS_ARB_LOST 状态位时才有效。 |
__u8 |
|
导致未确认错误的传输尝试次数计数器。仅当硬件支持此功能时才会设置此计数器,否则始终为 0。此计数器仅当设置了 CEC_TX_STATUS_NACK 状态位时才有效。 |
__u8 |
|
导致仲裁丢失错误的传输尝试次数计数器。仅当硬件支持此功能时才会设置此计数器,否则始终为 0。此计数器仅当设置了 CEC_TX_STATUS_LOW_DRIVE 状态位时才有效。 |
__u8 |
|
除仲裁丢失或未确认之外的其他传输错误的计数器。仅当硬件支持此功能时才会设置此计数器,否则始终为 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 |
仅当设置了 请注意,这假定供应商 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,或者
CEC_MSG_FL_RAW
是从没有CAP_SYS_RAWIO
功能的进程中使用的。- ENONET
CEC 适配器未配置,即调用了 ioctl CEC_ADAP_S_LOG_ADDRS,但物理地址无效,因此没有声明逻辑地址。在这种情况下,从发起者 0xf(“未注册”)到目标 0(“电视”)的传输是一个例外。在这种情况下,传输将照常进行。
- EBUSY
另一个文件句柄处于独占关注者或发起者模式,或者文件句柄处于
CEC_MODE_NO_INITIATOR
模式。如果传输队列已满,也会返回此错误。- EINVAL
struct
cec_msg
的内容无效。- ERESTARTSYS
等待成功传输被中断(例如,通过 Ctrl-C)。