| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- .. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
- .. _cec_pin_error_inj:
- CEC Pin Framework Error Injection
- =================================
- The CEC Pin Framework is a core CEC framework for CEC hardware that only
- has low-level support for the CEC bus. Most hardware today will have
- high-level CEC support where the hardware deals with driving the CEC bus,
- but some older devices aren't that fancy. However, this framework also
- allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and
- you have now made a CEC adapter.
- What makes doing this so interesting is that since we have full control
- over the bus it is easy to support error injection. This is ideal to
- test how well CEC adapters can handle error conditions.
- Currently only the cec-gpio driver (when the CEC line is directly
- connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver
- support this framework.
- If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available
- through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is
- now an ``error-inj`` file.
- .. note::
- The error injection commands are not a stable ABI and may change in the
- future.
- With ``cat error-inj`` you can see both the possible commands and the current
- error injection status::
- $ 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 settings:
- # rx-no-low-drive do not generate low-drive pulses
- #
- # 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-glitch-low-usecs <usecs> define the 'low' time for the glitch pulse
- # tx-glitch-high-usecs <usecs> define the 'high' time for the glitch pulse
- # tx-glitch-falling-edge send the glitch pulse after every falling edge
- # tx-glitch-rising-edge send the glitch pulse after every rising edge
- #
- # 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
- You can write error injection commands to ``error-inj`` using
- ``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj``
- output contains the current error commands. You can save the output to a file
- and use it as an input to ``error-inj`` later.
- Basic Syntax
- ------------
- Leading spaces/tabs are ignored. If the next character is a ``#`` or the end
- of the line was reached, then the whole line is ignored. Otherwise a command
- is expected.
- The error injection commands fall in two main groups: those relating to
- receiving CEC messages and those relating to transmitting CEC messages. In
- addition, there are commands to clear existing error injection commands and
- to create custom pulses on the CEC bus.
- Most error injection commands can be executed for specific CEC opcodes or for
- all opcodes (``any``). Each command also has a 'mode' which can be ``off``
- (can be used to turn off an existing error injection command), ``once``
- (the default) which will trigger the error injection only once for the next
- received or transmitted message, ``always`` to always trigger the error
- injection and ``toggle`` to toggle the error injection on or off for every
- transmit or receive.
- So '``any rx-nack``' will NACK the next received CEC message,
- '``any,always rx-nack``' will NACK all received CEC messages and
- '``0x82,toggle rx-nack``' will only NACK if an Active Source message was
- received and do that only for every other received message.
- After an error was injected with mode ``once`` the error injection command
- is cleared automatically, so ``once`` is a one-time deal.
- All combinations of ``<op>`` and error injection commands can co-exist. So
- this is fine::
- 0x9e tx-add-bytes 1
- 0x9e tx-early-eom
- 0x9f tx-add-bytes 2
- any rx-nack
- All four error injection commands will be active simultaneously.
- However, if the same ``<op>`` and command combination is specified,
- but with different arguments::
- 0x9e tx-add-bytes 1
- 0x9e tx-add-bytes 2
- Then the second will overwrite the first.
- Clear Error Injections
- ----------------------
- ``clear``
- Clear all error injections.
- ``rx-clear``
- Clear all receive error injections
- ``tx-clear``
- Clear all transmit error injections
- ``<op> clear``
- Clear all error injections for the given opcode.
- ``<op> rx-clear``
- Clear all receive error injections for the given opcode.
- ``<op> tx-clear``
- Clear all transmit error injections for the given opcode.
- Receive Messages
- ----------------
- ``<op>[,<mode>] rx-nack``
- NACK broadcast messages and messages directed to this CEC adapter.
- Every byte of the message will be NACKed in case the transmitter
- keeps transmitting after the first byte was NACKed.
- ``<op>[,<mode>] rx-low-drive <bit>``
- Force a Low Drive condition at this bit position. If <op> specifies
- a specific CEC opcode then the bit position must be at least 18,
- otherwise the opcode hasn't been received yet. This tests if the
- transmitter can handle the Low Drive condition correctly and reports
- the error correctly. Note that a Low Drive in the first 4 bits can also
- be interpreted as an Arbitration Lost condition by the transmitter.
- This is implementation dependent.
- ``<op>[,<mode>] rx-add-byte``
- Add a spurious 0x55 byte to the received CEC message, provided
- the message was 15 bytes long or less. This is useful to test
- the high-level protocol since spurious bytes should be ignored.
- ``<op>[,<mode>] rx-remove-byte``
- Remove the last byte from the received CEC message, provided it
- was at least 2 bytes long. This is useful to test the high-level
- protocol since messages that are too short should be ignored.
- ``<op>[,<mode>] rx-arb-lost <poll>``
- Generate a POLL message to trigger an Arbitration Lost condition.
- This command is only allowed for ``<op>`` values of ``next`` or ``all``.
- As soon as a start bit has been received the CEC adapter will switch
- to transmit mode and it will transmit a POLL message. By default this is
- 0x0f, but it can also be specified explicitly via the ``<poll>`` argument.
- This command can be used to test the Arbitration Lost condition in
- the remote CEC transmitter. Arbitration happens when two CEC adapters
- start sending a message at the same time. In that case the initiator
- with the most leading zeroes wins and the other transmitter has to
- stop transmitting ('Arbitration Lost'). This is very hard to test,
- except by using this error injection command.
- This does not work if the remote CEC transmitter has logical address
- 0 ('TV') since that will always win.
- ``rx-no-low-drive``
- The receiver will ignore situations that would normally generate a
- Low Drive pulse (3.6 ms). This is typically done if a spurious pulse is
- detected when receiving a message, and it indicates to the transmitter that
- the message has to be retransmitted since the receiver got confused.
- Disabling this is useful to test how other CEC devices handle glitches
- by ensuring we will not be the one that generates a Low Drive.
- Transmit Messages
- -----------------
- ``tx-ignore-nack-until-eom``
- This setting changes the behavior of transmitting CEC messages. Normally
- as soon as the receiver NACKs a byte the transmit will stop, but the
- specification also allows that the full message is transmitted and only
- at the end will the transmitter look at the ACK bit. This is not
- recommended behavior since there is no point in keeping the CEC bus busy
- for longer than is strictly needed. Especially given how slow the bus is.
- This setting can be used to test how well a receiver deals with
- transmitters that ignore NACKs until the very end of the message.
- ``<op>[,<mode>] tx-no-eom``
- Don't set the EOM bit. Normally the last byte of the message has the EOM
- (End-Of-Message) bit set. With this command the transmit will just stop
- without ever sending an EOM. This can be used to test how a receiver
- handles this case. Normally receivers have a time-out after which
- they will go back to the Idle state.
- ``<op>[,<mode>] tx-early-eom``
- Set the EOM bit one byte too soon. This obviously only works for messages
- of two bytes or more. The EOM bit will be set for the second-to-last byte
- and not for the final byte. The receiver should ignore the last byte in
- this case. Since the resulting message is likely to be too short for this
- same reason the whole message is typically ignored. The receiver should be
- in Idle state after the last byte was transmitted.
- ``<op>[,<mode>] tx-add-bytes <num>``
- Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes
- have the value of the byte position in the message. So if you transmit a
- two byte message (e.g. a Get CEC Version message) and add 2 bytes, then
- the full message received by the remote CEC adapter is
- ``0x40 0x9f 0x02 0x03``.
- This command can be used to test buffer overflows in the receiver. E.g.
- what does it do when it receives more than the maximum message size of 16
- bytes.
- ``<op>[,<mode>] tx-remove-byte``
- Drop the last byte from the message, provided the message is at least
- two bytes long. The receiver should ignore messages that are too short.
- ``<op>[,<mode>] tx-short-bit <bit>``
- Make this bit period shorter than allowed. The bit position cannot be
- an Ack bit. If <op> specifies a specific CEC opcode then the bit position
- must be at least 18, otherwise the opcode hasn't been received yet.
- Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
- With this command the period of this bit is 1.8 milliseconds, this is
- done by reducing the time the CEC bus is high. This bit period is less
- than is allowed and the receiver should respond with a Low Drive
- condition.
- This command is ignored for 0 bits in bit positions 0 to 3. This is
- because the receiver also looks for an Arbitration Lost condition in
- those first four bits and it is undefined what will happen if it
- sees a too-short 0 bit.
- ``<op>[,<mode>] tx-long-bit <bit>``
- Make this bit period longer than is valid. The bit position cannot be
- an Ack bit. If <op> specifies a specific CEC opcode then the bit position
- must be at least 18, otherwise the opcode hasn't been received yet.
- Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
- With this command the period of this bit is 2.9 milliseconds, this is
- done by increasing the time the CEC bus is high.
- Even though this bit period is longer than is valid it is undefined what
- a receiver will do. It might just accept it, or it might time out and
- return to Idle state. Unfortunately the CEC specification is silent about
- this.
- This command is ignored for 0 bits in bit positions 0 to 3. This is
- because the receiver also looks for an Arbitration Lost condition in
- those first four bits and it is undefined what will happen if it
- sees a too-long 0 bit.
- ``<op>[,<mode>] tx-short-start``
- Make this start bit period shorter than allowed. Normally the period of
- a start bit is between 4.3 and 4.7 milliseconds. With this command the
- period of the start bit is 4.1 milliseconds, this is done by reducing
- the time the CEC bus is high. This start bit period is less than is
- allowed and the receiver should return to Idle state when this is detected.
- ``<op>[,<mode>] tx-long-start``
- Make this start bit period longer than is valid. Normally the period of
- a start bit is between 4.3 and 4.7 milliseconds. With this command the
- period of the start bit is 5 milliseconds, this is done by increasing
- the time the CEC bus is high. This start bit period is more than is
- valid and the receiver should return to Idle state when this is detected.
- Even though this start bit period is longer than is valid it is undefined
- what a receiver will do. It might just accept it, or it might time out and
- return to Idle state. Unfortunately the CEC specification is silent about
- this.
- ``<op>[,<mode>] tx-last-bit <bit>``
- Just stop transmitting after this bit. If <op> specifies a specific CEC
- opcode then the bit position must be at least 18, otherwise the opcode
- hasn't been received yet. This command can be used to test how the receiver
- reacts when a message just suddenly stops. It should time out and go back
- to Idle state.
- ``<op>[,<mode>] tx-low-drive <bit>``
- Force a Low Drive condition at this bit position. If <op> specifies a
- specific CEC opcode then the bit position must be at least 18, otherwise
- the opcode hasn't been received yet. This can be used to test how the
- receiver handles Low Drive conditions. Note that if this happens at bit
- positions 0-3 the receiver can interpret this as an Arbitration Lost
- condition. This is implementation dependent.
- Custom Pulses
- -------------
- ``tx-custom-low-usecs <usecs>``
- This defines the duration in microseconds that the custom pulse pulls
- the CEC line low. The default is 1000 microseconds.
- ``tx-custom-high-usecs <usecs>``
- This defines the duration in microseconds that the custom pulse keeps the
- CEC line high (unless another CEC adapter pulls it low in that time).
- The default is 1000 microseconds. The total period of the custom pulse is
- ``tx-custom-low-usecs + tx-custom-high-usecs``.
- ``<op>[,<mode>] tx-custom-bit <bit>``
- Send the custom bit instead of a regular data bit. The bit position cannot
- be an Ack bit. If <op> specifies a specific CEC opcode then the bit
- position must be at least 18, otherwise the opcode hasn't been received yet.
- ``<op>[,<mode>] tx-custom-start``
- Send the custom bit instead of a regular start bit.
- ``tx-custom-pulse``
- Transmit a single custom pulse as soon as the CEC bus is idle.
- Glitch Pulses
- -------------
- This emulates what happens if the signal on the CEC line is seeing spurious
- pulses. Typically this happens after the falling or rising edge where there
- is a short voltage fluctuation that, if the CEC hardware doesn't do
- deglitching, can be seen as a spurious pulse and can cause a Low Drive
- condition or corrupt data.
- ``tx-glitch-low-usecs <usecs>``
- This defines the duration in microseconds that the glitch pulse pulls
- the CEC line low. The default is 1 microsecond. The range is 0-100
- microseconds. If 0, then no glitch pulse will be generated.
- ``tx-glitch-high-usecs <usecs>``
- This defines the duration in microseconds that the glitch pulse keeps the
- CEC line high (unless another CEC adapter pulls it low in that time).
- The default is 1 microseconds. The range is 0-100 microseconds. If 0, then
- no glitch pulse will be generated.The total period of the glitch pulse is
- ``tx-custom-low-usecs + tx-custom-high-usecs``.
- ``tx-glitch-falling-edge``
- Send the glitch pulse right after the falling edge.
- ``tx-glitch-rising-edge``
- Send the glitch pulse right after the rising edge.
|