Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

RE: [AVR-Chat] Getting The Program Counter in C

2005-12-04 by Larry Barello

The only way to get the PC is to interrupt the processor.  The PC will be on
the stack upon entry into the ISR.  WDT will reset the processor and you
will lose your PC. 

The simplest way to debug something like this is a hardware debugger: JTAG
or ICE200 (if it is a really old chip!).  The $30-40 for a clone JTAG
debugger makes it an essential tool.  Something I do a lot is host on a
bigger chip (m128) and use JTAG to get the algorithms working. Then port to
the target chip which with the AVR is no work at all as virtually all chips
are a subset of the bigger chips so 100% compatible code can be written.  At
that point 99% of the code was working so the remaining bit was easily
debugged via churn & burn.

Alternatively you can poke characters to an USART or twiddle bits on an I/O
port to narrow down the location of the hang.  If you have space, formatted
printf's at critical points can illuminate what is going on (e.g. a loop
counter not incrementing, or something like that).

If none of the above is practical, then you can code a trace routine in an
ISR.  A periodic timer would be convinient.  You need to get the stack
pointer into an index register and then access the PC on the stack. You
could get fancy and have a circular buffer in EEPROM so you keep track of
the last 100 samples (and spread the load around) and an input you control
tracing with (0 = trace, 1 = don't trace).  Then unwind the stack and return
as a normal ISR. That way you can "sample" where the code was when it got
hung.

This could be done in C, but would be simpler in assembly:

ISR:
	Sbic	PINx.pin
	Rjmp	YourRegularISR	; control trace with I/O pin
	Push	r24-31
	In	r24, SREG
	Push 	r24
	In	r28, SPL
	In	r28, SPH
	Ld	r24, Y+9	; PCL
	Ld	r25, Y+10	; PCH (check these offsets)
	...
	; do whatever EEPROM stuff you want
	; since you have the stack pointer you could even save
	; that as well as SREG, etc.  If you know the CV stack 
	; layout you might even be able to print a trace of all
	; the calls to the point of hanging, etc.

	Pop	r24
	Out	sreg, r24
	Pop	r31-24
	Rjmp	YourRegularISR
-----------
Larry Barello
www.barello.net


| -----Original Message-----
| From: AVR-Chat@yahoogroups.com [mailto:AVR-Chat@yahoogroups.com] On Behalf
| Of James Washer
| Sent: Saturday, December 03, 2005 8:36 PM
| To: AVR-Chat@yahoogroups.com
| Subject: Re: [AVR-Chat] Getting The Program Counter in C
| 
| Did you ever get an answer to this?
| 
| Seems to me you want to use either the WDT, or an external interrupt.
| Exactly what will be in the stack will depend on what compiler/library
| routines you are using.. but you should be able to determine this by
| looking some disassembled ISRs. Once you determine the relative stack
| location in the ISR, you should have no trouble storing (or displaying)
| the previous PC
| 
|  - jim
| On Thu, 01 Dec 2005 19:34:55 -0000
| "Terry Slocum" <tslocum@pacbell.net> wrote:
| 
| > I'm trying to track down a bug in an existing program. I believe it is
| > getting stuck in a loop. Once the error occurs the only way to restore
| > communication is to reset the processor. It would help a lot if I could
| > locate the place in the code where it is getting stuck. I would like to
| > be able to store the Program Counter, Hardware Stack Pointer and Data
| > Stack Pointer (Y Register) in EEPROM so I can output them the next time
| > the processor boots. The problem is that the code is in C. I am not
| > sure how to get a value from a hardware register and store it in a C
| > variable. I am using the CodeVisionAVR compiler.  Any ideas?
| >
| > Terry
| >
| >
| >
| >
| >
| >
| >
| > Yahoo! Groups Links
| >
| >
| >
| >
| >
| >
| 
| 
| 
| 
| Yahoo! Groups Links
| 
| 
| 
| 
|

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.