| Subject: |
|
Re: New port questions |
| Name: |
|
Mike |
| Date Posted: |
|
Apr 18, 08 - 2:33 PM |
| Email: |
|
delsauce@hotmail.com |
| Message: |
|
OK, I've dug into this a bit more and found some good info that will hopefully help others port to coldfire.
My previous post was correct, the STLDSR instruction will load the status register and save the current value so that interrupts can be disabled in one go.
However, upon looking at the code that the compiler was generating for an ISR, I noticed that this instruction was already be placed at the top of the interrupt. The compiler masks all interrupts by default if you declare the ISR in the following way:
__declspec(interrupt) void ISR_NAME()
If you don't want interrupts disabled by default you need to tell the compiler what value you want loaded into the status register on entry into the ISR (if any):
__declspec(interrupt:0) void ISR_NAME() - doesn't touch the satus register at all, while:
__declspec(interrupt:XXXX) void ISR_NAME() - loads the status register with the value XXXX.
SO, with all that info, my QK_ISR_ENTRY() macro looks like this:
#define QK_ISR_ENTRY(level) do { \
QK_intNest_++; \
SetInterruptMaskLevel(level); \
} while (0)
Now, interrupts are off when QK_intNest is incremented. They are then restored to the appropriate level before normal interrupt processing resumes.
QK_ISR_EXIT() macro looks like this:
#define QK_ISR_EXIT() do { \
asm \
{ \
stldsr #0x2700 \
} \
QK_intNest_--; \
QK_SCHEDULE_(); \
} while (0)
Interrupts are disabled before the QK_intNest variable is touched, then the scheduler is called.
I think that the race condition is now avoided and interrupts can be nested. Anyone out there see a problem with this or perhaps I am missing something?
Mike |
|
Replies:
|
|
|
|
|