* [ECOS] Cortex-M3 interrupt handling & context switching
@ 2008-10-06 16:42 simon.kallweit
0 siblings, 0 replies; only message in thread
From: simon.kallweit @ 2008-10-06 16:42 UTC (permalink / raw)
To: eCos Disuss
Hi
After getting rid of some more toolchain troubles I'm again faced with
the proper implementation of interrupt handling and context switching.
I'm still a bit puzzled, and would really appreciate some help, if
anyone knows a bit of the Cortex-M3 architecture and the ecos kernel. I
would like to use the Cortex's feature of saving/restoring some of the
processors state automatically when entering/leaving exceptions (namely
pc, lr, r12, r0-r3). This would also determine the bottom half of the
HAL_SavedRegisters type:
typedef struct
{
// Additional states
cyg_uint32 basepri; // Base priority
cyg_uint32 r4, r5, r6, r7, r8, r9, r10, r11; // Data registers
cyg_uint32 lr_exc; // Link register in
exception context
// Handled by exception handler
cyg_uint32 r0, r1, r2, r3; // Data registers
cyg_uint32 lr_thd; // Link register in
thread context
cyg_uint32 pc; // Program counter
cyg_uint32 xpsr; // Condition register
} HAL_SavedRegisters;
The context switch can then be implemented using a system service call
(SVC). Calling the context switch from within a thread would
automatically push half of the processor state to the thread's stack on
exception entry and pop on exit. Switching stacks, and pushing/popping
the rest of the registers can be done in the SVC handler. The initial
load of the first context would have to be handled in a special case,
popping the complete processor state without a SVC call. Does this make
sense to you?
Interrupts are also handled as exception on the Cortex-M3, so on
entering/leaving an interrupt, half of the processor state is also
saved/restored automatically. Interrupts can be preempted by higher
priority interrupts, which pushes a new stack frame. Also, multiple
interrupts can be tail-chained, which drops the pop/push of the stack
frame for more efficiency. My current approach would look something like
this:
- exception entry
- mask higher priority interrupts if nesting is disabled and store
current priority on stack
- store additional processor state if necessary
- determine interrupt vector
- call respective interrupt handler
- call interrupt_end() -> may switch contexts
- restore additional processor state
- restore interrupt priority
- return from exception
As SVC would be of higher priority than any other interrupt exception,
the call to the SVC would always preempt and create a new stack frame,
and successfully switch contexts. Do you think this should work?
One problem I see, is when enabling interrupt nesting. As soon as a
higher priority interrupt preempts a lower priority one, and leads to a
context switch, the lower priority interrupt can be delayed for quite a
while. The Cortex-M3 offers the PendSV exception, which can be run at
the and of nested, or tail-chained exception handling, offering a good
point for the scheduler to switch to the highest priority thread. But as
I see it, ecos needs a call to interrupt_end() for every processed
interrupt, possibly leading to a context switch. We could increment
cyg_scheduler_sched_lock before entering interrupt_end() to prevent a
context switch. Then we could call the scheduler
(Cyg_Scheduler::unlock()) from the PendSV handler. Is this possible?
Providing a separate interrupt stack could pretty easily achieved, as
the Cortex-M3 provides two separate stack pointers, which can be swapped.
Anyway, this is how I currently look at the subject. Comments, critics,
hints are highly welcome.
Best regards,
Simon
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-10-06 16:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-06 16:42 [ECOS] Cortex-M3 interrupt handling & context switching simon.kallweit
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).