jakbird wrote on Tuesday, January 11, 2011:
A few years ago I added I2C to FreeRTOS for an STR750 (ARM7TDMI). The concept was a device driver that ran a “transaction” with a peripheral device: send command, wait for response. I used a mutex flag to serialize access to the device driver, and a completion semaphore to block the originating task until the transaction completed (or timed out). The data transfer was handled in an interrupt service routine which set the completion flag when the I2C was done.
The mutex was needed because I had two devices on the I2C bus, with a separate task for each device. The mutex ensured that commands and responses were in serial order and data went to the right task. Both tasks used the same completion flag but since the mutex blocked the second task while the first was using I2C there was no conflict.
The other trick on I2C is being able to recover from a fault. In my case I had to shut off the I2C logic, switch to bit bang mode, and manually clock out 9 bits to clear the I2C bus if a peripheral hung (it happens, don’t expect perfection). Without the timeout if a peripheral fails to respond to a command the bus hangs forever waiting for the response.