Hi everyone,
My weird programming style has led me to a problem. I don't know if it's possible or not but here it is. As far as I know normally when an ISR fires, upon it's completion it goes back to the area of code where the interrupt occurred.
Here is my case it goes back to task_A function (which is just main() while loop), all good till here. But there is a condition, which is that on completion of every 15th interrupt it must return ( or go ) to task_B function before going back to task_A and while this is happening, the interrupts must go on, even in task_B.
Following is the dummy code to create the scenario.
#include <avr/io.h> #include <avr/interrupt.h> inline void task_A(void) { __asm__ __volatile__ ("nop"); } void task_B(void) { __builtin_avr_delay_cycles(2000); // Simulating some work to do } ISR(TIMER1_COMPA_vect) { static uint8_t count = 0; __asm__ __volatile__ ("nop"); // Pretending to do some critical work here if(++count == 15) { count = 0; // On every 15th interrupt, count resets to zero return (task_B()); // I know this is a bad idea. Just so that you get the picture. } } int main(void) { OCR1A = 1600; TIMSK1 |= (1 << OCIE1A); TCCR1B |= (1 << WGM12) | (1 << CS10); sei(); while (1) { task_A(); } }
I can't really put the contents of the task_B in the ISR itself, because the interrupt is occurring in every 1600 clock cycles and task_B will take more than 1600 clks. I tried doing return (task_B()); with this interrupts don't happen in task_B and more PUSH/POP's happen for the interrupt. In simple words how to conditionally insert the task_B function in between the path of returning from ISR to task_A at the point where it left off, without ever stopping or missing an interrupt.
I hope I cleared everything in detail. If there is a another way to implement this logic, please let me know.
Thank you.