Saturday, January 6, 2018

Fake i2c device( i2c-stub)




If you want to test I2C client implementation without actual hardware you can do this with i2c-stub.

Kernel has a Fake I2C master and I2C device implementation , i2c-stub.
https://www.kernel.org/doc/Documentation/i2c/i2c-stub
http://elixir.free-electrons.com/linux/latest/source/drivers/i2c/i2c-stub.c

Basically it creates a fake I2C adapter( Controller/Master) and also emulates
i2C hardware ( using array to store data, which can also be mapped any other
slave driver , so that all slave calls is redirected to stub.)
https://eraretuya.github.io/2016/12/10/the-i2c-stub-in-action/

(I2C device files are character device files with major device number 89
cat /proc/devices | grep i2c
 89 i2c
)

the typical use-case is like this:
1. load this module
2. use i2cset (from the i2c-tools project) to pre-load some data
3. load the target chip driver module
4. observe its behavior in the kernel log

There's a script named i2c-stub-from-dump in the i2c-tools package which
can load register values automatically from a chip dump.


Loading i2c-stub
===============
To have load this i2c-stub with Master and slave of Devcice address 0x1c
modprobe i2c-stub chip_addr=0x1c

#dmesg
[ 9587.673215] i2c-stub: Virtual chip at 0x1c

root@embsys-VirtualBox:/boot/grub# lsmod | grep i2c
i2c_stub               16384  0

Once you load the i2c-stub a new i2c master node is create in /sys/class/i2c-adapter & i2c-dev
(here it is i2c-1)

root@embsys-VirtualBox:/boot/grub# tree /sys/class/i2c*---->IMP:i2c-0 and i2c-1 are two i2c master each suppports upto- 0x03-0x77 slaves.
/sys/class/i2c-adapter
├── i2c-0 -> ../../devices/pci0000:00/0000:00:07.0/i2c-0
└── i2c-1 -> ../../devices/i2c-1
/sys/class/i2c-dev
├── i2c-0 -> ../../devices/pci0000:00/0000:00:07.0/i2c-0/i2c-dev/i2c-0
└── i2c-1 -> ../../devices/i2c-1/i2c-dev/i2c-1



There are some nice user space tools to see i2c devices..
apt-get install i2c-tools
This install
1. i2cdetect         
2. i2cdump           
3. i2cget           
4. i2cset           
5. i2c-stub-from-dump




i2cdetect
===========

1.
To List I2C Adapters(Master( in systems)
root@embsys-VirtualBox:/boot/grub# i2cdetect -l
i2c-1   smbus           SMBus stub driver                       SMBus adapter
i2c-0   smbus           SMBus PIIX4 adapter at 4100             SMBus adapter

2.Detect devices present on I2C bus
e.g To read i2c devices connect to i2c master bus at i2c-1

root@embsys-VirtualBox:/boot/grub# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

( THis shows devices/slave address from 03--0x77 possible )
right now only 1c device is prsent in the system with slave address
as 1c.

Reading/Writing
===============
writing
i2cset 1 0x1C 0x07 0x04 b


oot@embsys-VirtualBox:~/pci-hacking/ksrc/interrupt# i2cset 1 0x1C 0x07 0x04 b
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will write to device file /dev/i2c-1, chip address 0x1c, data address
0x07, data 0x04, mode byte.
Continue? [Y/n] y

dmesg
[ 2653.138676] i2c i2c-1: ioctl, cmd=0x705, arg=0x7fff70394ca0
[ 2653.138681] i2c i2c-1: ioctl, cmd=0x703, arg=0x1c
[ 2654.662332] i2c i2c-1: ioctl, cmd=0x720, arg=0x7fff70394ca0
[ 2654.662338] i2c i2c-1: smbus byte data - addr 0x1c, wrote 0x04 at 0x07.


Reading

root@embsys-VirtualBox:~/pci-hacking/ksrc/interrupt# i2cget 1 0x1c 0x07
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-1, chip address 0x1c, data address
0x07, using read byte data.
Continue? [Y/n] y
0x04


Binding to other device to simulate
===================================
i2c-stub can be used in conjuction with actualt clinet driver,
in the absence of real hardware ,...values in the array of stub driver
will be written or read.

example to use
http://lxr.free-electrons.com/source/drivers/iio/light/al3320a.c ( this has slave address as 0x1C)

echo al3320a 0x1c > /sys/class/i2c-adapter/i2c-1/new_device

Range of Address it supports is
#define AL3320A_REG_CONFIG_RANGE 0x07
#define AL3320A_REG_DATA_LOW 0x22



root@embsys-VirtualBox:~/pci-hacking/ksrc/interrupt# echo al3320a 0x1c > /sys/class/i2c-adapter/i2c-1/new_device
root@embsys-VirtualBox:~/pci-hacking/ksrc/interrupt# dmesg
[ 3519.706231] al3320a 1-001c: probe
[ 3519.706277] i2c i2c-1: smbus byte data - addr 0x1c, wrote 0x01 at 0x00.
[ 3519.706286] i2c i2c-1: smbus byte data - addr 0x1c, wrote 0x04 at 0x07.
[ 3519.706289] i2c i2c-1: smbus byte data - addr 0x1c, wrote 0x04 at 0x09.
[ 3519.706292] i2c i2c-1: smbus byte data - addr 0x1c, wrote 0x00 at 0x06.
[ 3519.707752] i2c i2c-1: client [al3320a] registered with bus id 1-001c
[ 3519.707758] i2c i2c-1: new_device: Instantiated device al3320a at 0x1c


No comments:

Post a Comment

Featured Post

XDP - Getting Started with XDP (Linux)