Hi, I need some help. I have an ISR that reads and writes some registers from a i2c bus. I have another task_A that also reads/writes to another peripheral on the same i2c bus. I’m using xSemaphoreTakeFromISR and xSemaphoreGiveFromISR from within the ISR and xSemaphoreTake and xSemaphoreGive from task_A to synchronize access to the bus.
Is there a proper way to handle this? I see that sometimes, while task_A is in the middle of the i2c transaction, the interrupt is fired; because of this, xSemaphoreTakeFromISR fails. What is the correct way to handle this? Do I just keep retrying xSemaphoreTakeFromISR until it returns pdTRUE? I need some advice please. Thank you.
An ISR cant really read from an I2C Bus, as that is going to take MANY cpu cycles to do, and you don’t want the ISR to take that long. Also, you will need to define what the ISR should do if it finds the device busy, since it can’t “wait” for it to become ready (since the task won’t run to give the semaphore back)
Normally, that sort of action would be done by having the ISR notify some task that is waiting to support that sort of action, and do the I2C transaction in that support task.
Remember, the actual ISR should normally be code that is very short and handles just what MUST happen right away, and then pass the data to a task to process.
@SeanR, the following page describes the same pattern in detail - Safer Interrupt Handling Demo for NXP LPCXpresso55S69 Development Board - FreeRTOS.
A useful pattern in this scenario is called deferred interrupt processing, just Google as it’s not allowing me to insert a link in this response.