My embedded application never finishes init to get to main() due to watchdog (IAR/MSP430)
Asked Answered
B

2

7

I'm using an MSP430 chip with 10K of RAM. If I go above 5k of RAM usage, it's never capable of making it to main(). The init code calls __data20_memzero to clear out the used RAM space.

__data20_memzero source

It look like it increments through memory and clears bytes till R14=R12. R14 is 0x34B4. But the max value of R12 is 0x2c86 before it reboots and starts over again. I manually turned off the watchdog through the debugger, and it started running just fine. I can't see this as being normal. Any idea how to get around this problem?

Breadroot answered 28/7, 2013 at 7:11 Comment(0)
B
6

Just after posting this, I found this application note

http://supp.iar.com/Support/?note=37778&from=search+result

If the application has much (over 4k) of global initialized data, then the initialization within cstartup will not be finished before the watchdog times out (and the device is reset).

and

The solution

The Watchdog timer must be turned off before the initialization phase. This should preferably be done in __low_level_init.

The steps (for F1610, F1611 or F1612)
Copy of the file "low_level_init.c" (from ...\430\src\lib\) to your project directory.
Add the copied "low_level_init.c" file to your project.
Edit your copy of the "low_level_init.c" file
In the file you need to add, either...

#include <msp430x16x.h>

...or add...

#include <io430x16x.h>

You should add, in the __low_level_init() function.

WDTCTL = WDTPW + WDTHOLD;
Breadroot answered 28/7, 2013 at 7:22 Comment(1)
I ended up adding #include <msp430.h> as the other options were causing some linker problems. I think it's only required to define the values of WDTCTL, WDTPW, and WDTHOLD.Breadroot
L
2

As you've found, the root problem is that initializing the global ram is just taking too long. While disabling the watchdog at startup does indeed solve the problem, if you're worried about the WD being turned off (even temporarily), an alternative may exist to shorten that init time.

IAR supports an extension __no_init. This tells the compiler that it doesn't need to include those variables in the initialization routine. It can be useful for e.g. RTOS stacks or communication buffers for which initial values don't add any value.

As an example:

__no_init int8_t timerStack[TIMER_STACK_SIZE];
__no_init int8_t displayStack[DISPLAY_STACK_SIZE];
Lishalishe answered 29/7, 2013 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.