in reply to i2c bus contention

I considered having a lock file that each script accesses, to control access to the i2c bus, but that seems like a lot of overhead, probably worse that my time slot solution.

Taking a brief look at the code, it appears that what HiPi::Device::I2C is doing is an ioctl on the /dev/i2c* device file, and my guess would be that the Linux kernel doesn't guarantee those to be atomic when there are multiple writers. But I also don't see your issue with a lock file, since I2C writes should be pretty quick - why not just flock the object's filehandle? I don't have an RPi with an I2C device handy to test, but I'd suggest just trying something like this:

use Fcntl qw/:flock/; ... my $i2c = HiPi::Device::I2C->new(...); ... flock($i2c->fh, LOCK_EX) or die "flock: $!"; $i2c->bus_write(...); flock($i2c->fh, LOCK_UN) or die "flock: $!";

Replies are listed 'Best First'.
Re^2: i2c bus contention
by anita2R (Scribe) on Apr 02, 2020 at 13:52 UTC

    Well adding locks to the i2c object as suggested by @haukex works fine.

    The volts/amps data looks fine and there has been no disruption to the lcd dislay, albeit for 24 hours or so. As a test I removed the locking on both scripts, and to my surprise there were virtually no faults. I saw one display line corruption, but the display did not freeze or become unreadable as it had done before, but there were intermittent data errors from the amps/voltage devices.

    Perhaps a kernel update has substantially corrected the problem. I started using the time slot code in November 2018 and I am currently running Raspbian Stretch with 4.19.66+ on a Raspberry Pi Model B Plus Rev 1.2, so there will have been updates since November 2018.

    After updating scripts on a second Raspberry Pi (Raspberry Pi 3 Model B Rev 1.2) also running Stretch, there has been a marked increase in stability. One script that previously had unexplained crashes has been stable for almost 24 hours and data errors have stopped. This Pi has three scripts accessing i2c devices on a regular basis.

    When using flock to lock the filehandles, note that the module to use is

    HiPi::Device::I2C;

    The BCM2835 module

    HiPi::BCM2835::I2C qw( :all )

    does not work - you get this message

    Can't locate object method "fh" via package "HiPi::BCM2835::I2C"

    The other gotcha was that using the default i2c bus on pins 3 & 5 (gpio2/gpio3) resulted in this error

    i2c_write failed with return value -1

    This is resolved by opening an alternate i2c bus. Edit the /boot/config.txt file and add this:

    # activate an additional i2c interface on gpio 6(pin 31) & gpio 12(pin + 32) dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=6,i2c_gpio_scl=12

    You need to be root to edit the file (use sudo). Reboot to activate. You can use any unused pair of gpios, preferably avoiding any that are designated for other functions. The two gpio's used each require a pull-up resistor to 5 volts.

    The additional i2c bus is likely i2c-3. Enter ls -l /dev/i2c* to see the device id's.

    Thanks to everyone for your replies and of course to haukex for a successful conclusion.

Re^2: i2c bus contention
by anita2R (Scribe) on Mar 30, 2020 at 13:21 UTC

    @haukex Thanks for the suggestion. I will try adding the lock

    It will take some time to test, as I will have to deactivate the time slot code in both scripts.