In the image to the left, you see me debugging hardware I2C (or TWI) from AVR to a PCF8574.
This past week and a bit I realised something, there’s a couple of missing pieces in the core libraries that are really needed to tidy up the last messy pieces in IoAbstraction. Once we move beyond TcMenu 2.0, we expect that it should be enhancements only.
Firstly, we think that task manager lacks one last feature, a suitable generic cross-platform spin locking mechanism. Secondly, the way I2C is done in IoAbstraction is suboptimal, with too many conditional blocks handling different boards. Further it is synchronous often causing delays in task manager.
We have built out simple spin locking that can be used both inside and outside of task manager, it uses the same atomic constructs as task manager itself. It is reentrant within a task, so the same task can lock more than once. Usage is quite straightforward:
// define the lock somewhere
SimpleSpinLock myLock;
void methodToLock() {
TaskMgrLock locker(myLock);
// do something while locked.
}
Along with the simple traditional use, it also supports tryLock
which tells you if your task already owns the lock without spinning, and spinLock
where you can spin for a while and try to get the lock with a timeout. This allows us to implement more asynchronous behaviour in our libraries, drastically improving performance on larger boards.
We are part way through cleaning up the I2C code in IoAbstraction. As a result you can choose not to use Wire on AVR boards, as we have a hardware implementation that’s mainly asynchronous. IE: It allows other tasks to run while waiting for I2C operations to complete. We’ve introduced the above lock on all frameworks to control the I2C bus, you can use it too to wrap more than one operation into a guaranteed lock.
In addition to this, we’ll also implement the asynchronous transfer method for mbed boards; which will allow task manager to run other tasks while waiting for I2C operations. After this is done we’ll do an asynchronous implementation for ESP32 and SAMD. As always, we’d be really glad to take PRs for other boards.
We will start to provide asynchronous implementations for each board, starting with AVR where we’ll directly use the hardware and allow tasks to run, and on mbed where we’ll support the async method where its available.
We’ll provide an example in IoAbstraction of using U8G2 with the improved wire methods, in a way that does not slow down task execution.
This will be a huge improvement, especially when dealing with 100Hkz devices such as PCF8574; which are not that uncommon.