Techniques to debug COP resets in S08?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Techniques to debug COP resets in S08?

Jump to solution
1,047 Views
belskyc
Contributor III

Hello,

I have an application utilizing the S08DZ60A microcontroller and the CodeWarrior 6.3 IDE.  My application is resetting, and I'm suspecting it's the COP causing the reset.  Does anyone have any suggestions for techniques on debugging:

 

1)  where the COP reset is taking place?

2)  capturing the SRS register just before reset to verify the source of the reset? 

 

Any helpful tips on debugging COP resets would be greatly appreciated.

 

Thanks,

~belskyc

Labels (1)
0 Kudos
1 Solution
608 Views
rocco
Senior Contributor II

Hi Belskyc,

 

Here is the routine. It is pretty straightforward. Each system has about 20 MCUs in a networked environment, and this code is common to them all (both HC08s and S08s), but "ErrLog" is a macro specific to the circumstances of each MCU. The argument of ErrLog is in a common definition file.

 

This routine runs early in the startup code.

 

;
;
;
; Report the reason for this reset.
;
LogReset:
 lda SRS   ;get System Reset Status Register
 sta ACCUM0   ;store in page zero where we can bit-test
 brset SRS.PIN,ACCUM0,lr_1 ;SRSR: External Pin reset
 brset SRS.COP,ACCUM0,lr_2 ;SRSR: Computer Operating Properly reset
 brset SRS.ILOP,ACCUM0,lr_3 ;SRSR: Illegal Opcode reset
 brset SRS.ILAD,ACCUM0,lr_4 ;SRSR: Illegal Address reset
 brset SRS.POR,ACCUM0,lr_5 ;SRSR: Power-On Reset
 brset SRS.LVD,ACCUM0,lr_6 ;SRSR: Low Voltage Detect reset
 brset SRS.ICG,ACCUM0,lr_7 ;SRSR: Internal Clock Generation reset
;
 ErrLog E_ResetNONE  ;report no Reset bits set
 rts    ;return
;
lr_1: ErrLog E_ResetPIN  ;report External Reset Pin
 rts    ;return
;
lr_2: ErrLog E_ResetCOP  ;report COP Counter Timout Reset
 rts    ;return
;
lr_3: ErrLog E_ResetILOP  ;report Illegal Opcode Reset
 rts    ;return
;
lr_4: ErrLog E_ResetILAD  ;report Illegal Address Reset
 rts    ;return
;
lr_5: ErrLog E_ResetPOR  ;report Power-On Reset
 rts    ;return
;
lr_6: ErrLog E_ResetLVI  ;report Low Voltage Detect Reset
 rts    ;return
;
lr_7: ErrLog E_ResetMonMod  ;report Clock Generation reset
 rts    ;return
;

 

View solution in original post

0 Kudos
6 Replies
608 Views
rocco
Senior Contributor II

Hi Belskyc,

 

You don't need to capture the SRS prior to the reset, as the SRS reflects the cause of the previous reset. I have a routine that runs after every reset and logs the cause. I can provide it if you want, but it is in assembly language.

 

As for determining where the code is getting hung-up and causing the watchdog to timeout, that is trickier. My approach is to disable the watchdog, and wait for the code to hang. Then issue a stop and look where the PC is. It was much easier with the HC08, where you could simply monitor the address-bus while the code was running.

0 Kudos
608 Views
belskyc
Contributor III

Hi rocco,

 

Thanks for the reply.  I'd be very interested in taking a look at this reset logging routine of yours.  Could you please send it? 

 

Also, good idea on disabling the Watchdog and seeing where the code hangs up.  I'm going to try this. 

 

Thanks,

~belskyc

0 Kudos
608 Views
bigmac
Specialist III

Hello belskyc,

 

Like Rocco, I have had occasion to chase the cause of unexpected resets for an assembly program, and to distinguish between COP, ILAD, and ILOP resets.  In my situation, if one of these events did occur, I report a message string to the SCI at the conclusion of initialisation, just prior to entering the main loop.

 

I have also developed a means of reporting the start address of the application subroutine being executed when the reset occurred.

 

A debug subroutine GET_CALL is called using a macro RSDEBUG, and this may be used by including the macro name right at the start of each application subroutine you wish to test.  The purpose of the debug subroutine is to derive from the stack, the address at which the debug subroutine is called, and to store this to a memory location.  If the call occurs at the beginning of the application subroutine, the stored address will be that of the application subroutine (as would be listed in a symbol table).

 

As each monitored subroutine is executed, the stored address would normally be updated.  However, should one of the error reset conditions occur, we require to inhibit further updates until the stored address can be examined.  This is achieved using a control flag that is manipulated by a further debug sub-routine DB_CTRL, that would be called early in the initialisation process, before other subroutines (or ISRs), that might need to be monitored, are called.

 

;_DEBUG_                        ; Enable reset source debugRSDEBUG:  MACRO                 ; Reset source debug macro  IFDEF   _DEBUG_          JSR    GET_CALL       ; Get address of this call  ENDIF          ENDM

 

; Debug RAM variables:  IFDEF   _DEBUG_DBADDR    DS.W   1              ; Debug: SR return addressDBFLAG    DS.B   1              ; Debug control flag  ENDIF

 

;**************************************************************; DEBUG PROCESS:;**************************************************************; RESET DEBUG CONTROL; A zero value in DBFLAG prevents over-write of stored address; value after an ILAD, ILOP or COP error reset occurs.RST_MASK  EQU  mSRS_ILAD|mSRS_ILOP|mSRS_COP ; Reset maskDB_CTRL:  IFDEF   _DEBUG_          CLRX          LDA    SRS          AND    #RST_MASK      ; Reset mask          BNE    *+3            ; Skip next if error reset          INCX                  ; Enable address update          STX    DBFLAG  ENDIF          RTS;--------------------------------------------------------------  IFDEF   _DEBUG_; GET ADDRESS OF THIS SUBROUTINE CALLGET_CALL: PSHX                  ; Save current values          PSHH          LDX    DBFLAG          BEQ    SRR1           ; Exit if flag is clear          LDHX   3,SP          AIX    #-3            ; Address at start of call          STHX   DBADDR         ; Save value to RAMSRR1:     PULH                  ; Restore original values          PULX          RTS  ENDIF

 

For completeness, the subroutines that I used to display both the reset type and the last subroutine address -

 

  IFDEF   _DEBUG_; DISPLAY CALL ADDRESS (HEXADECIMAL)DSP_CALL: LDA    DBADDR          PSHA          NSA          BSR    DISPHEX          PULA          BSR    DISPHEX          LDA    DBADDR+1          PSHA          NSA          BSR    DISPHEX          PULA          BSR    DISPHEX          LDA    #' '          JSR    PUTCHR          LDA    DBFLAG+1          PSHA          NSA          BSR    DISPHEX          PULADISPHEX:  ; Display hexadecimal digit          AND    #$0F          ADD    #'0'          CMP    #'9'          BLS    *+4          ADD    #7          JSR    PUTCHR         ; Put character to FIFO buffer          RTS  ENDIF;--------------------------------------------------------------; DISPLAY RESET TYPEDISP_RST:   IFDEF   _DEBUG_          SEND_STR RST_TYPE     ; Reset type          LDX    #RESET_EV      ; First reset type POR          LDA    SRS            ; System reset statusDR1:      LSLA          BCS    DR2            ; Branch if status bit is set          INCX                  ; Next reset type          TSTA                  ; Test for remaining bit active          BNE    DR1            ; Loop for next bit if so               RTS          DR2:                            ; X = message index value          JSR    SENDSTR        ; Send string data to FIFO buffer                    LDA    DBFLAG          BNE    *+5            ; Skip next if non-zero          JSR    DSP_CALL       ; Display SR call address          LDA    #1             ; Revert to normal flag state          STA    DBFLAG  ENDIF          RTS

 

I guess that it is possible that the code could be adapted for C usage.  However the returned address would likely differ from the function address listed in the map file.  This is because there will be intervening code to store parameters and create local variables on the stack.

 

Regards,

Mac

 

0 Kudos
608 Views
belskyc
Contributor III

Thanks to both rocco & bigmac for the COP debugging techniques.  I was able to implement a simple C-routine that read the SRS early in startup and capture the SRS status bits leading me to the cause of my COP resets.  For anyone that's interested, one thing I learned was that the SRS register is cleared with a read (at least on the S08DZ60A), so make sure to capture the SRS on the first read, and definitely make sure not to pet the watchdog (write to SRS) before reading the SRS status. 

 

Regards,

~belskyc

0 Kudos
608 Views
bigmac
Specialist III

Hello,

 


belskyc wrote:

For anyone that's interested, one thing I learned was that the SRS register is cleared with a read (at least on the S08DZ60A), so make sure to capture the SRS on the first read, and definitely make sure not to pet the watchdog (write to SRS) before reading the SRS status. 


 

If this is true, it would indicate a serious omission from the datasheet/reference manual.  However, it is documented that a reset initiated by the BDM will result in all SRS bits being cleared.

 

Regards,

Mac

 

0 Kudos
609 Views
rocco
Senior Contributor II

Hi Belskyc,

 

Here is the routine. It is pretty straightforward. Each system has about 20 MCUs in a networked environment, and this code is common to them all (both HC08s and S08s), but "ErrLog" is a macro specific to the circumstances of each MCU. The argument of ErrLog is in a common definition file.

 

This routine runs early in the startup code.

 

;
;
;
; Report the reason for this reset.
;
LogReset:
 lda SRS   ;get System Reset Status Register
 sta ACCUM0   ;store in page zero where we can bit-test
 brset SRS.PIN,ACCUM0,lr_1 ;SRSR: External Pin reset
 brset SRS.COP,ACCUM0,lr_2 ;SRSR: Computer Operating Properly reset
 brset SRS.ILOP,ACCUM0,lr_3 ;SRSR: Illegal Opcode reset
 brset SRS.ILAD,ACCUM0,lr_4 ;SRSR: Illegal Address reset
 brset SRS.POR,ACCUM0,lr_5 ;SRSR: Power-On Reset
 brset SRS.LVD,ACCUM0,lr_6 ;SRSR: Low Voltage Detect reset
 brset SRS.ICG,ACCUM0,lr_7 ;SRSR: Internal Clock Generation reset
;
 ErrLog E_ResetNONE  ;report no Reset bits set
 rts    ;return
;
lr_1: ErrLog E_ResetPIN  ;report External Reset Pin
 rts    ;return
;
lr_2: ErrLog E_ResetCOP  ;report COP Counter Timout Reset
 rts    ;return
;
lr_3: ErrLog E_ResetILOP  ;report Illegal Opcode Reset
 rts    ;return
;
lr_4: ErrLog E_ResetILAD  ;report Illegal Address Reset
 rts    ;return
;
lr_5: ErrLog E_ResetPOR  ;report Power-On Reset
 rts    ;return
;
lr_6: ErrLog E_ResetLVI  ;report Low Voltage Detect Reset
 rts    ;return
;
lr_7: ErrLog E_ResetMonMod  ;report Clock Generation reset
 rts    ;return
;

 

0 Kudos