I'm trying to better understand the interaction between the foreground (interrupt) and background (while (1)
) loops in a PIC microcontroller. Specifically, a PIC16F1709 using XC8 v1.33. This documentation helps a bit, but I'm more interested in things at a C level (and less so hardware or assembly).
I know that we can neither return nor accept any parameters, so the only way to interact with the interrupt is with a global or module-level variable. Is it also true that we do NOT have any stack available to us in an ISR? So no local variables can be declared? Or is stack defined as depth of function calls?
My use of another function MY_FIFO_Push
(while I know bad for ISRs), will consume some stack to pass the variables. I don't understand how this is working.
static volatile my_fifo_t my_fifo;
void MyIsr(void) {
static uint8_t new_byte;
// Grab a result from a hardware register
new_byte = XXXRES;
// Push the result onto a queue to be processed in background loop
MY_FIFO_Push(&my_fifo, new_byte);
// Clear the source of the interrupt
XXXIF = 0;
}
...
void main(void) {
while (1) {
// Process the FIFO queue in the background loop
// If there is new data on the queue
// Consume it
}
}
Best Answer
Most Microchip PIC 8-bit micros have a hardware stack with a depth of only 8! (the size will vary for different PIC devices). Because the stack depth on these micros is so small it is used only for function calls. Each function call will consume one level of the hardware stack. The rest of the variables are pushed into a software stack which is automatically handled by the compiler.
So having an interrupt will automatically consume 1 level of the stack. Of course you can have variables declared in your interrupt, but they will be pushed into the software stack by the compiler.
Your microcontroller (PIC16F1709) has a 16-level hardware stack, which is a fairly good depth. In your sample code you only use 2 levels of the stack: one for the ISR and one for the
MY_FIFO_Push
function call from the ISR. So you're left with 14 more levels for nested function calls.From Embedded Systems/PIC Microcontroller:
From PIC stack overflow (if you read this article you might not want to use PICs in future projects. It hasn't stopped me, though :-) ):