rtel wrote on Thursday, May 31, 2007:
> Hi Dave!
> Thanks for your explanations. Unfortunately I am unsure of a
> few things concerning
> interrupt handling and I am hoping you can help me on this.
> At the moment I am using isrs the following way: An interrupt
> activates an interrupt
> handler, which runs portSAVE_CONTEXT and then jumps to a c
> interrupt handler,
> which puts an item in a queue, which activates a high
> priority task. After the
> c interrupthandler returns to the asm wrapper,
> portRESTORE_CONTEXT is being
> run.
From this snippet it sounds like you are using IAR, as GCC does not require the asm wrappers. If so your description is correct.
> In my c interrupthandler I use portEND_SWITCHING_ISR to
> activate the high
> priority task. All interrupts have the same priority, so no
> nested interrupts
> should occur. Now there are two things which I do not understand:
> Does portEND_SWITCHING_ISR immediately switch to the
> activated high priority
> task, which makes its work, and then returns to the c
> interrupthandler
Again, assuming IAR, then the answer is really no. portEND_SWITCHING_ISR just tells the scheduler that it might need to select a new task to run, as the interrupt itself has unblocked a task. In this case portEND_SWITCHING_ISR is just a sequential function call, its just like calling any other function from within an interrupt.
If the unblocked task has the highest priority of all ready tasks then the scheduler will decide that this is the task that should be executed next.
> or does
> it make sure that after the c interrupthandler and the asm
> wrapper the high
> priority task gets activated?
That is correct. portEND_SWITCHING_ISR has told the scheduler to check which is the highest priority ready task. The asm wrapper at the end of the interrupt causes the processor to start executing the task selected by the scheduler.
Say task A has a priority of 0 and is running, task b a priority of 1 and is blocked:
1) An interrupt executes, interrupting task A. The asm wrapper saves the context of task A and the interrupt C code then runs.
2) The interrupt C code wakes task b, which has a priority higher than A.
3) portEND_SWITCHING_ISR() is called, this causes the scheduler to recognise that task A is now in the ready state, and that it has a priority higher than task b.
4) The asm wrapper executes, causing the ISR to restore the context of (and start running) task B.
> What exactly do the portSAVE_CONTEXT and portRESTORE_CONTEXT
> macros do? Since
> I am using an AT91SAM7X and the uIP demo, I have only the
> EMAC interrupt as
> an example and in this it is done exactly as I do it now.
> Maybe I can have the
> interrupts handled faster without the asm wrapper or the
> portEND_SWITCHING_ISR
> macro? I think I read in the description of another port that
> interrupts have
> to be handled with an asm wrapper but in this port there is
> no really explanation
> of the interrupts other than the EMAC example.
The asm wrapper is only required if you want to return directly into another task. In the example above, the interrupt interrupted task B, but returned to task A. This is what you want if task A is urgent.
If task A is not urgent then the asm wrapper can be removed and the interrupt written as per the IAR documentation. In this case task A is put into the ready state and, as the higher priority task, will get selected the next time the tick interrupt occurs or task b blocks or yields.
Regards.