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.

Array size over 4674 bytes crashes IAR on F5438 experimenter's board



I tried out the UART by echoing bytes from a terminal. Worked fine.

Then I picked off the bytes as they came in and stored them in an array.

Originally I tried an array size of 8192. This part has 16k of RAM and the UART test snip is around 600 bytes in flash.

I'm using the latest download of IAR Kickstart. With 8192, it compiled and loaded okay but the debug screen never

came out of initialization. I waited several minutes.  It turns out that anything over 4674 for the array size causes that reaction.

#include "msp430x54x.h"
volatile char RCV_DATA;
volatile char XMIT_DATA;
volatile char BUFFER [4674];   // <========
volatile  unsigned int CNT = 0;
const char UCR0IFG = 0x01;    // Receiver full interrupt flag
const char UCT0IFG = 0x02;    // Transmit buffer empty interrupt flag
const char P3TX    = 0x10;    // Pin on P3 used as xmit bit

void main(void)
{
   // Set up the UART
 P3DIR |= P3TX;                   // Set transmit pin to output
 P3SEL |= 0x30;                        // P3.4,5 =  USCI_A0 TXD/RXD
 UCA0CTL1 |= UCSWRST;            // **Put state machine in reset**
 UCA0CTL1 |= UCSSEL_2;        // Select SMCLK as source, 8N1
 UCA0BRW = 138;                  // 16MHz 115200 (see User's Guide)
 UCA0MCTL |= UCBRS_7+UCBRF_0;    // Modulation
 UCA0CTL1 &= ~UCSWRST;        // **Initialize USCI state machine**
 UCA0IE |= UCRXIE;                // Enable USCI_A0 RxD interrupt

 __bis_SR_register(GIE);    //  enable interrupts
 
   while (1)
   {
        __no_operation;
   }
}

  • Hi Andy,

    what's likely going on here is that the device's watchdog timer times out during C-startup initialization code. Once your array reaches a certain "critical" size, it will take the C-startup init code more than the default watchdog timer timeout period (32,768 CPU cycles) before you reach main(). To resolve this you could add a __no_init modifier to your array definition (like __no_init volatile char BUFFER[8192]), or you could add code that runs before the C-startup code that disables the WDT. For this, see the MSP430 FET User's Guide (SLAU138), FAQ chapter, Program Development section.


    As a side note, in your application code the Watchdog timer currently isn't handled at all. Either it needs to be disabled the first thing you do in the main() routine or in your case a better place would be as part of the C-startup code - see above suggestions. Or, if not disabled, you would need to constantly pet it, otherwise it will time out and your application will reset periodically.

    Regards,
    Andreas

  • (copy&pasted section from the User's Guide FAQ)

    14. The CSTARTUP that is implicitly linked with all C applications does not disable the Watchdog timer.

    Use WDT = WDTPW + WDTHOLD; to explicitly disable the Watchdog. This statement is best placed in the __low_level_init() function that gets executed before main(). If the Watchdog timer is not disabled, and the Watchdog triggers and resets the device during CSTARTUP, the source screen goes blank, as C-SPY is not able to locate the source code for CSTARTUP. Be aware that CSTARTUP can take a significant amount of time to execute if a large number of initialized global variables are used.

    int __low_level_init(void)
    {
        /* Insert your low-level initializations here */
        WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog timer

        /*==================================*/
        /* Choose if segment initialization */
        /* should be done or not. */
        /* Return: 0 to omit seg_init */
        /* 1 to run seg_init */
        /*==================================*/

        return (1);
    }

  • That's it! I accidently erased the line that disables the WDT when I copied the file over for a new project.

    I also like the __no_init modifyer. There's no reason to pre-set this buffer at this time.

    Thanks, Andreas

  • Just to add my 2 cents...

    The one and only purpose of the WDT is to reset the device if it crashed for some reason.

    One thing are crashes due to software bugs. But another one is a crash due to ESD or other external influence such as power surges/bursts.

    If the WDT is disabled during execution of the startup code, the processor might crash again immediately due to the lasting external crash condition. And this time, there's no WDT bringing the device back to life again.

    I was surprised that the WDT didn't trigger (on purpose) on my application until I discovered that the default startup code of the MSPGCC compiler simply disables the WDT -  to ensure that it won't trigger during lengthy init data copying (such as the one that was the reason of this thread).

    I ended up completely rewriting the startup code myself, manually triggering the WDT after every 256 words copied or cleared. The additional execution time of a few cycles is nothing compared to the risk of a device not recovering from a crash.

    JMGross

**Attention** This is a public forum