This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR5969: Is is possible to make changes to the return address of ISR?

Part Number: MSP430FR5969

Hi,

On my MSP430FR5969, I've written a code where, an interrupt is triggered when a key is pressed.

However, as per my needs, I want that after every interrupt(ISR) segment execution, I want a specific function to be executed.

One way to do so would be calling the function in ISR. However since the function is large enough, that isn't a thing I want to do. 

I've discovered that another way to do so would be modifying the return address. Can someone point me out, how to achieve so?

Is there some other way to achieve my task?

I can't use a set-a-flag-in-isr based thing. The function needs to be called immediately after ISR execution. The code should forget everything, and do the special function.

An example:

 

ISR Segment
{
//Execution of ISR
//Sets some value to flag variable.
}

void Special_Emergency_Func()
{
//This is  a large function to be executed on priority on every time ISR is executed
}

 

void main(void)
{
//init MSP430 modules
   while(1)
   {
      if(flag == x)
      {
      //execute this large part
      //these segments are quite big. 
      //It takes a lot of time before code checks for flag value once again, after interrupt.
      }

 
      else if(flag == y)
      {
      //execute this large part
      //these segments are quite big. 
      //It takes a lot of time before code checks for flag value once again, after interrupt.
      }
   }
}

  • Does "forget everything" imply that the old code that was interrupted should not continue after the specific function has finished?

    And what should happen if the special function is already being executed?
  • I am sorry that I have confused you. What I mean is, The special function should be executed immediately, after ISR return. Once the special function is finished then the code can resume the main's while segment. In simpler words, the special_function has a higher priority than main's while segment when interrupt occurs.
  • An RTOS would be able to schedule tasks.

    If you do not want to use an RTOS, you have to implement this manually. The ISR must check if the special function is already running. If not, change the stack so that it looks as if the special function was called. (The compiler makes assumptions about what registers can be used without saving them, you the special function probably needs to be declared an interrupt handler, and the stack adjusted accordingly.)
  • If it *has* to be called immediately after the ISR, you might as well call it from the ISR
  • "One way to do so would be calling the function in ISR. However since the function is large enough, that isn't a thing I want to do. "

    Calling a large function in ISR would increase the time for execution of ISR. The application can't afford to loose to many clock cycles in one interrupt.

  • I am sorry, I can't use an RTOS. I'd like to go via the stack modification method. Since, I haven't done before, could you please point me in the right direction? Maybe a code example for MSP430FR5969 or suggested read/article?
  • You are the one that said that "special function should be executed immediately, after ISR return", If it has to be called after every ISR, you are going to waste the clock cycles anyway.
  • Inside the actual interrupt handler, the stack looks like this:

         ...
         stack data from main loop
         PC (where main loop was interrupted)
         SR (of main loop)
         register(s) saved by the interrupt handler
    SP → additional stack data of the interrupt handler

    To make the interrupt handler return to the other function, you have to change the return address, and modify the stack so that the other function will return to the main loop:

         ...
         stack data from main loop
         PC (where main loop was interrupted)
         SR (of main loop; this assumes the extra function is declared as an interrupt handler)
         PC (beginning of the extra function)
         SR (for the extra function)

         register(s) saved by the interrupt handler
    SP → additional stack data of the interrupt handler

    The stuff below the last saved SR is annoying (because you do not know what exactly the compiler does); you probably should write the interrupt handler in assembler so that you have control what it pushes on the stack. (And if you're already using assembler, instead of pushing PC/SR of the extra function, you could just change SR to re-enable interrupts, and jump to the extra function).

  • I don't know what you mean by "waste the clock cycles". I thank you for your effort to help me out but I think you are confused.
    Afaik, calling a function in ISR, isn't the same as calling it outside an ISR(say from main).
    Calling a function, in ISR, means giving more time for the return of ISR, which in turn keeps the other interrupts waiting. Say, if I call the function from main, I wouldn't be putting other interrupts at wait. Which, is of course, one way to do it. But, as said earlier, it has it's own drawback an doesn't serves my purpose.
  • What keeps the other interrupts waiting is just that the global interrupt enable flag (GIE) is cleared. You could simply set it inside the interrupt handler before calling that function (and then you have to be prepared for recursive interrupts).

**Attention** This is a public forum