| Linux I2C fault injection |
| ========================= |
| |
| The GPIO based I2C bus master driver can be configured to provide fault |
| injection capabilities. It is then meant to be connected to another I2C bus |
| which is driven by the I2C bus master driver under test. The GPIO fault |
| injection driver can create special states on the bus which the other I2C bus |
| master driver should handle gracefully. |
| |
| Once the Kconfig option I2C_GPIO_FAULT_INJECTOR is enabled, there will be an |
| 'i2c-fault-injector' subdirectory in the Kernel debugfs filesystem, usually |
| mounted at /sys/kernel/debug. There will be a separate subdirectory per GPIO |
| driven I2C bus. Each subdirectory will contain files to trigger the fault |
| injection. They will be described now along with their intended use-cases. |
| |
| "scl" |
| ----- |
| |
| By reading this file, you get the current state of SCL. By writing, you can |
| change its state to either force it low or to release it again. So, by using |
| "echo 0 > scl" you force SCL low and thus, no communication will be possible |
| because the bus master under test will not be able to clock. It should detect |
| the condition of SCL being unresponsive and report an error to the upper |
| layers. |
| |
| "sda" |
| ----- |
| |
| By reading this file, you get the current state of SDA. By writing, you can |
| change its state to either force it low or to release it again. So, by using |
| "echo 0 > sda" you force SDA low and thus, data cannot be transmitted. The bus |
| master under test should detect this condition and trigger a bus recovery (see |
| I2C specification version 4, section 3.1.16) using the helpers of the Linux I2C |
| core (see 'struct bus_recovery_info'). However, the bus recovery will not |
| succeed because SDA is still pinned low until you manually release it again |
| with "echo 1 > sda". A test with an automatic release can be done with the |
| following class of fault injectors. |
| |
| Introduction to incomplete transfers |
| ------------------------------------ |
| |
| The following fault injectors create situations where SDA will be held low by a |
| device. Bus recovery should be able to fix these situations. But please note: |
| there are I2C client devices which detect a stuck SDA on their side and release |
| it on their own after a few milliseconds. Also, there might be an external |
| device deglitching and monitoring the I2C bus. It could also detect a stuck SDA |
| and will init a bus recovery on its own. If you want to implement bus recovery |
| in a bus master driver, make sure you checked your hardware setup for such |
| devices before. And always verify with a scope or logic analyzer! |
| |
| "incomplete_address_phase" |
| -------------------------- |
| |
| This file is write only and you need to write the address of an existing I2C |
| client device to it. Then, a read transfer to this device will be started, but |
| it will stop at the ACK phase after the address of the client has been |
| transmitted. Because the device will ACK its presence, this results in SDA |
| being pulled low by the device while SCL is high. So, similar to the "sda" file |
| above, the bus master under test should detect this condition and try a bus |
| recovery. This time, however, it should succeed and the device should release |
| SDA after toggling SCL. |
| |
| "incomplete_write_byte" |
| ----------------------- |
| |
| Similar to above, this file is write only and you need to write the address of |
| an existing I2C client device to it. |
| |
| The injector will again stop at one ACK phase, so the device will keep SDA low |
| because it acknowledges data. However, there are two differences compared to |
| 'incomplete_address_phase': |
| |
| a) the message sent out will be a write message |
| b) after the address byte, a 0x00 byte will be transferred. Then, stop at ACK. |
| |
| This is a highly delicate state, the device is set up to write any data to |
| register 0x00 (if it has registers) when further clock pulses happen on SCL. |
| This is why bus recovery (up to 9 clock pulses) must either check SDA or send |
| additional STOP conditions to ensure the bus has been released. Otherwise |
| random data will be written to a device! |
| |