Hi, Roberto
Roberto Padovani wrote:
In the libgcc.S file there is:
#if defined(L__low_level_init)
/*****************************************************************
* Initialize peripherial, particularly disable watchdog
* can be overwriten
*****************************************************************/
.section .init3, "ax", @progbits
.global __low_level_init
.weak __low_level_init
.func __low_level_init
__low_level_init:
mov #0x5a80, &0x120
.endfunc
#endif
where the watchdog address 0x120 is hardcoded. This is correct for
every MSP except for the newer x5xx family.
First time I met this problem with hw multiplier.
Is there anyone knowing the internals of the GCC who can fix or
suggest how to fix this ?
Parametrizing would be best, maybe with two different __low_level_init
functions that are linked against depending on the processor family.
In last sources in 430X branch __low_level_init (as well as other
startup-related routines) moved from libgcc to libc. And current version
__low_level_init.S has following code:
/*****************************************************************
* Initialize peripherial, particularly disable watchdog
* can be overwriten by user function with the same name
*****************************************************************/
.section .init3, "ax", @progbits
.weak __low_level_init
.func __low_level_init
__low_level_init:
mov #0x5a80, &__WDTCTL
.endfunc
So, __WDTCTL now defined as external symbol. The same approach used for HWMUL
registers. Actual addresses can be defined in linker scripts, but I think it
would bloat scripts. So, I decided to define those symbols as weak in gcrt0.S
because gcrt0.S compiled separately for every mcu and (!) io.h with actual
addresses definitions is included to gcrt0.S. So, we don't need to synchronize
addresses in two places as in ld scripts case:
#include <io.h>
#include "core_common.inc"
/***************************************************************
* Declare registers used in library routines
***************************************************************/
macro MAKE_WEAK name
.weak __\name
.set __\name, \name
endm
MAKE_WEAK WDTCTL
#if defined (__MSP430_HAS_HW_MUL__)
MAKE_WEAK MPY
MAKE_WEAK MPYS
MAKE_WEAK MAC
MAKE_WEAK MACS
MAKE_WEAK OP2
MAKE_WEAK RESLO
MAKE_WEAK RESHI
MAKE_WEAK SUMEXT
#if defined (__MSP430_HAS_HW_MUL32__)
MAKE_WEAK MPY32L
MAKE_WEAK MPY32H
MAKE_WEAK MPYS32L
MAKE_WEAK MPYS32H
MAKE_WEAK MAC32L
MAKE_WEAK MAC32H
MAKE_WEAK MACS32L
MAKE_WEAK MACS32H
MAKE_WEAK OP2L
MAKE_WEAK OP2H
MAKE_WEAK RES0
MAKE_WEAK RES1
MAKE_WEAK RES2
MAKE_WEAK RES3
MAKE_WEAK MPY32CTL0
#endif
#endif
Actually, the only wdt and hwmul are used in compiler internal functions, so I
don't think we have to define all sfrs this way.
Good luck!
--
Regards,
Sergey A. Borshch mailto: [email protected]
SB ELDI ltd. Riga, Latvia