What is the "force" parameter doing in the smbus commands?

I am using smbus on a Raspi for I2C control (mostly with good success). But some (all?) commands contain an optional “force” parameter, like this:

import smbus
i2c = smbus.SMBus(1)
raw = i2c.read_i2c_block_data(0x48, 0x00, 2, force=None)  # LM75B sensor

In no documentation do I find what “force” does, and what options exist for it. Upon some problems I tried the obvious True and False, but did not see any differences.

Can anyone help?

Which smbus library are you talking about? Googling for “Python smbus” gives something different:

Is your library open source?

python-smbus, pysmbus, and smbus2 are all front ends for the Linux kernel’s I2C/SMBus subsystem. The force parameter tells Linux to reuse a slave device’s address, even if that address is already used by the driver.

The actual implementation in the kernel is here. When given the command I2C_SLAVE, the kernel will check if the address is in use and if so raise EBUSY (“Device or resource busy”), but if given I2C_SLAVE_FORCE it will go ahead and set the address anyway.

2 Likes

Ah! Thanks.
Since it is so simple to explain, why is this nowhere to be found?

My interest in this force parameter came from problems which I have with one specific I2C chip (GDK101, a solid state “Geiger” counter module). When requesting a value it returns 2 bytes. These may be both zero [0, 0] and represent a correct value, but sometimes, when at least one of the bytes should be greater zero, it still comes back as double zero. This is an error, but an exception is NOT returned, nor, as far as I can tell, not any other error.

I was hoping that “force” allowed some more stringent call, to let me know of a problem. But I now know that this is not the case.

Is there any other way to do a “more stringent” I2C call, or is the problem solely in the firmware of the chip?

It is documented in smbus2’s SMBus class, actually:

:param force: force using the slave address even when driver is
            already using it.

Is there any other way to do a “more stringent” I2C call, or is the problem solely in the firmware of the chip?

Probably not. Smbus2 (assuming that’s what you’re using) is a fairly thin wrapper around the kernel subystem, using ioctl for low level communication. The ioctl calls are almost invariably unguarded by try/except blocks, so if you’re not getting an exception that’s because the Linux kernel doesn’t detect that anything is wrong.

Sigh. But I wasn’t really expecting anything.

I am actually using smbus (not the ‘2’ version). This is coming from Debian and is default in Raspi.

I have now searched the smbus class, and if I am not mistaken then this ‘force’ parameter doesn’t even exist there. No wonder it is not documented :-/.

Probably I saw the smbus2 documentation smbus2 docu and draw a wrong conclusion based on the claimed ‘drop in replacement’.

But if smbus2 has this ‘force’ as a key difference to smbus, it is all the more surprising that this isn’t clearly documented. You really have to look very closely to find it in the class docu!

I have now used smbus2 instead of smbus, but, unsurprisingly, I do not see any difference in the behavior of my scripts.

Beyond ‘force’ (when needed) - is there any reason to prefer smbus2 over smbus?

I am actually using smbus (not the ‘2’ version). This is coming from Debian and is default in Raspi.

Ah, if you are using python3-smbus from the Debian repos, you’re actually using py-smbus which is part of the Linux kernel itself.

Beyond ‘force’ (when needed) - is there any reason to prefer smbus2 over smbus?

Smbus2 is written entirely in python, while py-smbus is written in C. This makes smbus2 easier to extend, should you need to, and if you are unfamiliar with C then using a pure python package may simplify troubleshooting.

2 Likes