Wolfram Sang | 14911c6 | 2017-11-28 16:53:32 +0100 | [diff] [blame] | 1 | Linux I2C fault injection |
| 2 | ========================= |
| 3 | |
| 4 | The GPIO based I2C bus master driver can be configured to provide fault |
| 5 | injection capabilities. It is then meant to be connected to another I2C bus |
| 6 | which is driven by the I2C bus master driver under test. The GPIO fault |
| 7 | injection driver can create special states on the bus which the other I2C bus |
| 8 | master driver should handle gracefully. |
| 9 | |
| 10 | Once the Kconfig option I2C_GPIO_FAULT_INJECTOR is enabled, there will be an |
| 11 | 'i2c-fault-injector' subdirectory in the Kernel debugfs filesystem, usually |
| 12 | mounted at /sys/kernel/debug. There will be a separate subdirectory per GPIO |
| 13 | driven I2C bus. Each subdirectory will contain files to trigger the fault |
| 14 | injection. They will be described now along with their intended use-cases. |
| 15 | |
| 16 | "scl" |
| 17 | ----- |
| 18 | |
| 19 | By reading this file, you get the current state of SCL. By writing, you can |
| 20 | change its state to either force it low or to release it again. So, by using |
| 21 | "echo 0 > scl" you force SCL low and thus, no communication will be possible |
| 22 | because the bus master under test will not be able to clock. It should detect |
| 23 | the condition of SCL being unresponsive and report an error to the upper |
| 24 | layers. |
| 25 | |
| 26 | "sda" |
| 27 | ----- |
| 28 | |
| 29 | By reading this file, you get the current state of SDA. By writing, you can |
| 30 | change its state to either force it low or to release it again. So, by using |
| 31 | "echo 0 > sda" you force SDA low and thus, data cannot be transmitted. The bus |
| 32 | master under test should detect this condition and trigger a bus recovery (see |
| 33 | I2C specification version 4, section 3.1.16) using the helpers of the Linux I2C |
| 34 | core (see 'struct bus_recovery_info'). However, the bus recovery will not |
| 35 | succeed because SDA is still pinned low until you manually release it again |
| 36 | with "echo 1 > sda". A test with an automatic release can be done with the |
| 37 | 'incomplete_transfer' file. |
| 38 | |
| 39 | "incomplete_transfer" |
| 40 | --------------------- |
| 41 | |
| 42 | This file is write only and you need to write the address of an existing I2C |
| 43 | client device to it. Then, a transfer to this device will be started, but it |
| 44 | will stop at the ACK phase after the address of the client has been |
| 45 | transmitted. Because the device will ACK its presence, this results in SDA |
| 46 | being pulled low by the device while SCL is high. So, similar to the "sda" file |
| 47 | above, the bus master under test should detect this condition and try a bus |
| 48 | recovery. This time, however, it should succeed and the device should release |
| 49 | SDA after toggling SCL. Please note: there are I2C client devices which detect |
| 50 | a stuck SDA on their side and release it on their own after a few milliseconds. |
| 51 | Also, there are external devices deglitching and monitoring the I2C bus. They |
| 52 | can also detect a stuck SDA and will init a bus recovery on their own. If you |
| 53 | want to implement bus recovery in a bus master driver, make sure you checked |
| 54 | your hardware setup carefully before. |