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


Reply via email to