Forums

LPC2366: Question about UART interrupt which goes into DAbt_Handler

Started by abracadalba November 21, 2007
> > It's provided with CrossWorks and fully documented. It's not a
> generic GNU
> > thing.
> >
>
> Thank you Paul :-).
> Unfortunately, we have already started our project
> using Keil+GCC, thus I don't think we can now change
> our IDE in order to buy CrossWorks...
> Thank you very very much, anyway!
>
> Does someone know if exist another way achieve
> the results of the functionalities we are talking
> about?
>
> **************
> ** If does not exist, I am wrong if i tell that using
> ** only GCC I can't manage correctly ISRs?
> **************
>

I'm coming into this thread without having read its beginning, so I might be
off topic.

You are declaring the IRQ naked and then providing your own prologue and
epilogue code through the use of the macros - but do these macros setup a
stack frame? Probably not as they don't know how big a stack you require.
You state that you have a local variable, but where is this variable ending
up in RAM?

The easiest way of ensuring correct behaviour, but not the most efficient
way, is to split the ISR into two, a wrapper and a handler, as follows:

void vAnISRWrapper( void ) __attribute__((naked));
void vAnISRHandler( void );

void vAnISRWrapper( void )
{
____SAVE_CONTEXT(); /* Prologue macro. */

____/* Call the handler function. No stack is required
____by the wrapper as all it does is perform a branch. */
____vAnISRHandler();

____RESTORE_CONTEXT(); /* Epilogue macro. */
}

void vAnISRHandler( void )
{
____/* Function that actually does the ISR work. If
____declaring a local variable here then the *compiler*
____will ensure there is stack allocated during the
____compiler generated function prologue. */

long lAVariableDeclaredLocally;

____/* The variable can be accessed safely. */
____lAVariableDeclaredLocally = 0;

____/* Clear the interrupt before exiting the function! */
}
Regards,
Richard.

+ http://www.FreeRTOS.org
14 official architecture ports, 1000 downloads per week.

+ http://www.SafeRTOS.com
Certified by T as meeting the requirements for safety related systems.



An Engineer's Guide to the LPC2100 Series

On Mon, 26 Nov 2007, abracadalba wrote:

> Because the external function is a *normal* function, it is
> Interruptible by other ISRs, even from ISRs which priority is less
> then the priority of the ISR we are coming from. In order to
> completely manage prioritized nested interrupts, now is required a bit
> of code for managing the priority, in order to disable interrupts with
> priority less or equal than the ISR we are coming from.

Nah, that's what the VIC handles for you. In each of my ISRs, in every
(well, "most") of my interrupt handlers, after getting the cause of, then
clearing the source of the interrupt, I re-enable higher-priority (by VIC
lookup-table entry) interrupts (by dropping 0x0 in the VICVectReg).

I have code similar to yours that runs IRQs as regular functions in SVC
mode.

-Kenny

--
Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Los Angeles
O: 3630 S. Sepulveda Blvd. #138, L.A., CA 90034-6809 (888) 454-8181
> I'm coming into this thread without having read its beginning, so I
might be
> off topic.
>
> You are declaring the IRQ naked and then providing your own prologue and
> epilogue code through the use of the macros - but do these macros
setup a
> stack frame? Probably not as they don't know how big a stack you
require.
> You state that you have a local variable, but where is this variable
ending
> up in RAM?
>
> The easiest way of ensuring correct behaviour, but not the most
efficient
> way, is to split the ISR into two, a wrapper and a handler, as follows:
>
> void vAnISRWrapper( void ) __attribute__((naked));
> void vAnISRHandler( void );
>
> void vAnISRWrapper( void )
> {
> ____SAVE_CONTEXT(); /* Prologue macro. */
>
> ____/* Call the handler function. No stack is required
> ____by the wrapper as all it does is perform a branch. */
> ____vAnISRHandler();
>
> ____RESTORE_CONTEXT(); /* Epilogue macro. */
> }
>
> void vAnISRHandler( void )
> {
> ____/* Function that actually does the ISR work. If
> ____declaring a local variable here then the *compiler*
> ____will ensure there is stack allocated during the
> ____compiler generated function prologue. */
>
> long lAVariableDeclaredLocally;
>
> ____/* The variable can be accessed safely. */
> ____lAVariableDeclaredLocally = 0;
>
> ____/* Clear the interrupt before exiting the function! */
> }
> Regards,
> Richard.

Hello to everyone,
and thank you all for your answers.
In effect, you are right: the problem was in the managing of
local variables IN THE CASE THERE WILL BE NESTED INTERRUPTS.
I've seen this disabling all the interrupts except the UART ISR,
making it work very slowly, and tracing the entry/exit to/from the ISR.
As you suggest, a safe mode to correctly manage this behaviour is
to call an extern function (thanks Richard!) which safely manages
local variables.

Because the external function is a *normal* function, it is
Interruptible by other ISRs, even from ISRs which priority is less
then the priority of the ISR we are coming from. In order to
completely manage prioritized nested interrupts, now is required a bit
of code for managing the priority, in order to disable interrupts with
priority less or equal than the ISR we are coming from.
What do you think? Am I wrong?

Thank you very much for your answer, again.