This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Returning from interrupt to a specified address in main

I'm quite new to context switch and embedded software development. I'm developing a standalone application (no OS) with aduc7026 and keil uVision3. My problem is that at the end of an uart messagge, which I must receive by interrupt, depending on the content of the messagge I've to return return in main in the state saved before entering in the ISR or I've have to return in a specified point where a funcion call is executed.

Hoping that I've been clear. Does anyone have suggestions?

Thank ìs in advance,

Matteo

Parents
  • I've have to return in a specified point where a funcion call is executed.

    Let me point out that for someone who's still quite new to the whole field of embedded SW, you hold some awfully firm beliefs about how you "have to" do things. That doesn't feel right.

    And no, you almost certainly (a) don't have to do that, nor (b) should be be trying to at this point on your learning curve. Stick to simpler designs until you really know what you're doing.

Reply
  • I've have to return in a specified point where a funcion call is executed.

    Let me point out that for someone who's still quite new to the whole field of embedded SW, you hold some awfully firm beliefs about how you "have to" do things. That doesn't feel right.

    And no, you almost certainly (a) don't have to do that, nor (b) should be be trying to at this point on your learning curve. Stick to simpler designs until you really know what you're doing.

Children
  • I try to explain better. When i receive a messagge i must restart from a specifc pOint since the messagge work like a reset command but due tO strict time requirements i can not perform a reset.

  • So you should then use a state machine. Let the states represent the task at hand. And when you receive commands, you can decide if the commands should be queued (or may even be processed instantly) or if the received command should place the state machine back into an initial state again.

    There just is no reason for trying to jump to absolute positions in the code. It is just an example of "I have a problem and want to run on the first idea I get even if it is a bad - or even nonworking - idea.

  • I agree with the others: this sounds like an awful way to structure a program.

  • I understand that it isn't the best way to structure a program but using state machine what happens if the main loop hang?

    Thanks to all for the useful messages and suggestions.

  • I've have to return in a specified point where a funcion call is executed.

    And no, you almost certainly ... should [not] be be trying to at this point on your learning curve.

    I would say this has nothing to do with the "point on your learning curve". I know of no technique that can do this safely, at least in C. I can visualize some "monkey code" in assembler that might make it 'work' in a non-mainatinable way.

    Erik

  • So I should implement a context switch to a specified point in assembly and add it to the c code? In the assembly code I should save the state in the specific point where I want to retur if specific messagge is received. Then if the messagge arrives I should Pop the stack with the saved information for the state where the interrupt wants to come back and load the state saved and set the program counter to the address of the saved state? Does This work and recover main from hangs? Don't care about the manteinment and portability of the code.

  • but using state machine what happens if the main loop hang?

    If understand this correctly, your main loop is too slow to ensure a fast enough response to a message. Use interrupts then. Structure the fast message handler as an ISR and trigger the corresponding interrupt when you receive the message. Assign interrupt priorities accordingly.

  • "If understand this correctly, your main loop is too slow to ensure a fast enough response to a message. "

    The problem isn't the speed but the fact that receving a messagge is more important than executing other task.

    " Use interrupts then. Structure the fast message handler as an ISR and trigger the corresponding interrupt when you receive the message. Assign interrupt priorities accordingly. "

    This is a nice solution, however doesn't meet the requirements to restart from that function because after the interrupt the execution restart from the point where the code was executing...

  • So I should implement a context switch to a specified point in assembly and add it to the c code?

    No, you shouldn't. And I find it really hard to see how you arrived at that conclusion from the advice you've been given here. It's a Bad Idea(no TM).

    You appear to be going at this from entirely the wrong angle. The cure you're trying so very hard to administer is almost certainly worse than the possible problem you're worried about. It's quite possible that this crazy technique not only won't help if main is unstable, but it's actually going to make it unstable.

  • This is a nice solution, however doesn't meet the requirements to restart from that function because after the interrupt the execution restart from the point where the code was executing.

    If you have this kind of a problem, then your program is a mess already. Adding another layer of mess might make it work, but the whole thing won't be pretty.
    A clean rewrite is not an option, is it?

  • I understood all of your suggesttions and i'm gratefull to all. However my supervisor insist to force me to the inyours opinions bad solution... So i'll have meeting with it tomorrow where I can spek with it about other possible solutions... Thanks to all
    Matteo

  • 10 tips.

    1 state machine.
    2 state machine
    3 state machine
    4 state machine
    5 state machine
    6 state machine
    7 state machine
    8 state machine
    9 state machine
    10 stat machine

    The loop running the state machine steps will not hang unless you introduce bugs or the hardware suffers problems.

    Long tasks can be splitted into multiple steps, making them breakable before they are fully done.

    Task switches are for running multiple jobs concurrently - most environments cant survive that you kill/restart at arbitrary place becauce of atomicity reasons.

    If you still manage to.hang your main loop, then you have no real option but a (watchdog) reset. The reason is that you have then managed to put the processor in a state where it can't be trusted.

    The choice is yours. Solving a problem the established way, or assume your problem is unique and implement a spaghetti failure you will spend the next couple of years trying to get reliable.

  • Perhaps your supervisor could come and join this discussion...?

    Either you have badly misunderstood/misinterpreted what (s)he's telling you, or (s)he is giving you bad advice!

  • Your supervisor is either a skilled developer, or (s)he isn't.

    If skilled, then I'm convinced you have misunderstood something. If not, then it's time you suggest he/she switches from supervisor to developer and implements the failure.

    The closest you can expect to get directing further evaluation from an interrupt is with a RTOS. An interrupt can tell the scheduler that it should perform a rescheduling. Such a rescheduling will mean that the program doesn't return to the same place it was before the interrupt. But it does not jump to a fixed address. Instead it jump to the current location of that other thread.

    So if you do get a rescheduling to a thread that was already busy with a long command, that command will have to be computed to the end (unless you have state machines within the threads). The scheduler will only switch to that thread if it had the highest priority. But if it had, then you wouldn't even need any rescheduling because then the thread was already busy with the previous command when the interrupt came.

    In the end, you either have commands that are fully processed before the processor reschedules. Or you have one or more state machines, where you can force a restart of a state machine.

    Note that restarting a state machine from an ISR can't be done by just assigning a new value to the state variable. The reason is that the ISR may be activated while the state machine is busy handling state x, and the state machine may after the ISR process a source line that assigns a new state, overwriting the expected new state from the ISR. So having a ISR forcing a new state should be done by setting a separate variable "force_state", and the state machine should check this variable to see if it should switch state at the top or bottom of the state machine loop. In some situations, you may even need cleanup states.

    Any attempts to have an ISR force a fixed return address will end with a black eye and a bloody nose. A C compiler expects that a single thread is always executed sequentially without anything interfering. And ISR or OS scheduler must be written to be invincible. They may "pause time" for a task, but execution must return at the exact same place with all registers and relevant variables in their known states. If not, then your program will not fulfill the requirements of the C standard, and all bets are off what will really happen. You would then have introduced a number of random dices giving you percentages on an infinite number of potential failures in your code.

    In reality, you will get the same if the main program is written in assembler. The reason is that no normal human developer can write code while assembler instruction by assembler instruction all the time think about the concept of the execution breaking at an arbitrary position just to jump to another position.

    State machines have the advantage that they only switch action between two states. So the states can be documented. And it's possible to keep track of what happens when breaking between two states since the behaviour of the program will follow the C rules.

  • " Use interrupts then. Structure the fast message handler as an ISR and trigger the corresponding interrupt when you receive the message. Assign interrupt priorities accordingly. "

    This is a nice solution, however doesn't meet the requirements to restart from that function because after the interrupt the execution restart from the point where the code was executing...
    yes, it does for ONE instruction and then it executes "the fast message handler as an ISR "

    Erik