One I2C bus, two programs - how does that work ?

Hello all,

I've got a few I2C modules (clock, temperature sensor, etc) that I would like to access using different programs.

Under Windows the first program accessing certain hardware "takes possession" of it, causing other programs to be denied access.

The question is: how do I allow multiple programs to access the same I2C bus, but not interfering with each other ?

Or am I worrying about nothing, and the OS already sequentialises the request for me ?

Regards, Rudy Wieser

Reply to
R.Wieser
Loading thread data ...

On a sunny day (Sat, 23 Nov 2019 09:55:15 +0100) it happened "R.Wieser" wrote in :

Different tasks to the same i2c interface from user space is not possible in a multitasker. But you can make your own i2c interfaces on _any_ pins with some diodes, I am doing that exactly here using two i2c busses:

formatting link

It is Linux so on windows you are on your own. I never use the hardware i2c, software is more than fast enough and that way I can port my code to any other platform.

Reply to
Jan Panteltje

Jan,

Ofcourse it is. The only question is: how.

Though chances are the serializer for it is already present in the OS, and we do not need to do anything special.

Did you know that, as long as you can switch a pin from in to output, you do not even need diodes for that ?

Just write a Zero to the pin and switch it from input to output and back. That way you mimic a open-collector pull-down pin. :-)

Regards, Rudy Wieser

Reply to
R.Wieser

Make one program which access I2C modules and serves other programs through some protocol (sockets, message queues, REST API, whatever...).

Benefits: - you can scale to large number of consumers - consumers do not need to know anything about I2C - if you add additional modules which do not use I2C but some other protocol, they can be exposed through same interface

--
obruT
Reply to
obruT

obruT,

I take it that you mean to say you do not know of a build-in serializer for it. Thats too bad, as it would have made everything much simpler.

...

But instead need to know about the private interface/API instead of just being able to google the public (for the Pi) I2C one ...

Warning, feature-creep detected. :-)

Thanks for the suggestion though.

Regards, Rudy Wieser

Reply to
R.Wieser

On a sunny day (Sat, 23 Nov 2019 12:30:34 +0100) it happened "R.Wieser" wrote in :

Maybe you think you can use flags to signal 'in use' for one process, and have the other task wait 'Semaphore' i the keyword. But that just may easily lock, reduces speed, not my sort of solution.

i2c has many modes, muti-master is one of those. Why make it difficult if you have a zillion (tm) pins available on GPIO (or anywhere else).

Yes, me using diodes it is just a fail safe protection, you can switch I/O direction but that is not safe in case of a software fault if your I/O pin is high and the i2c chip does a sda pulldown as acknowledgment. In experimental setups like I use (well sort of permanent, it is working perfectly for years now) it is just a protection measure. I leave it in in case of raspi, as new raspis are more expensive than diodes.

Reply to
Jan Panteltje

Jan,

Do tell how that might happen, so that I can evade such a situation.

:-) You have some solution in which neither program needs to wait for the other ? I'm intrigued.

I wanted to limit the scope a bit (with the Py functioning as /the/ master), but realized that that doesn't make any difference that I can think of.

Yep, a glitch and an acknowledgement at the same time might cause that. What do you think of the chances of the first, and than the chances of both happening together (mind you, for an I2C device to generate an ACK it first needs to recognise its own address).

Personally I would be more afraid of me/someone connecting the device the wrong way - putting vcc on a data/clock pin or just a 5v device with its own passive pull-ups - and that way blow a pin.

Absolutily. But I than rather spend a buck-and-a-half and put an I2C level-converter in - even when both sides are 3v3.

Regards, Rudy Wieser

Reply to
R.Wieser

Have you read the I2C docs for the Linux kernel? There's a whole I2C driver/API section.

Reply to
mm0fmf

On a sunny day (Sat, 23 Nov 2019 18:30:38 +0100) it happened "R.Wieser" wrote in :

If you already think you know everything why ask? How many i2c projects did you design / write code for BTW?

Reply to
Jan Panteltje

It's his modus operandi.

Reply to
A. Dumas

On a sunny day (23 Nov 2019 18:30:05 GMT) it happened A. Dumas wrote in :

I just hope he does not design for space or airplanes or something like that 'unlikely to happen' (bus conflict), for me rules Murphy's law: If it can happen it will.

Same for 2 programs using the same i2c hardware nd semaphore communication, if one fails (could be user exit, crash, whatever) while it has the 'i2c in use flag' set, then the other will also fail, wait forever, do nothing.

Reply to
Jan Panteltje

Jan,

I didn't. It was /your/ suggestion to go use a software I2C solution instead.

My question is still about *how to access* the Pi's own I2C. And that means that the question /is not even about I2C itself/ - but rather about the OS.

Ah. Nope, not going into a pissing match. Sorry. But you now know that I also know a thing or two about both I2C as well as electronics.

Regards, Rudy Wieser

Reply to
R.Wieser

Jan,

Really ? Is that so ?

So, how do you protect both the Pi as well as th I2C modules you connect to it against mishaps like I already described (miswiring, voltage differences - and I'm sure there are more) ?

Or do you think that that is way more unlikely than a glitch ? For the record, I don't. Especially not as both the Pi and the attached modules are there to experimenting with. Murphy's law indeed.

Ah, the old "I'm are not going to answer the person who asked it, but use it to impress someone who already agrees with me instead". Great going kid. A bit obvious though.

But I wonder how different OSes deal with .... I dunno, multiple programs trying to access the internet, and not geting in a deadlock.

I mean, if deadlocks are as easy to get into as you try to make it sound than I should have had one even just in the last month, if not week. But for some reason I can't seem to remember one, not even for the last year (or ever actually) ... How is that possible ? Can you explain ?

And if you can, why isn't the same approach not usable for an I2C device ?

Regards, Rudy Wieser

Reply to
R.Wieser

On a sunny day (Sat, 23 Nov 2019 20:43:31 +0100) it happened "R.Wieser" wrote in :

Yes, and it still is.

So show us what you are making / did make, open source your code, contribute.

Reply to
Jan Panteltje

On Sat, 23 Nov 2019 09:55:15 +0100, "R.Wieser" declaimed the following:

Unless you are running the Win10 IoT release on the R-Pi, this one is left assuming you mean that as an unfinished question "... does Linux do that too?"

Have you tried a search for "Linux share i2c"?

Various hits:

formatting link
(from
formatting link
)
formatting link
formatting link

formatting link
requires too much study to make sense out of...

Since most documentation I've found uses the file-system access scheme (/dev/), and Linux tends to not lock multiple opening of files.

Off-hand -- if you have two processes trying to access the SAME I2C device, I suspect that YOU will have to code any locks needed to ensure a command write and data read are isolated to single process.

Two processes accessing different I2C devices are probably safe, and each operation should be handled by the kernel independently...

ProcA ProcB write-dev1-command write-dev2-command read-dev1-data read-dev2-data

Crawling around Adafruit (through three layers of: module1 is deprecated, use module2; module2 is deprecated use module3) I eventually got to the CircuitPython/Blinka

formatting link
which explicitly states: """ class busio.I2C(scl, sda, *, frequency=400000, timeout=255)

I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.

See also

Using this class directly requires careful lock management. Instead, use I2CDevice to manage locks. """ and therefrom to

formatting link
which claims to handle device locking (and that implies one has to open/close the device for each transaction, and may have to catch failure to open if another process currently has it locked).

NOTE: it turns out this locking is only within the single Python (using the Threading library). (I had to check the source code for the library to discover the locks are internal)

So... if you need to support external processes which may attempt to conflict on a single device, you will apparently need to implement a locking scheme that all those processes will follow.

formatting link
formatting link
formatting link

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
Reply to
Dennis Lee Bieber

On a sunny day (Sat, 23 Nov 2019 20:49:50 +0100) it happened "R.Wieser" wrote in :

Get lost!

Reply to
Jan Panteltje

Jan,

And that is your whole problem. Instead of focussing on my question you just replace it with something you know something about - without any consideration if that is what I'm looking for.

Lol. Kiddo, the only thing you are trying to do there is to find something of that you can criticise. Why would I set myself up for that ?

As I said, I'm not here for a pissing match. I'm here seeking an answer to my question. Go find someone else to butt heads with.

Regards Rudy Wieser

Reply to
R.Wieser

Dennis,

Yes, and no. That kind of behaviour is pretty-much a requirement for accessing hardware in a multi-tasking environment. Don't do it and the first time two programs want to use the same hardware you get (either soft or hardware) sparks flying all around. So I /expect/ it to be there - but do not know for certain.

Yes, I have. Exactly two seconds ago. :-) And thanks for that. I've (ofcourse) first tried to google something myself, but couldn't think of the right keyword combination (got stuck on "multiple programs").

:-) The first link you posted already answers my question (yes, its handled internally), and the second shows that others had the same one (I'm definitily not the odd-one-out here).

And all of them are of use to me, including the "much study" one (not exactly now, but most likely a bit further down the road).

Ehrmm... That is not what the links you posted seem to tell me ...

The third link you posted (I2C concurrent access on Linux, mutex) is rather specific about it, mentioning that the kernel functions do such locking themselves. Or is that not enough ?

Which is probably 95%+ of what I'm after.

But yes, you're right. For example, I have a standard 2-line LCD display with I2C "packpack", for which a previous send I2C output is directly related to the next I2C input. A second program butting into that sequence would be disastrous.

Lightbulb moment: The I2C protocol seems to allow to start a new command without ending the old one (probably made for exactly the above problem). The question is if the Pi's SMBus supports its (and thats not a suggestion/request to look at it for me!)

Adafruit isn't Pi specific - it caters to a range of different devices, AFAIK including ones without an OS. I can imagine that it has to implement locks itself for such situations. In other words, not reference material I would want to depend on for the Pi.

Again thanks for those links. I hope you do realise that you are spoiling me this way ? Just a few more weeks and I will just post every question I have here, without trying to google it myself first ... :-D

Regards, Rudy Wieser

Reply to
R.Wieser

The Linux API seems to expose what you need. See:

formatting link

There are functions: lock_bus Get exclusive access to an I2C bus segment trylock_bus Try to get exclusive access to an I2C bus segment unlock_bus Release exclusive access to an I2C bus segment

That was after a few minutes Googling.

That was the easy bit. However, you don't say what cable lengths or electrical environment you will be working with. I2C hardware is

*very* sensitive to electrical noise. Software bit-banged drivers tend to be much more tolerant, so the idea of just using a pair of GPIO pins has merit.

A client of ours produces train control systems. They spent a few weeks writing a supposedly bullet-proof hardware driver for a deep embedded CPU. On test, it failed (but recovered) more than once per hour. On reverting to the bit-banged driver we had already supplied, they saw no failures in more than two weeks.

Except for memory devices, most I2C chips change the bus direction very frequently (every few bytes). If you want to use an unsupported device, I suggest you do it from scratch, mmap() the GPIO port, and read/wite the pins yourself. This has the downside of requiring you to use sudo to run the program, but the upside that even the klunkiest bit of coding should be able to toggle bits at tens of megahertz.

Stephen

--
Stephen Pelc, stephen@mpeforth.com 
MicroProcessor Engineering Ltd - More Real, Less Time 
133 Hill Lane, Southampton SO15 5AF, England 
tel: +44 (0)23 8063 1441, +44 (0)78 0390 3612 
web: http://www.mpeforth.com - free VFX Forth downloads
Reply to
Stephen Pelc

Stephen,

Thank you.

I have been googeling for quite a bit longer than that, but just have not been able to come up with the right keywords. :-\

Thats because I regard that as a fully seperate item, having nothing to do with the "One I2C bus, two programs" one problem. One thing(/problem) at a time seems to work best for me.

Also, what I currently have (in experimental wiring to at least two devices) does not seem to cause any problems (yet).

Ever found out what the problem was ? A too-high transmission speed ?

??? Unsupported ? I was not aware that there where supported devices.

I normally grab myself the devices datasheet and work my way up from there. Much more fun than just installing someone elses drivers. :-)

Currently I've just been using the available drivers, but with me being me there is a rather good chance (understatement) that I will try my hand at that too.

Regards, Rudy Wieser

Reply to
R.Wieser

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.