EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Debugging interrupt service routine with Crossworks NOT using tasking library

Started by Markus Zingg February 18, 2008
Hi all,

I'm having trouble here with making some sample code from NXP (the EMAC
sample actually) work in crossworks. After first using the tasking
library functions to setup IRQ I ended up in a situation where I could
place a breakpoint within the ISR and execution halted. However, the
system always hung sooner or later when debugging, stack was corrupted
after calling the isr and all kind of other very spookey problems were
observed.

I now changed the code not to use the tasking library at all. This made
it absolutely stable. The isr routine is called, but when I set a
breakpoint in there, the debugger does not stop.

Could it be that the instability was caused by the debugger stub used?
What would I have to initialize to make the crossworks debugger let me
debug the isr?

TIA

Markus
PS: I gather that there is a public holiday in the US, is the same true
for the UK?

An Engineer's Guide to the LPC2100 Series

Markus,

> I'm having trouble here with making some sample code from NXP (the EMAC
> sample actually) work in crossworks. After first using the tasking
> library functions to setup IRQ I ended up in a situation where I could
> place a breakpoint within the ISR and execution halted. However, the
> system always hung sooner or later when debugging, stack was corrupted
> after calling the isr and all kind of other very spookey problems were
> observed.
>
> I now changed the code not to use the tasking library at all. This made
> it absolutely stable. The isr routine is called, but when I set a
> breakpoint in there, the debugger does not stop.

You have two hardware breakpoints. Use them wisely! Look at the
Breakpoints window and ensure that the breakpoint is set, i.e. the red
breakpoint icon doesn't hae a question mark on it.

> Could it be that the instability was caused by the debugger stub used?
> What would I have to initialize to make the crossworks debugger let me
> debug the isr?

ISRs are no different to regular code. You don't need to do anything.

> PS: I gather that there is a public holiday in the US, is the same true
> for the UK?

Nope, we're all working.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
Paul,

Thanks for your quick reply. I do use the hardware breakpoints and code
execution still does not stop there. There is no question mark on the
red dot. In fact, the breakpoint in the isr is the only one I use. I'm
aware that single stepping uses the second one (at least I figure this
is the case cause if I set a second one, single stepping results in an
error message). Any other ideas?

Markus

Paul Curtis schrieb:
>
> Markus,
>
> > I'm having trouble here with making some sample code from NXP (the EMAC
> > sample actually) work in crossworks. After first using the tasking
> > library functions to setup IRQ I ended up in a situation where I could
> > place a breakpoint within the ISR and execution halted. However, the
> > system always hung sooner or later when debugging, stack was corrupted
> > after calling the isr and all kind of other very spookey problems were
> > observed.
> >
> > I now changed the code not to use the tasking library at all. This made
> > it absolutely stable. The isr routine is called, but when I set a
> > breakpoint in there, the debugger does not stop.
>
> You have two hardware breakpoints. Use them wisely! Look at the
> Breakpoints window and ensure that the breakpoint is set, i.e. the red
> breakpoint icon doesn't hae a question mark on it.
>
> > Could it be that the instability was caused by the debugger stub used?
> > What would I have to initialize to make the crossworks debugger let me
> > debug the isr?
>
> ISRs are no different to regular code. You don't need to do anything.
>
> > PS: I gather that there is a public holiday in the US, is the same true
> > for the UK?
>
> Nope, we're all working.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
>
Hi Markus,

> Thanks for your quick reply. I do use the hardware breakpoints and code
> execution still does not stop there. There is no question mark on the
> red dot. In fact, the breakpoint in the isr is the only one I use. I'm
> aware that single stepping uses the second one (at least I figure this
> is the case cause if I set a second one, single stepping results in an
> error message). Any other ideas?

Make sure you have debug information enabled--you get blue triangles next to
the lines that can have breakpoints set on them when you run. Clear all
your breakpoints and navigate to your ISR code--do you see a blue triangle
next to the line you want to break on?

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
Paul,

The configuration used to build the porject reads "ARM Flash Debug" in
CrossStudio. I hope this leads to what you refer to with "have debug
information enabled". I do see the blue triangle on the line I like to
stop in the isr. Unfortunately still no joy. Stopping on any other line
(not part of the isr) havnig a blue triangle works just fine.

Markus

PS: I sent you three mails off list. Do you get my off list e-mails?

Paul Curtis schrieb:
>
> Hi Markus,
>
> > Thanks for your quick reply. I do use the hardware breakpoints and code
> > execution still does not stop there. There is no question mark on the
> > red dot. In fact, the breakpoint in the isr is the only one I use. I'm
> > aware that single stepping uses the second one (at least I figure this
> > is the case cause if I set a second one, single stepping results in an
> > error message). Any other ideas?
>
> Make sure you have debug information enabled--you get blue triangles
> next to
> the lines that can have breakpoints set on them when you run. Clear all
> your breakpoints and navigate to your ISR code--do you see a blue triangle
> next to the line you want to break on?
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
>
Markus,

> The configuration used to build the porject reads "ARM Flash Debug" in
> CrossStudio. I hope this leads to what you refer to with "have debug
> information enabled". I do see the blue triangle on the line I like to
> stop in the isr. Unfortunately still no joy. Stopping on any other line
> (not part of the isr) havnig a blue triangle works just fine.

So, do you know that the ISR is firing? Breakpoints are set without knowing
whether it's an ISR or not. If you're not stopping then the ISR is probably
not firing. If there is a solid red breakpoint marker in the margin when
the program is running then it means the breakpoint is correctly set. You
can hover over the breakpoint icon in the margin to see where it's set.

> PS: I sent you three mails off list. Do you get my off list e-mails?

Yes, but not all of them needed a response...

-- Paul.
Markus,

> I admit, I understimated this IRQ stuff on the ARM. Seems to be a
> totally different beast than what I've been used before. Anyways, I
> read
> the user manual about the embedded ICE logic and re-read the charpter
> about the VIC, and this made it clear to me that the ARM does not need
> to call an IRQ or need to execute some internal monitor code as its the
> case on some other architectures to be stopped for debugging when the
> hardware breakpoints are used. Alas, you (Paul) are right that the IRQ
> routine is not called.
>
> I was missleaded here because the EMAC was sending out packets like
> hell
> - aparently without calling the isr. I somehow was under the wrong
> assumption that the isr would be part of the sending process. After
> thinking about it more closely it became aparent that the isr from the
> point of view of the EMAC is optional.
>
> Ok, I umasked the interrupt in the cpsr register which I have missed
> bevore, now the IRQs are "fired", but since I'm not using the ctl
> library, it seems like no IRQ handling code (the code that reads out
> the IRQ vector and branches to the routine I installed in the vector) is
> linked in.

You should use ctl_set_isr and the appropriate stl_unmask_isr (IIRC).
Although this says "CTL" at the beginning, interrupt handling and setting
handlers is independent of any of the "tasking". In the next release it
will be renamed as the CrossWorks Target Library to reinforce the fact that
tasking is optional.

> So, any pointer to such code anyone? I looked in various startup files
> from other ARM compiler envireonements but haven't found this part. I
> will continue to search for this, try to write my own if needed, but I
> obviousely would apreciate to save the time to do so.

If you created the project using the New Project wizard then you'll have the
VIC handling code already placed into your project, you just need to use it.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
I admit, I understimated this IRQ stuff on the ARM. Seems to be a
totally different beast than what I've been used before. Anyways, I read
the user manual about the embedded ICE logic and re-read the charpter
about the VIC, and this made it clear to me that the ARM does not need
to call an IRQ or need to execute some internal monitor code as its the
case on some other architectures to be stopped for debugging when the
hardware breakpoints are used. Alas, you (Paul) are right that the IRQ
routine is not called.

I was missleaded here because the EMAC was sending out packets like hell
- aparently without calling the isr. I somehow was under the wrong
assumption that the isr would be part of the sending process. After
thinking about it more closely it became aparent that the isr from the
point of view of the EMAC is optional.

Ok, I umasked the interrupt in the cpsr register which I have missed
bevore, now the IRQs are "fired", but since I'm not using the ctl
library, it seems like no IRQ handling code (the code that reads out the
IRQ vector and branches to the routine I installed in the vector) is
linked in.

So, any pointer to such code anyone? I looked in various startup files
from other ARM compiler envireonements but haven't found this part. I
will continue to search for this, try to write my own if needed, but I
obviousely would apreciate to save the time to do so.

TIA

Markus

Paul Curtis schrieb:
>
> Markus,
>
> > The configuration used to build the porject reads "ARM Flash Debug" in
> > CrossStudio. I hope this leads to what you refer to with "have debug
> > information enabled". I do see the blue triangle on the line I like to
> > stop in the isr. Unfortunately still no joy. Stopping on any other line
> > (not part of the isr) havnig a blue triangle works just fine.
>
> So, do you know that the ISR is firing? Breakpoints are set without
> knowing
> whether it's an ISR or not. If you're not stopping then the ISR is
> probably
> not firing. If there is a solid red breakpoint marker in the margin when
> the program is running then it means the breakpoint is correctly set. You
> can hover over the breakpoint icon in the margin to see where it's set.
>
> > PS: I sent you three mails off list. Do you get my off list e-mails?
>
> Yes, but not all of them needed a response...
>
> -- Paul.
>
>
Paul,

I created a new project with the Project Wizzard to be on the save side
and added the three small source files (emac.c emactest.c and crc32.c).
Crossworks now included VIC controll code. I'm now back to using the
fuctions you suggested (see below). Unfortunately I'm also back to the
problems....

I meanwhile spent close to two weeks on getting this code to work
reliable. Lacking experinece with Crossworks and the LPC2378 I first
misinterpreted a lot of things, but I now can say that as soon as the
isr routine GETs called, things go highwire on return from the isr. I
thus wonder what could go wrong by using

ctl_set_isr( );
ctl_global_interrupts_enable();
ctl_unmask_isr( );

to setup the isr routine and enable the interruts and by using an isr
routine declared as

extern __attribute ((interrupt ("IRQ" ) )) void EMACHandler( void );

so badly that on return from the isr, local variables in the fuction
that was interrupted (actually a simple sending loop) point to the nirvana?

The isr code does not copy memory around nor does it other stuff that
could be dangerous. It mainly increases statistics counters acroding to
the kind of interrupt and sets the MAC_INTCLEAR register accordingly. I
commented out the calls for nested interrupts (cause I don't want to add
complexity at this point in time).

I'm really new to the ARM and Crossworks, I'm not lazy and willing to
work to get this going, but it seems a truly steep entry here. Is there
a way I can get help with that relatively small sample? Can I send the
code (well, did that alredy with no reply at all)? I'm willing to pay
for a solution if needed, cause I'm starting to get under pressure from
all sides. Are you so absolutely sure that nothing could be wrong with
the isr dealing code in Crossworks? What do you suggest I can do to
finally get over all this and move on?

TIA

Markus

Paul Curtis schrieb:
>
> Markus,
>
> > I admit, I understimated this IRQ stuff on the ARM. Seems to be a
> > totally different beast than what I've been used before. Anyways, I
> > read
> > the user manual about the embedded ICE logic and re-read the charpter
> > about the VIC, and this made it clear to me that the ARM does not need
> > to call an IRQ or need to execute some internal monitor code as its the
> > case on some other architectures to be stopped for debugging when the
> > hardware breakpoints are used. Alas, you (Paul) are right that the IRQ
> > routine is not called.
> >
> > I was missleaded here because the EMAC was sending out packets like
> > hell
> > - aparently without calling the isr. I somehow was under the wrong
> > assumption that the isr would be part of the sending process. After
> > thinking about it more closely it became aparent that the isr from the
> > point of view of the EMAC is optional.
> >
> > Ok, I umasked the interrupt in the cpsr register which I have missed
> > bevore, now the IRQs are "fired", but since I'm not using the ctl
> > library, it seems like no IRQ handling code (the code that reads out
> > the IRQ vector and branches to the routine I installed in the vector) is
> > linked in.
>
> You should use ctl_set_isr and the appropriate stl_unmask_isr (IIRC).
> Although this says "CTL" at the beginning, interrupt handling and setting
> handlers is independent of any of the "tasking". In the next release it
> will be renamed as the CrossWorks Target Library to reinforce the fact
> that
> tasking is optional.
>
> > So, any pointer to such code anyone? I looked in various startup files
> > from other ARM compiler envireonements but haven't found this part. I
> > will continue to search for this, try to write my own if needed, but I
> > obviousely would apreciate to save the time to do so.
>
> If you created the project using the New Project wizard then you'll
> have the
> VIC handling code already placed into your project, you just need to
> use it.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
>
--- In l..., Markus Zingg wrote:
>
> Paul,
>
> I created a new project with the Project Wizzard to be on the save side
> and added the three small source files (emac.c emactest.c and crc32.c).
> Crossworks now included VIC controll code. I'm now back to using the
> fuctions you suggested (see below). Unfortunately I'm also back to the
> problems....
>
> I meanwhile spent close to two weeks on getting this code to work
> reliable. Lacking experinece with Crossworks and the LPC2378 I first
> misinterpreted a lot of things, but I now can say that as soon as the
> isr routine GETs called, things go highwire on return from the isr. I
> thus wonder what could go wrong by using
>
> ctl_set_isr( );
> ctl_global_interrupts_enable();
> ctl_unmask_isr( );
>
> to setup the isr routine and enable the interruts and by using an isr
> routine declared as
>
> extern __attribute ((interrupt ("IRQ" ) )) void EMACHandler( void );
>
> so badly that on return from the isr, local variables in the fuction
> that was interrupted (actually a simple sending loop) point to the
nirvana?

Try getting rid of all that 'extern __attribute ((interrupt ("IRQ" )
))' gunge and simply declare a C void function, eg, (cut/paste from my
working code):

// ********* UART0 interrupt handler
void UART0interruptHandler(void){
unsigned interruptID;
interruptID=U0IIR;
UART0interface.UARTinstance->interruptEntry(((interruptID>>1)&0x7));
};

I suspect that you are setting up an interrupt-based stack frame that
is not appropriate for ctl_set_isr.

I just use C void functions for my interrupt handlers and have no
problems with the CAN, UART, timer1, capture/match etc.

OK, this is on 2129, but I'm guessing that your environment is much
the same rgds. interrupts.

Rgds,
Martin

Memfault Beyond the Launch