Difference between revisions of "Tests:I2C-fault-injection"

From eLinux.org
Jump to: navigation, search
m (Final edits to make first version finished)
m (Preparation for second "incomplete transfer" style injector)
Line 2: Line 2:
 
=Setup=
 
=Setup=
  
 +
==Kernel Version and Configuration==
 +
Support for this feature is upstream since v4.16. An update is scheduled for v4.19. Please note that in this update, the file ''incomplete_transfer'' has been renamed to ''incomplete_address_phase'' to distinguish it better from another fault injector.
  
==Kernel Version and Configuration==
+
The original patches are available in a topic branches:
Support for this feature is expected to land upstream in v4.15. It is currently available in a topic branch:
 
  
 
git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/topic/i2c-fault-injection
 
git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/topic/i2c-fault-injection
 +
 +
git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/i2c/recovery/write-byte-fix
  
 
The following kernel options need to be set in addition to the defconfig:
 
The following kernel options need to be set in addition to the defconfig:
Line 48: Line 51:
 
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
 
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
 
# ls -1
 
# ls -1
incomplete_transfer
+
incomplete_address_phase
 +
incomplete_write_byte
 
scl
 
scl
 
sda
 
sda
Line 57: Line 61:
 
== Incomplete transfer ==
 
== Incomplete transfer ==
  
An incomplete transfer is used to make a device keep SDA low.
+
An incomplete transfer is used to make a device keep SDA low. Here the first example of stopping the transfer during acknowledgment of the address of the client.
  
 
=== Salvator-X/r8a7796 (R-Car M3-W SoC) ===
 
=== Salvator-X/r8a7796 (R-Car M3-W SoC) ===
Line 63: Line 67:
 
<pre>
 
<pre>
 
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
 
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# echo 0x10 > incomplete_transfer
+
# echo 0x10 > incomplete_address_phase
 
</pre>
 
</pre>
  
Line 76: Line 80:
 
# echo 2 > /sys/devices/platform/i2c-11/current_master
 
# echo 2 > /sys/devices/platform/i2c-11/current_master
 
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
 
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# echo 0x5a > incomplete_transfer
+
# echo 0x5a > incomplete_address_phase
 
</pre>
 
</pre>
  
Line 86: Line 90:
 
Checking another device:
 
Checking another device:
 
<pre>
 
<pre>
# echo 0x12 > incomplete_transfer
+
# echo 0x12 > incomplete_address_phase
 
</pre>
 
</pre>
  
Line 127: Line 131:
  
 
= Conclusion =
 
= Conclusion =
It could be demonstrated that the "incomplete_transfer" mechanism creates a stalled bus. It could be observed that some devices detect this condition and try to recover the bus. Cases which create a completely stalled bus could also be created (e.g. by the audio codec on Lager). This can serve as a test case for the bus recovery feature of the Linux I2C core. Also, the features of pinning SCL and SDA permanently low could be demonstrated. This can be used to make I2C drivers handle this abnormal situation gracefully.
+
It could be demonstrated that the incomplete transfer fault injectors create a stalled bus. It could be observed that some devices detect this condition and try to recover the bus. Cases which create a completely stalled bus could also be created (e.g. by the audio codec on Lager). This can serve as a test case for the bus recovery feature of the Linux I2C core. Also, the features of pinning SCL and SDA permanently low could be demonstrated. This can be used to make I2C drivers handle this abnormal situation gracefully.

Revision as of 00:58, 2 July 2018

This document describes how to test the I2C fault injection feature. The Renesas Salvator-X (R-Car M3-W) and Lager (R-Car H2) boards are used.

Setup

Kernel Version and Configuration

Support for this feature is upstream since v4.16. An update is scheduled for v4.19. Please note that in this update, the file incomplete_transfer has been renamed to incomplete_address_phase to distinguish it better from another fault injector.

The original patches are available in a topic branches:

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/topic/i2c-fault-injection

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/i2c/recovery/write-byte-fix

The following kernel options need to be set in addition to the defconfig:

CONFIG_I2C_GPIO=y
CONFIG_I2C_GPIO_FAULT_INJECTOR=y

Hardware Environment

Salvator-X/r8a7796 (R-Car M3-W SoC)

On the EXIO_B connector, you need to connect the pins:

57 <-> 73 (for SCL)
54 <-> 74 (for SDA)

This will hook two GPIO to the I2C2 bus. The above branch will update the DTS to enable the GPIO as a bit-banged I2C bus.

Lager/r8a7790 (R-Car H2 SoC)

You need to connect the pins:

EXIO_C 78 <-> EXIO_A 58 (for SCL)
EXIO_C 80 <-> EXIO_A 60 (for SDA)

This will connect the I2C1 and the I2C2 bus. We will use the I2C demultiplexer at runtime to switch I2C1 to GPIO:

# echo 2 > /sys/devices/platform/i2c-11/current_master

Software Environment

Only a busybox with standard commands like cd, cat, echo is needed.

Testing

On both boards, you should go to the i2c fault injector directory and see the following files:

# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# ls -1
incomplete_address_phase
incomplete_write_byte
scl
sda

Please refer to the documentation file in Documentation/i2c/gpio-fault-injection about the meaning of the files.

Incomplete transfer

An incomplete transfer is used to make a device keep SDA low. Here the first example of stopping the transfer during acknowledgment of the address of the client.

Salvator-X/r8a7796 (R-Car M3-W SoC)

Use these commands:

# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# echo 0x10 > incomplete_address_phase

With a scope, you can see the following happening: Incomplete transfer on Salvator-X

You can see that SDA is kept low. After 45ms, SCL is toggled again, so the device releases SDA again. This is done by the external LTC4313 chip which monitors the bus and tries to reactivate it. So, the bus stalled condition was met which made the LTC4313 reactivate the bus.

Lager/r8a7790 (R-Car H2 SoC)

Use these commands:

# echo 2 > /sys/devices/platform/i2c-11/current_master
# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# echo 0x5a > incomplete_address_phase

With a scope, you can see the following happening: Incomplete transfer on Lager, device reacts

You can see that SDA is kept low. After 30ms, SDA raises without SCL being toggled. This is because the DA9xxx chips detect the timeout on SCL and release SDA on their own. So, the bus stalled condition was met which made the DA9xxx reactivate the bus.

Checking another device:

# echo 0x12 > incomplete_address_phase

With a scope, you can see the following happening: Incomplete transfer on Lager, device does not react

You can see that SDA is kept low forever. The audio codec does not have any timeout detection and there is no external chip to reactivate the bus. It is now the I2C bus masters turn to detect this condition and to recover the bus by toggling SCL.

Pin SDA low

Use these commands on the Salvator-X:

# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# echo 0 > sda

With a scope, you can see the following happening: SDA pinned low on Salvator-X

Now, SDA is pinned low by us until we release it. You can see the LTC4313 trying to recover the bus, but to no avail. The bus can only be released with

# echo 1 > sda

On the Lager board, nothing special will happen because there is no LTC4313. SDA just stays low until it gets manually released again.

Pin SCL low

Use these commands on the Salvator-X or Lager:

# cd /sys/kernel/debug/i2c-fault-injector/i2c-8/
# echo 0 > scl

With a scope, you can see the following happening: SCL pinned low on Salvator-X

Now, SCL is pinned low by us until we release it. No communication is possible anymore. The bus can only be released with:

# echo 1 > scl

Conclusion

It could be demonstrated that the incomplete transfer fault injectors create a stalled bus. It could be observed that some devices detect this condition and try to recover the bus. Cases which create a completely stalled bus could also be created (e.g. by the audio codec on Lager). This can serve as a test case for the bus recovery feature of the Linux I2C core. Also, the features of pinning SCL and SDA permanently low could be demonstrated. This can be used to make I2C drivers handle this abnormal situation gracefully.