I have written a small application to communicate with TCA6424A IO-expander. I do this on a Linux-Debian ARM processor from user space. I followed
those guidelines:
Everything works fine except that the i2c_smbus_read_byte_data(fd,address) is very CPU consuming. Writing the same register with i2c_smbus_write_byte_data(fd, address,regValue) only takes a fractional CPU compared to the read-command. As I'm reading very fast incoming pulses on 8 inputs of the TCA6424A, I loose pulses because the CPU is overwhelmed with the frequent CPU demanding i2c_smbus_read_byte_data(fd,address) calls. How can it be that the read operation is so much heavier than the write-operation? Can I solve this problem by writing a device kernel-driver? I would like to avoid that as I'm not familiar with that. Another thing I have noticed is that if I call ioctl(fd,I2C_PEC,1) after opening the i2C to use check-sums both smbus- read and write fail. That is also strange?
Just to compare here are some results:
Test 1:
In a 1-5000 loop read Input register 0 in TCA6424A.
It took 26 seconds. That is 5.2mS per byte read.
This is far too slow.
Test2:
In a 1-50000 (10 times longer) loop wrote Output register 1 in TCA6424A (the relays).
It took 4 seconds. That is 80uS per byte as expected.
Test3:
In a 1-5000 loop read Input register 2 in a TLC59116f LED manager.
It took 26 seconds. That is 5.2mS per byte read.
Same slow result as with the IO expander.
I have navigated that the time/CPU consumption happens in i ioctl() call that i2c_smbus_read_byte_data() is calling.
Result, there is something very wrong regarding the Linux User Space I2C-dev driver....unless all I2C based hardware behave like this. Why should that be?