Reply by David Rick February 14, 20052005-02-14


--- In , "David Rick" <davidlrick@y...> wrote:

Thanks to everyone who replied, including several who sent me private
email.

It seems that the problem is DSP/BIOS breaking the C calling
conventions for save-on-entry registers. I found and fixed the
problem by changing my interrupt routine to save more registers
before making a BIOS call.

The difference is in the first argument passed to HWI_enter and
HWI_exit. C55_AR_DR_BIOS_CONTEXT_MASK (defined in C55.h55) should
save the ARn and Tn regs that BIOS might modify, but it doesn't do
the job. Apparently BIOS is not saving the context of some registers
that aren't in this mask.

Here's the original routine:

CWadcHalf:
; ADC half buffer full ISR
; Hooked to HWI_INT18 in HWI module of GUI
; This calls the first decimation filter via SWI
HWI_enter C55_AR_DR_BIOS_CONTEXT_MASK,
C55_ACC_BIOS_CONTEXT_MASK,
C55_MISC1_BIOS_CONTEXT_MASK,
C55_MISC2_BIOS_CONTEXT_MASK,
C55_MISC3_BIOS_CONTEXT_MASK,
IER0DISABLEMASK, IER1DISABLEMASK

AR1 = DMA_CSR0_IOPORT ; read DMA status to
acknowledge
XAR0 = #CWdecimate1
SWI_inc

HWI_exit C55_AR_DR_BIOS_CONTEXT_MASK,
C55_ACC_BIOS_CONTEXT_MASK,
C55_MISC1_BIOS_CONTEXT_MASK,
C55_MISC2_BIOS_CONTEXT_MASK,
C55_MISC3_BIOS_CONTEXT_MASK,
IER0RESTOREMASK, IER1RESTPREMASK

Now here's how I changed it:

CWadcHalf:
; ADC half buffer full ISR
; Hooked to HWI_INT18 in HWI module of GUI
; This calls the first decimation filter via SWI
HWI_enter C55_ALL_AR_DR_REGS,
C55_ACC_BIOS_CONTEXT_MASK,
C55_MISC1_BIOS_CONTEXT_MASK,
C55_MISC2_BIOS_CONTEXT_MASK,
C55_MISC3_BIOS_CONTEXT_MASK,
IER0DISABLEMASK, IER1DISABLEMASK

AR1 = DMA_CSR0_IOPORT ; read DMA status to
acknowledge
XAR0 = #CWdecimate1
SWI_inc

HWI_exit C55_ALL_AR_DR_REGS,
C55_ACC_BIOS_CONTEXT_MASK,
C55_MISC1_BIOS_CONTEXT_MASK,
C55_MISC2_BIOS_CONTEXT_MASK,
C55_MISC3_BIOS_CONTEXT_MASK,
IER0RESTOREMASK, IER1RESTPREMASK

Note that it is certainly DSP/BIOS screwing up, not my code. This HWI
is the highest priority in my system, and the SWI that it posts can't
run until the interrupt routine returns.

Thanks again for the help.

David L. Rick
Hach Company


Reply by Dileepan C February 7, 20052005-02-07
hi,

May be you can use the breakpoints and single stepping
features to find where exactly the T3 gets the
unexpected value. Are you passing more number of
values to the called function which forces the system
to use stack apart from the ususal T and AR registers?

It can also be that there is a bug in bios functions
or the way your CCS version works.

regards,
Dileepan.

--- David Rick <> wrote:

>
>
> I'm looking for ideas on how to find a particularly
> elusive bug. The
> target is a C5509A using DSP/BIOS, CSL, and DSPlib.
>
> I have a task written in C that runs forever. The
> compiler has used
> the T3 register to store an array offset. It
> initializes T3 prior to
> the main loop in this task, which then cycles
> indefinately, pending
> on mailbox and timer events. In this context, T3
> should never
> change, but it is getting corrupted by some other
> task or function.
> Fortunately this leads only to incorrect results
> instead of complete
> mayhem, but it still needs to be fixed.
>
> If I am screwing up T3 myself, it must be because of
> something I've
> written in assembly language. I have two
> time-critical functions
> written in algebraic assembly. I also have a short
> HWI function.
>
> The HWI looks schematically like this:
> HWI_enter...
> AR1 = something
> XAR0 = address of SWI below
> SWI_inc
> HWI_exit..
>
> The first ASM function runs as a SWI posted from the
> HWI. I strongly
> suspected this function because it processes ADC
> values, and T3 is
> getting overwritten with an address 256 words into
> my ADC buffer. But
> in this function, I only set T3 to 0 or 1, which
> doesn't fit. I've
> checked the code, and I'm saving T3 on entry and
> restoring it on
> exit. Prior to restoring context, I make calls to
> SWI_inc and
> SWI_dec. The SWI_dec call posts a C-language routine
> which ends up
> calling my second assembly language function,
> described below.
>
> This second ASM function is a special-size FFT. It,
> too, saves and
> restores T3. Inside this function, T3 gets used to
> store the offset
> of my twiddle table, which isn't the rogue number in
> question.
>
> So if I'm not the one corrupting T3, how can I find
> out who is? I'd
> really love to be able to break on a T3 load, but my
> Spectrum Digital
> emulators can't do this sort of thing. Anyone got
> another idea?
>
> David L. Rick
> Hach Company


__________________________________________________




Reply by Lakshman February 5, 20052005-02-05

did you saved the context of T3 and restored back in
asm files which you coded????

Cheers
-Lakshman --- Tim Thorpe <> wrote:

> On Fri, 04 Feb 2005 22:38:55 -0000
> "David Rick" <> wrote:
>
> >
> > I'm looking for ideas on how to find a
> particularly elusive bug. The
> > target is a C5509A using DSP/BIOS, CSL, and
> DSPlib.
> >
> > I have a task written in C that runs forever. The
> compiler has used
> > the T3 register to store an array offset. It
> initializes T3 prior to
> > the main loop in this task, which then cycles
> indefinately, pending
> > on mailbox and timer events. In this context, T3
> should never
> > change, but it is getting corrupted by some other
> task or function.
> > Fortunately this leads only to incorrect results
> instead of complete
> > mayhem, but it still needs to be fixed.
> >
> > If I am screwing up T3 myself, it must be because
> of something I've
> > written in assembly language. I have two
> time-critical functions
> > written in algebraic assembly. I also have a short
> HWI function.
> >
>
> It sounds horrid.
>
> I think you're concentrating on code which might do
> "T3 = something",
> having failed to save or restore context correctly.
>
> Could it not be that a wild write is hitting the
> memory-mapped
> location of T3?
>
> I would try to disable various bits of the
> functionality of the
> system while disturbing the overall operation as
> little as possible,
> in the hope of finding a clue: eg replace parts of
> your signal
> processing with null operations not involving
> pointers.
>
> Of course, CSL and DSP/BIOS are very capable of
> having bugs.
>
> Tim.
------------------------
> Tim Thorpe Tel: +44 1223
> 240366
> Fax: +44
> 1223 414402
>
------------------------
>


__________________________________________________




Reply by Tim Thorpe February 4, 20052005-02-04
On Fri, 04 Feb 2005 22:38:55 -0000
"David Rick" <> wrote:

>
> I'm looking for ideas on how to find a particularly elusive bug. The
> target is a C5509A using DSP/BIOS, CSL, and DSPlib.
>
> I have a task written in C that runs forever. The compiler has used
> the T3 register to store an array offset. It initializes T3 prior to
> the main loop in this task, which then cycles indefinately, pending
> on mailbox and timer events. In this context, T3 should never
> change, but it is getting corrupted by some other task or function.
> Fortunately this leads only to incorrect results instead of complete
> mayhem, but it still needs to be fixed.
>
> If I am screwing up T3 myself, it must be because of something I've
> written in assembly language. I have two time-critical functions
> written in algebraic assembly. I also have a short HWI function.
>

It sounds horrid.

I think you're concentrating on code which might do "T3 = something",
having failed to save or restore context correctly.

Could it not be that a wild write is hitting the memory-mapped
location of T3?

I would try to disable various bits of the functionality of the
system while disturbing the overall operation as little as possible,
in the hope of finding a clue: eg replace parts of your signal
processing with null operations not involving pointers.

Of course, CSL and DSP/BIOS are very capable of having bugs.

Tim.

------------------------
Tim Thorpe Tel: +44 1223 240366
Fax: +44 1223 414402
------------------------



Reply by David Rick February 4, 20052005-02-04


I'm looking for ideas on how to find a particularly elusive bug. The
target is a C5509A using DSP/BIOS, CSL, and DSPlib.

I have a task written in C that runs forever. The compiler has used
the T3 register to store an array offset. It initializes T3 prior to
the main loop in this task, which then cycles indefinately, pending
on mailbox and timer events. In this context, T3 should never
change, but it is getting corrupted by some other task or function.
Fortunately this leads only to incorrect results instead of complete
mayhem, but it still needs to be fixed.

If I am screwing up T3 myself, it must be because of something I've
written in assembly language. I have two time-critical functions
written in algebraic assembly. I also have a short HWI function.

The HWI looks schematically like this:
HWI_enter...
AR1 = something
XAR0 = address of SWI below
SWI_inc
HWI_exit..

The first ASM function runs as a SWI posted from the HWI. I strongly
suspected this function because it processes ADC values, and T3 is
getting overwritten with an address 256 words into my ADC buffer. But
in this function, I only set T3 to 0 or 1, which doesn't fit. I've
checked the code, and I'm saving T3 on entry and restoring it on
exit. Prior to restoring context, I make calls to SWI_inc and
SWI_dec. The SWI_dec call posts a C-language routine which ends up
calling my second assembly language function, described below.

This second ASM function is a special-size FFT. It, too, saves and
restores T3. Inside this function, T3 gets used to store the offset
of my twiddle table, which isn't the rogue number in question.

So if I'm not the one corrupting T3, how can I find out who is? I'd
really love to be able to break on a T3 load, but my Spectrum Digital
emulators can't do this sort of thing. Anyone got another idea?

David L. Rick
Hach Company