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.

MSP430FR6043: MSP430-GCC: how to set multiple vectors to the same trap handler (C, linker or asm)?

Part Number: MSP430FR6043


In order to reduce FRAM consumption I'm trying to set a same common trap-handler to multiple interrupt vectors on MSP430FR6043.

With the TI compiler this is possible using "pragma vector":

#pragma vector=RTC_VECTOR, PORT2_VECTOR, …, UNMI_VECTOR
__interrupt void Dummy_ISR(void) { while (1) { } }

Is there an equivalent for MSP430 GCC compiler 9.3.1.11, which uses "__attribute__((interrupt(x)))"?

On MSP430 irq handlers and vectors with gcc there is a hint, but it fills the memory every 32-bit instead every 16-bit (the vector table has 16-bit elements!).

Example msp430fr6043.ld:

MEMORY {
…
  UNUSED_VECTS_1   : ORIGIN = 0xFF90, LENGTH = 0x004C  /* END=0xFFDB, 38 vectors, size 76 bytes*/
…
}

SECTIONS
{
…
  __unused_vectors_1      : { KEEP (*(__unused_vectors_1)) } > UNUSED_VECTS_1  /* 0 - 37 =  38 vectors */
…
}

traps.c:

static void __attribute((interrupt)) default_trap(void) {
    while (1) { }
}

__attribute__((section("__unused_vectors_1"), used))
static void (*vectors[19])(void) = {  // 1. compile ok, but elements are 32 not 16-bit!
//static const uintptr_t v[19] = {    // 2. compile ok, but elements are 32 not 16-bit!
//static const __int20 v[19] = {      // 3. compile ok, but elements are 32 not 16-bit!
//static const uint16_t v[38] = {     // 4. compile error: initializer element is not computable at load time
    default_trap,  // unused
    default_trap,  // unused
    default_trap,  // unused
    default_trap,  // unused
    0,             // intentionally left zero to check the result
    0,             // same as above
};

In the above traps.c snippet, the first 3 forms compile, but the result is wrong. For example if the resulting address of default_trap is 0x99FA, then the resulting memory content at 0xFF90 is: 99FA 0000, 99FA 0000, 99FA 0000, 99FA 0000, 0000 0000, 0000 0000, .... but what I expect is 99FA, 99FA, 99FA, 99FA, ....

If I try to force the table to be 16-bit (the form 4 in the above traps.c), then the code doesn't compile, failing with the "initializer element is not computable at load time" error!

Any suggestion how to achieve this with GCC using any C/ASM/Linker combination? Thanks!

  • I don't know why you would need a default handler. Unless you enable those particular interrupts, they will never happen so no handler is required.

    Never having done this I tried the obvious thing:

    unsigned __attribute__((section("__interupt_vector_nmi"), used)) nmi_vector = Timer_A;

    But encountered the same error you have. A quick test shows that it is of course possible to assign the address of a function to a variable at run time and the compiler doesn't whine about that. The only alternative I can think of is to use raw assembly. Not particularly difficult with that. Or at least it wasn't when I did it for an ARM. Or even for the MSP430:

            .section __interrupt_vector_timer0_a0,"ax",@progbits
            .word   timer_A_CCR0_isr
            .section __interrupt_vector_usci_a0,"ax",@progbits
            .word   usci_a0_isr
            .section __interrupt_vector_sysnmi,"ax",@progbits
            .word   sysnmi_irq
            .section .resetvec,"ax",@progbits
            .word   sys_init
    

  • Thanks a lot! Clap This does the job perfectly!

  • I actually meant plain assember. As in a .S file. (s vs. S matters.)

    I have seen where "weak" symbols were used which assigned values to those vectors that would be overriden if you created an ISR somewhere else. So one .S file with the default handler and the vector definitions to provide a default for  every interrupt.

    Still seems pointless to me. If you don't enable the interrupt for a particular device, the interrupt will never happen so you don't need an ISR. Worse is that some devices will not automatically clear an interrupt so you would get stuck in an interrupt loop. So the default handler doesn't help much.

**Attention** This is a public forum