Resource sharing and locking question

Forgive my ignorance on this matter but I want to be sure I start out this project on the right foot.
Two questions:
-If I have multiple devices on an I2C bus (or SPI) and I want to access each those devices with different threads do I need to lock access to the i2c bus? Since TinyCLR is single-threaded, and I assume Read/Write functions block until completion is it necessary?

-Similar question as above but in regards to a memory buffer. I will have a large memory buffer, probably 4KB that will need to be shared by multiple threads. Various threads will be reading/writing data to it, does it need locking.

I guess the bigger question is does a thread always run to completion or Thread.Sleep() with no interrupts? (I guess that’s 3 questions.)

We are using locks within our drivers for I2C and SPI. The lock is only on the read/write calls, not on the entire methods.

public void Write(UInt32 data)
        {
            _data[0] = (Byte)(data >> 16);
            _data[1] = (Byte)(data >> 8);
            _data[2] = (Byte)data;
            lock (_socket.LockSpi)
            {
                _bargraph.Write(_data);
            }
        }

The lock is a “per socket” (or rather “per bus”) lock because not all sockets are using the same bus and the lock does not need to block all spi/i2c calls if buses are not the same.

SocketOne.LockSpi = new Object();
SocketTwo.LockSpi = SocketOne.LockSpi;
SocketThree.LockSpi = SocketOne.LockSpi;
SocketFour.LockSpi = new Object();
SocketFive.LockSpi = SocketFour.LockSpi;
SocketSix.LockSpi = SocketFour.LockSpi;

I think it would be safe to use lock as well for your shared memory.

I don’t understand your third question, though.

To clarify my 3rd question, or put it a different way. Is there anything that would interrupt a thread mid-process? So if I have a thread reading through an array of 100 elements are there any processes or tasks that would interrupt that before it’s done?

No: Unless your thread has sleep or yield somewhere in loop.
Yes: TinyCLR is Rtos OS so yes. But it won’t effect to your thread (software thread).

To be sure you can use lock {} statement and Disable Interrupt.

Disable Interrupt will lock switching task in native. But it is not recommended.
And remember Enable Interrupt back once you are done with the thread.

Does TinyClr have a 20ms thread time slice like MF did?

Are any of the buses, UART, SPI, I2C, CAN, buffered so that a Send() returns immediately while the underlying OS sends the data out? (I think UART might be but want to understand better.)

Correct. I do not think we have changed that but we have that with native threads so things can be slightly different

It is still there, I forgot about that, thanks to remind me :))

UART, CAN => Yes. Send() just put data to fifo buffer and return.
SPI, I2C => No.

1 Like