11 years, 8 months ago.

Issue with Serial Interrupt (attach() method)

Hey mbed programmers! I am trying to implemetn a method to interrupt a routine so that it pauses for some amount of time. I have managed to pause it for 1 minute and resumed after this time. however, i want to include an option to resume at any time during this 1 minute, but i cant achieve that the mbed gets interrupted for a second time while the first interruption is in course.

the code is like that

PAUSE

#include "mbed.h"

char intr;
void interrupted();
void resumed();

int main(){
    pc.attach(&interrupted);
    ...
}

void interrupted(){ //function called when the first interruption is recieved
    int it=60;
    intr=pc.getc();
    if (intr=='p'||intr=='P') { //pauses only if the character is a 'p' or a 'P'
        pc.printf("PAUSED",);
        //resume interruption
        pc.attach(&resumed);
        while((intr=='p'||intr=='P')&&it>0){ //the while loop that should get interrupted
            wait(5);                                    
            it-=5;                                     
        }                                               
        pc.printf("RESUME");             
    }                                     
}                                                      
                                                  
void resumed(){                              
    intr=pc.getc(); //it should change the value of intr and break the above while loop 
}

Thank you very much for the help!

2 Answers

11 years, 8 months ago.

Hi Rocket Team. Add "volatile" before "intr" definition to avoid optimizing. And turn on LED in "resumed" function.

11 years, 8 months ago.

A few things...

You want to periodically check for intr == 'P' in main() and put your while loop in a separate function, not in the ISR (the interrupted() function). You almost never want to have anything done in an ISR that could potentially take a large amount of time, or is blocking (i.e. waits on an external action indefinitely). So an ISR is not a great place for a routine that implements waiting :)

You also don't want to call printf() in an ISR because it is a non-reentrant function. If another printf() were in the middle of execution when the CPU was interrupted and jumped to your ISR, bad things could happen.

Like Takahiro mentioned, add the "volatile" specifier before your "char intr" declaration to force the CPU to read intr from memory each time it checks it against your conditions.

So in summary, you want to have a periodic check in your main() function for intr == a upper/lowercase letter P. If a P is detected, you can jump to a regular old function that does the waiting. In that function you can put your while loop that continues to spin as long as intr is still a P. The ISR can interrupt that function just fine, and if a non-P is read, you can jump back to your main() function.

Main thing is you don't want to spend a lot of time in an ISR.