Von: Sergey A. Borshch
An: GCC for MSP430 - http://mspgcc.sf.net
Gesendet am: 25 Feb 2009 14:21:55
Betreff: Re: [Mspgcc-users] error w/msp430x54xx.h in win release
mspgcc-20081230.exe
JMGross wrote:
>> Some thing I had to fix in the default startup code is the default disabling
>> of the WDT.
>It's very simle: just add function named __low_level_init() with
>__attribute__((naked, section ".init3")) into your project. It replaces
>default
>peripheral init function. Library function looks like:
[...]
>You can also replace data init routines by redefining __do_clear_bss() and/or
>__do_copy_data() in section .init4 Don't forget __attribute__((naked))!
[...]
I didn't know about the separate init sections, so what I've done was to
replace the whole reset vector by my own init code, as there was a hint in the
mspgcc documentation.
NAKED(_reset_vector__)
{
// original startup code (init data area)
__asm__ __volatile__("mov %0 , r12 "::"i" (&WDTCTL));
// init registers for watchdog trigger
__asm__ __volatile__("mov %0 , r11 "::"i" (WDTPW|WDTCNTCL));
__asm__ __volatile__("mov #_etext , r15 "::);
__asm__ __volatile__("mov #__data_start, r14 "::);
__asm__ __volatile__("mov #_edata , r13 "::);
__asm__ __volatile__("cmp r14 , r13 "::);
__asm__ __volatile__("jz $+16 "::);
__asm__ __volatile__("mov r11 , 0(r12) "::);
// trigger watchdog
__asm__ __volatile__("mov.b @r15+ , 0(r14) "::);
// copy variable init data from flash
__asm__ __volatile__("inc r14 "::);
__asm__ __volatile__("cmp r13 , r14 "::);
__asm__ __volatile__("jnc $-12 "::);
__asm__ __volatile__("mov #__bss_start , r15 "::);
__asm__ __volatile__("mov #__bss_end , r13 "::);
__asm__ __volatile__("cmp r15 , r13 "::);
__asm__ __volatile__("jz $+16 "::);
__asm__ __volatile__("mov.b #0 , 0(r15) "::);
// fill variable area with 0
__asm__ __volatile__("mov r11 , 0(r12) "::);
// trigger watchdog
__asm__ __volatile__("inc r15 "::);
__asm__ __volatile__("cmp r13 , r15 "::);
__asm__ __volatile__("jnc $-12 "::);
__asm__ __volatile__("mov #__stack , r1 "::);
__asm__ __volatile__("br #main "::);
}
Anyway, when I started with mspgcc I wanted to / had to work on the
application(s) and not on the compiler ;)
>> It took quite some time after starting with MSPs and mspgcc until I noticed
>> that the WDT is silently disabled right
>> after reset and all triggering of it was void.
> It's not safe at all to believe in default value in any peripheral sfr. I
> strongly recommend to explicitly init all used sfrs even with default values.
True for most, but the processor datasheet states clearly that the WDT is
active after power_up or a WDT-reset. And that's the only sane thing if you
want ensure that the device cannot lock-up under all circumstances.
I was very surprised when I wanted to force a WDT reset and nothing happened.
It wasn't obvious that the compilers default startup code was to blame.
Initializing the WDT in the very first line of main() (which ist the earliest
point where an application programmer could do it) is way too late to catch
anything that could happen even during the very first instruction ever executed.
My version of Murphy's law for embedded devices: if the probability for a crash
is greater than zero, the probability that the crash will happen at the worst
position in the program flow tends to 1.
This is while writing to a flash card (leaving the card in an illegal state so
it won't respond anymore), or while the WDT is off during startup or such.
I'd vote for a default startup that leaves the WDT enabled and the optimized
one available through a switch or on devices where there isn't enough RAM that
the startup could take too long without triggering the WDT.
Or at least some clear hint in the docs. As there are surely some mspgcc users
out there (like me, but I'm flexible) who wanted just to use it and not to dig
into the internals of the compiler to figure out unexpected side-effects.
JMGross