Reputation: 308
I'm using I2C on an ATmega168 (slave) in C (compiling with avr-gcc), but this might be a general question about interrupts.
In my C program I have a global variable of type uint8_t i2c_buffer[32]
storing some sensor and configuration data. This array is also accessed by the I2C-ISR whenever the bus master reads or writes to the slave.
As communication is driven in hardware the transmission into ram (my I2C buffer variable) is triggered by an interrupt.
I understand that accessing the variable from both ISR and main routine carelessly might lead to corrupted data due to the race condition between the ISR and my main routine, but I'm not sure, how to handle this properly. I was told to disable interrupts while main is accessing the variable in question. This will protect the variable from getting corrupted, but won't this lead to loss of data on the other hand? What if the master tries to send data while interrupts are disabled?
I guess, as the I2C interface is still enabled, an incoming byte will at least be written to the TWDR. Is that correct? If yes: is there a way to trigger the ISR right after the main-routine has finished accessing the variable?
And: does this problem persist if one instance (ISR or main) is only reading and not writing to specific parts of the buffer?
Upvotes: 0
Views: 410
Reputation: 67546
In general you need to create a critical section in the main process (main program). You need to disable the interrupts when your main program accesses the shared variable.
You have a ready made standard solution:
#include <util/atomic.h>
/* ....*/
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
/* potentially non atomic opeartions */
}
Upvotes: 1