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-inj
或 cat cmd.txt >error-inj
将错误注入命令写入 error-inj
。 cat 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
' 仅在接收到活动源消息时才会 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>
在此位位置强制执行低驱动条件。如果
<op>
指定特定的 CEC 操作码,则位位置必须至少为 18,否则尚未接收到该操作码。这将测试发送器是否可以正确处理低驱动条件并正确报告错误。请注意,发送器也可能将前 4 位中的低驱动解释为仲裁丢失条件。这取决于具体实现。<op>[,<mode>] rx-add-byte
将一个虚假的 0x55 字节添加到接收到的 CEC 消息中,前提是该消息的长度为 15 个字节或更短。这有助于测试高层协议,因为应该忽略虚假字节。
<op>[,<mode>] rx-remove-byte
从接收到的 CEC 消息中删除最后一个字节,前提是该消息的长度至少为 2 个字节。这有助于测试高层协议,因为应该忽略太短的消息。
<op>[,<mode>] rx-arb-lost <poll>
生成一个 POLL 消息以触发仲裁丢失条件。此命令仅允许用于
<op>
值为next
或all
。只要收到起始位,CEC 适配器就会切换到发送模式,并发送一个 POLL 消息。默认情况下为 0x0f,但也可以通过<poll>
参数显式指定。此命令可用于测试远程 CEC 发送器中的仲裁丢失条件。当两个 CEC 适配器同时开始发送消息时会发生仲裁。在这种情况下,具有最多前导零的启动器获胜,而另一个发送器必须停止发送(“仲裁丢失”)。除了使用此错误注入命令外,很难对此进行测试。
如果远程 CEC 发送器的逻辑地址为 0(“电视”),则此方法不起作用,因为它始终会获胜。
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) 个虚假字节附加到消息。额外的字节具有消息中字节位置的值。因此,如果发送两个字节的消息(例如,获取 CEC 版本消息)并添加 2 个字节,则远程 CEC 适配器接收到的完整消息为0x40 0x9f 0x02 0x03
。此命令可用于测试接收器中的缓冲区溢出。例如,当接收到的消息超过 16 个字节的最大消息大小时会发生什么。
<op>[,<mode>] tx-remove-byte
从消息中删除最后一个字节,前提是该消息的长度至少为两个字节。接收器应忽略太短的消息。
<op>[,<mode>] tx-short-bit <bit>
使该位周期比允许的短。该位的位置不能是应答位。如果 <op> 指定了特定的 CEC 操作码,则该位的位置必须至少为 18,否则尚未收到操作码。通常,数据位的周期在 2.05 到 2.75 毫秒之间。使用此命令,该位的周期为 1.8 毫秒,这是通过减少 CEC 总线保持高电平的时间来实现的。此位周期小于允许值,接收器应以低驱动条件响应。
对于位位置 0 到 3 中的 0 位,此命令将被忽略。这是因为接收器也会在前四个位中寻找仲裁丢失条件,并且如果它看到一个太短的 0 位,则会发生什么是不确定的。
<op>[,<mode>] tx-long-bit <bit>
使该位周期比有效值长。该位的位置不能是应答位。如果 <op> 指定了特定的 CEC 操作码,则该位的位置必须至少为 18,否则尚未收到操作码。通常,数据位的周期在 2.05 到 2.75 毫秒之间。使用此命令,该位的周期为 2.9 毫秒,这是通过增加 CEC 总线保持高电平的时间来实现的。
即使此位周期比有效值长,接收器将执行什么操作也是不确定的。它可能只是接受它,也可能超时并返回到空闲状态。不幸的是,CEC 规范对此保持沉默。
对于位位置 0 到 3 中的 0 位,此命令将被忽略。这是因为接收器也会在前四个位中寻找仲裁丢失条件,并且如果它看到一个太长的 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>
在此位位置强制执行低驱动条件。如果 <op> 指定了特定的 CEC 操作码,则该位的位置必须至少为 18,否则尚未收到操作码。这可用于测试接收器如何处理低驱动条件。请注意,如果这种情况发生在位位置 0-3,则接收器可以将其解释为仲裁丢失条件。这取决于具体实现。
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>
发送自定义位而不是常规数据位。该位的位置不能是应答位。如果 <op> 指定了特定的 CEC 操作码,则该位的位置必须至少为 18,否则尚未收到操作码。
<op>[,<mode>] tx-custom-start
发送自定义位而不是常规起始位。
tx-custom-pulse
一旦 CEC 总线空闲,就发送单个自定义脉冲。