atefsawaed
atefsawaed

Reputation: 603

Stopping a function currently running from an interrupt handler

Let's say I have two functions in C, a() and b(). And let's say I have two interrupts corresponding to both functions. The first interrupt should start running function a() and stop b() from running if it was interrupted during its run. Similarly, the second interrupt does the same thing for function b().

If I am currently running in a(), and I triggered the interrupt for b(). How can I start b() and prevent a() from completing after the interrupt handler finished?

The Code is as follows:

int main(void)
{
    Init();
    while (true)
    {
    if (run_A)
    {
      a();
      run_A = false;
    }
    if (run_B)
    {
      b();
      run_B = false;
    }   
}

void Handler(void)
{
    IntClear(interruptMask);

    if (INTERRUPT_FOR_A)
    {
        run_A = true;
    }

    if (INTERRUPT_FOR_B)
    {
        run_B = true;
    }
}

Upvotes: 3

Views: 2329

Answers (4)

Richard at ImageCraft
Richard at ImageCraft

Reputation: 665

Sounds like you are looking for a feature similar to coroutines. While not directly supported in C, you maybe able to implement a version good enough for your needs. As mentioned above, this will probably involve setjmp/longjmp or the mind-bending "Duff's Device" if you want to do it in portable C.

Upvotes: 0

Luis Colorado
Luis Colorado

Reputation: 12668

This is the kind of problem for which the setjmp(3)/longjmp(3) functions where designed in old UNIX(tm). You need to call setjmp(3) before entering the function you want to interrupt and in case the interrupt comes (you must ensure the interrupt is handled in the context of the function you are going to interrupt) then yo make a call to longjmp(3) and restore the stack at the point of the call.

Upvotes: 0

Rishikesh Raje
Rishikesh Raje

Reputation: 8614

I have a situation where b() calls a function that does some work that I don't need if I want to switch back to a(). I want to prevent it from happening when I call a(), and minimize the time it takes to start a()

Basically this situation will occur if INTERRUPT_FOR_B happens and a very short time later INTERRUPT_FOR_A happens, and if b() has a longer run time.

You need to carefully think about this situation and find out the chance of happening before doing premature optimizations.

But, if you want to go ahead, you can have some check points in the function b() to see if run_A is true.

e.g.

void b(void)
{
    // some code.
    if (run_A == true) return;
    // some code 
    if (run_A == true) return;
    // etc
}

Note that you need to properly analyze and test b function with all the return paths to ensure that this function runs properly in all cases.

Upvotes: 4

Lundin
Lundin

Reputation: 213989

Overall it isn't very meaningful to speak about this in general terms. It depends on your requirements and what kind of hardware that is generating the interrupt.

You can't/shouldn't just stop a function mid-execution. The best way to do this is either to keep the functions small and let the current one finish, or alternatively have the functions poll a flag variable repeatedly.

A more intrusive but simple method would be to simply shut off the undesired interrupt, but that might lead to loss of data. Depending on the nature of the interrupt, this may or may not be fine.

And then there are of course evil ways to set the PC manually with assembler or longjmp, but this is very bad practice and almost certainly the wrong solution to any problem.

Upvotes: 2

Related Questions