This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Watchdog in Main Application jumps to bootloader and crashes?

I have successfully used the SYSRIVECT to move all interrupt vectors from flash to RAM.  My custom bootloader can jump to the application at the application's relocated reset vector.

So the bootloader uses the stock interrupt vector in flash at the default addresses including the reset vector.  And all the interrupt vectors are mapped to a global shared variable structure which maps to the top of the RAM address.  This is code I borrowed from Leo.

Everything in the app works great except when the watchdog kicks in the application, it jumps to a memory location belonging to the bootloader's flash area and hangs there.  There are three ISRs I am using in the application.  USCI_B0, USCI_B1, and Watchdog.  Both USCI I2C are fully functional and I have no issues.  In fact, I use USCI_B0 I2C to download the application, read verify, and stuff at 400KHz.  Works great.  I presume the interrupts in RAM are running fine.

I did not define any interrupt vectors in the application linker file other than the reset vector.  I assume that the CPU is going to move it to the TOP of RAM?  And so my function below that, will map to those interrupt vectors. Is this correct or am I supposed to define it here in a temporary proxy vector in flash?

For the reset vector, I did relocate it from 0xFFFE to 0xF7FE.  This is because the bootloader needs to know where to start the app.  The app cannot write the reset vector on runtime, it would be too late.

What am I doing wrong??  Disabling watchdog will fix my issue.  Bootloader is not using watchdog and is always disabled.

This is what my linker file for the application looks like:

MEMORY
{
SFR : origin = 0x0000, length = 0x0010
PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100
RAM : origin = 0x1C06, length = 0x17FA
INFOA : origin = 0x1980, length = 0x0080
INFOB : origin = 0x1900, length = 0x0080
INFOC : origin = 0x1880, length = 0x0080
INFOD : origin = 0x1800, length = 0x0080
FLASH : origin = 0x8002, length = 0x77FC
RESET : origin = 0xF7FE, length = 0x0002
}

This is how I assign the interrupt vectors in RAM in main.c.

#pragma RETAIN(ram_int_vect)
#pragma location=INT_VECT_START_ADDR
int_vect_t const ram_int_vect = {
{
EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR,
EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR,
EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR,
EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR,
EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR, EMPTY_ISR,
EMPTY_ISR
}, // reserved[41]
EMPTY_ISR, //RTC ;
EMPTY_ISR, //PORT2 ;
EMPTY_ISR, //TIMER2_A1 ;
EMPTY_ISR, //TIMER2_A0 ;
EMPTY_ISR, //USCI_B1 ;
EMPTY_ISR, //USCI_A1 ;
EMPTY_ISR, //PORT1 ;
EMPTY_ISR, //TIMER1_A1 ;
EMPTY_ISR, //TIMER1_A0 ;
EMPTY_ISR, //DMA ;
EMPTY_ISR, //LDO_PWR ;
EMPTY_ISR, //TIMER0_A1 ;
EMPTY_ISR, //TIMER0_A0 ;
EMPTY_ISR, //ADC10 ;
(isr_type_t) &USCI_B0_ISR, //USCI_B0 ;
(isr_type_t) &USCI_B1_ISR, //USCI_A0 ;
(isr_type_t) &WDT_A_ISR, //WDT ;
EMPTY_ISR, //TIMER0_B1 ;
EMPTY_ISR, //TIMER0_B0 ;
EMPTY_ISR, //COMP_B ;
EMPTY_ISR, //UNMI ;
EMPTY_ISR, //SYSNMI ;
EMPTY_ISR, //reset ;
};

This is what the bootloader's linker file, memory map looks like:

MEMORY
{
SFR : origin = 0x0000, length = 0x0010
PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100
RAM : origin = 0x1C06, length = 0x17FA
INFOA : origin = 0x1980, length = 0x0080
INFOB : origin = 0x1900, length = 0x0080
INFOC : origin = 0x1880, length = 0x0080
INFOD : origin = 0x1800, length = 0x0080
FLASH : origin = 0xF800, length = 0x0780, fill=0xFFFF
INT00 : origin = 0xFF80, length = 0x0002
INT01 : origin = 0xFF82, length = 0x0002
INT02 : origin = 0xFF84, length = 0x0002
INT03 : origin = 0xFF86, length = 0x0002
INT04 : origin = 0xFF88, length = 0x0002
INT05 : origin = 0xFF8A, length = 0x0002
INT06 : origin = 0xFF8C, length = 0x0002
INT07 : origin = 0xFF8E, length = 0x0002
INT08 : origin = 0xFF90, length = 0x0002
INT09 : origin = 0xFF92, length = 0x0002
INT10 : origin = 0xFF94, length = 0x0002
INT11 : origin = 0xFF96, length = 0x0002
INT12 : origin = 0xFF98, length = 0x0002
INT13 : origin = 0xFF9A, length = 0x0002
INT14 : origin = 0xFF9C, length = 0x0002
INT15 : origin = 0xFF9E, length = 0x0002
INT16 : origin = 0xFFA0, length = 0x0002
INT17 : origin = 0xFFA2, length = 0x0002
INT18 : origin = 0xFFA4, length = 0x0002
INT19 : origin = 0xFFA6, length = 0x0002
INT20 : origin = 0xFFA8, length = 0x0002
INT21 : origin = 0xFFAA, length = 0x0002
INT22 : origin = 0xFFAC, length = 0x0002
INT23 : origin = 0xFFAE, length = 0x0002
INT24 : origin = 0xFFB0, length = 0x0002
INT25 : origin = 0xFFB2, length = 0x0002
INT26 : origin = 0xFFB4, length = 0x0002
INT27 : origin = 0xFFB6, length = 0x0002
INT28 : origin = 0xFFB8, length = 0x0002
INT29 : origin = 0xFFBA, length = 0x0002
INT30 : origin = 0xFFBC, length = 0x0002
INT31 : origin = 0xFFBE, length = 0x0002
INT32 : origin = 0xFFC0, length = 0x0002
INT33 : origin = 0xFFC2, length = 0x0002
INT34 : origin = 0xFFC4, length = 0x0002
INT35 : origin = 0xFFC6, length = 0x0002
INT36 : origin = 0xFFC8, length = 0x0002
INT37 : origin = 0xFFCA, length = 0x0002
INT38 : origin = 0xFFCC, length = 0x0002
INT39 : origin = 0xFFCE, length = 0x0002
INT40 : origin = 0xFFD0, length = 0x0002
INT41 : origin = 0xFFD2, length = 0x0002
INT42 : origin = 0xFFD4, length = 0x0002
INT43 : origin = 0xFFD6, length = 0x0002
INT44 : origin = 0xFFD8, length = 0x0002
INT45 : origin = 0xFFDA, length = 0x0002
INT46 : origin = 0xFFDC, length = 0x0002
INT47 : origin = 0xFFDE, length = 0x0002
INT48 : origin = 0xFFE0, length = 0x0002
INT49 : origin = 0xFFE2, length = 0x0002
INT50 : origin = 0xFFE4, length = 0x0002
INT51 : origin = 0xFFE6, length = 0x0002
INT52 : origin = 0xFFE8, length = 0x0002
INT53 : origin = 0xFFEA, length = 0x0002
INT54 : origin = 0xFFEC, length = 0x0002
INT55 : origin = 0xFFEE, length = 0x0002
INT56 : origin = 0xFFF0, length = 0x0002
INT57 : origin = 0xFFF2, length = 0x0002
INT58 : origin = 0xFFF4, length = 0x0002
INT59 : origin = 0xFFF6, length = 0x0002
INT60 : origin = 0xFFF8, length = 0x0002
INT61 : origin = 0xFFFA, length = 0x0002
INT62 : origin = 0xFFFC, length = 0x0002
RESET : origin = 0xFFFE, length = 0x0002
}

This is what my watchdog ISR looks like.

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
//#pragma vector=WDT_VECTOR
#pragma CODE_SECTION(WDT_A_ISR, ".text:_isr")
__interrupt void WDT_A_ISR(void)
#elif defined(__GNUC__)
void __attribute__((interrupt(WDT_VECTOR))) WDT_A_ISR(void)
#endif
{

if(wdt_count==wdt_timeout){ //chip erase timeout is 0+8=9(144 seconds)
	wdt_count=0;
	PMMCTL0 = PMMPW + PMMSWPOR + (PMMCTL0 & 0x0003);
}
else
	wdt_count++;
}

  • So finally, I got it to work. Not sure exactly what happened but I didn't reserve a section of RAM for the interrupts so that the stack wouldn't use it. Not sure if that was the problem.

    The other thing is I used differential download via CCS and first downloaded the application, then the bootloader. Then I dumped the RAM to a file. Afterwards, I wanted to see what differences there was versus me downloading the application through the bootloader. So I wiped the flash, downloaded the bootloader via jtag, then transferred the application through i2c to bootloader. Then dumped the RAM to file.

    The binary comparison showed me that the download was entirely successful from 0x8000 and on (flash area). The main differences were in the RAM (of course) as well as some of the special function registers and peripherals. So not sure why the first time around, it didn't work and there are binary differences.
  • Hello Vern,

    Thank you for posting that you were able to solve your issue!

    Regards,
    JH

**Attention** This is a public forum