55 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 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
 | |
| 'incomplete_transfer' file.
 | |
| 
 | |
| "incomplete_transfer"
 | |
| ---------------------
 | |
| 
 | |
| This file is write only and you need to write the address of an existing I2C
 | |
| client device to it. Then, a 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. 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 are external devices deglitching and monitoring the I2C bus. They
 | |
| can also detect a stuck SDA and will init a bus recovery on their own. If you
 | |
| want to implement bus recovery in a bus master driver, make sure you checked
 | |
| your hardware setup carefully before.
 |