avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] assembly-c mix and interrupts


From: Erik Christiansen
Subject: Re: [avr-gcc-list] assembly-c mix and interrupts
Date: Fri, 20 Nov 2009 18:41:26 +1100
User-agent: Mutt/1.5.15+20070412 (2007-04-11)

On Thu, Nov 19, 2009 at 05:08:45AM -0800, darkschine wrote:
> My assembly code follows a standard that ALL registers used are pushed and
> popped from the stack. However, my assembly code does NOT store the SREG.
> Could this be causing my problems?

If it is in the interrupt routine that cpu status is not preserved, then
it must be obvious that execution of any interrupted code with a
condition test at the return point will at times be corrupted. And that
can of course be anywhere in the code.

If the assembler code is only reached by call and return, then I expect
your problem lies elsewhere, unless you're modifying r1, and not leaving
it cleared on return.

Also, there is limited merit in preserving any register that your code
does not use, or the volatile registers: r18-r27, r30-r31.

> I am coming across a problem in a fairly large project where the system
> seems to display incorrect data on the LCD screen and eventually reset
> itself. Other symptoms include displaying incorrect data when string
> constants are transfered to the LCD. The worst case of the problem has been
> uninitiated transfer to a part in the program requiring text input from the
> user. 

That could perhaps be stack corruption. Have you triple checked the
number and order of every assembler push and pop, using three different
people?

> The problem has proved very difficult to debug since modifying the code can
> cause unpredictable behaviour of the error.

But what happened when the SREG was pushed, to see if that would help?

> I believe that the problem first appeared as a global variable changing its
> value for no reason. The problem was corrected by declaring the global
> variable as static which I then considered to be the standard, but am now
> thinking it only masked the problem by storing the variable in a different
> location or modifying the compilation structure.

It is good to see you're recovering from the denial of clear evidence of
deeper problems. The system will never be reliable until the underlying
problem is found and removed.

> Now, all functions seem to be operating correctly and all unit tests pass,
> until interrupt routines are enabled.

If it is in the interrupt routine that cpu status is not preserved, then
it must be obvious that execution of any interrupted code with a
condition test at the return point will at times be corrupted.

> Can anyone provide any insight into this problem or provide some debugging
> techniques to help identify it?

If the "uninitiated transfer" occurs repeatedly, then displaying the
return address found on the stack reveals where the "uninitiated transfer"
occurred. If there is no call there, then it is likely that you returned
to the start of the input routine, perhaps using a data value as return
address. 

It is often necessary to fix the biggest bug in order to spot the
smaller ones hiding behind it. Attacked methodically, it can be quite
gratifying, though mostly when it's over, I must admit. :-)

Erik

P.S. I've written all my ISRs in assembler, on a variety of 8 and 32 bit
platforms, and it is not intrinsically risky, but if the absolutely
essential need to save cpu status is not immediately clear, then writing
them in C could be a wise alternative, which simultaneously eliminates
any push-pop mismatch issues.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]