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 | | | | |
Message
RE: [AVR-Chat] Getting The Program Counter in C
2005-12-04 by Larry Barello
Attachments
- No local attachments were found for this message.