# Persisting circular buffer throughout C code

So I have a circular buffer on an embedded device that I need to persist throughout the code. Specifically, I need to have it be able to be used in the main and also in an interrupt handler (these are both in separate files). I know how to do this in assembly by manually loading registers but I'm having trouble cleanly doing it in C.

I appreciate any help as I've been trying to do this for days with no luck.

Notes: I am using an stm32f103rg that uses a cortex M3 as the processor.

• For future reference, 'pure' programming functions (like variable scope in C) are likely a better fit on the Stack Overflow SE site. – Adam Lawrence Feb 20 '14 at 18:00

Data structures that you declare outside of any function will be visible to all functions in the program. You need to declare the data structure in any source files that need to use it, and you need to define the data structure in exactly one source file.

In general, you can initialize a variable when you define it but not when you declare it. Use the extern qualifier to declare a global variable in those source code files that do not define the variable.

In one file, define the variable outside the scope of any function (i.e., a global variable). Use the volatile type qualifier to tell the compiler not to optimize away any reads because the value of this variable could change at unpredictable times (for example, in the interrupt handler).

volatile circular_buffer_type circularbuffer;


In the other file, declare the variable as extern, again outside the scope of any function. This allows the other file to access the same variable defined in the first file. Alternately, you could make this declaration in an .h file included by the other file.

extern volatile circular_buffer_type circularbuffer;


All accesses to this variable in the main code should be atomic to prevent variable corruption. For example, if your main code does a read-modify-write and the interrupt occurs between the read and the write then the main code's write would overwrite any changes that occurred in the interrupt handler. To prevent this situation, you could disable interrupts before the read and re-enable interrupts after the write in order to make the read-modify-write access atomic.