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 消息,应用程序必须填写 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)。