I am struggling with the correct use of the volatile keyword when implementing a circular buffer. The buffer is written in an ISR and read in the main program. I am running a bare-metal microcontroller, so no multithreading.
My current implementation looks something like this:
volatile char circ_buf[n] = {0}; volatile size_t head_index = 0; volatile size_t tail_index = 0; void buffer_input(const char c) { if((head_index+ 1) % n != tail_index) { //Only if buffer is not full circ_buf[head_index] = c; head_index = (head_index + 1) % n; } } char buffer_read(void) { if (tail_index != head_index) { char c = circ_buf[tail_index]; tail_index = (tail_index + 1) % n; return c; } //Lets assume 0 will never be content of the buffer for this example return 0; } buffer_input is called from an ISR, buffer_read from the main program.
This implementation works, but I have read somewhere that making the buffer array itself volatile is not needed, because the content is only accessed via the volatile indices. Is that true? The content is accessed both in the interrupt and main program, so in my understanding the buffer should be volatile too?
size_t.size_tfor index?size_tseems alright for me, since the buffer might get big.buffer_readet. al. from main/task level are wrapped incli/sticalls.