pharo-iot@lists.pharo.org

Pharo IoT Developers and Hardcore users

View all threads

Firmata and concurrency

RV
Rob van Lopik <robvanlopik@gmail.com>
Tue, Jun 9, 2020 8:29 PM

Hi All,

When I first looked at Firmata, almost a year ago, I noticed that access to acquired data was shared between the thread that reads from the Arduino and the user code. This should be an uninterruptible operation. Later I learned that arrays #at: and #at:put:  are atomic operations. As far as I can see this is not by design, but because they are primitives. Changing the workings of the VM could also change that. By the way, it is not very evident from any documentation that this is the case. It so happens that these data are in arrays, so it would be safe. But when adding other devices I also have to use some dictionaries, so now I will have to introduce a Mutex to coordinate access to these instance variables. Please let me know if you don't agree with this analysis.

The part that sends commands to the Arduino also has concurrency problems. I expect a measurement and control system to be composed of different processes (threads in Pharo), while there can be only one instance of Firmata. So thread safety is important for all writes to the serial port. Full thread safety may not be necessary, as long as different processes access different functions of Firmata, e.g. one thread controls servo motors, another one steppers and a third one pwm output (the latter already is tricky, because both use analog writes). Anyway this is something the user should be aware of and take care of. But at least inside Firmata sending a sysex string to the serial port should be protected. I don't know whether the actual primitive operation (serialPort >> primWritePort: portNumber from: byteArray startingAt: startIndex count: count) is atomic. But serialPort>>netPutAll: contains (very little) Pharo code. I guess that it is sufficient when each method does only one "port nextPutAll:", so the byte array to be sent has to be prepared in advance. Separate sends of startsysex and endsysex should not be used. The same holds for all non-sysex sends. If not, I will have to protect all writes to the serial port with a mutex.

Thirty years ago I once taught an "introduction to real time programming" for agricultural researchers. The main thing I wanted to convey was to be aware of possible problems. That attitude  has remained with me, after all those years. But I thought I could better check with people like you, who have more actual/recent experience. The last realtime things I have done were with Arduino code. There a short critical section is easily accomplished by turning off all interrupts.

cheers and thanks for any comments. rob van lopik

Hi All, When I first looked at Firmata, almost a year ago, I noticed that access to acquired data was shared between the thread that reads from the Arduino and the user code. This should be an uninterruptible operation. Later I learned that arrays #at: and #at:put: are atomic operations. As far as I can see this is not by design, but because they are primitives. Changing the workings of the VM could also change that. By the way, it is not very evident from any documentation that this is the case. It so happens that these data are in arrays, so it would be safe. But when adding other devices I also have to use some dictionaries, so now I will have to introduce a Mutex to coordinate access to these instance variables. Please let me know if you don't agree with this analysis. The part that sends commands to the Arduino also has concurrency problems. I expect a measurement and control system to be composed of different processes (threads in Pharo), while there can be only one instance of Firmata. So thread safety is important for all writes to the serial port. Full thread safety may not be necessary, as long as different processes access different functions of Firmata, e.g. one thread controls servo motors, another one steppers and a third one pwm output (the latter already is tricky, because both use analog writes). Anyway this is something the user should be aware of and take care of. But at least inside Firmata sending a sysex string to the serial port should be protected. I don't know whether the actual primitive operation (serialPort >> primWritePort: portNumber from: byteArray startingAt: startIndex count: count) is atomic. But serialPort>>netPutAll: contains (very little) Pharo code. I guess that it is sufficient when each method does only one "port nextPutAll:", so the byte array to be sent has to be prepared in advance. Separate sends of startsysex and endsysex should not be used. The same holds for all non-sysex sends. If not, I will have to protect all writes to the serial port with a mutex. Thirty years ago I once taught an "introduction to real time programming" for agricultural researchers. The main thing I wanted to convey was to be aware of possible problems. That attitude has remained with me, after all those years. But I thought I could better check with people like you, who have more actual/recent experience. The last realtime things I have done were with Arduino code. There a short critical section is easily accomplished by turning off all interrupts. cheers and thanks for any comments. rob van lopik