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.

MSP430 irq handlers and vectors with gcc

Other Parts Discussed in Thread: MSP430F5529, MSP430F2013

Hi!

I just wondering if it is possible for define all the irq handlers array in c and placing it at the reset vector address:

something like is defined for arm.

void (* const g_pfnVectors[])(void) = {

reset_handler,

other_irq_handler,

dummy_handler,

....
};

  • The linker scripts do not define a single section that covers all interrupt vectors (there's a single section for each vector).

    However, it would be possible to change the linker script: remove all the *VECT* memory definitions and the __interrupt_vector* sections, and replace them with a single definition:

    MEMORY {
      ...
      ALLVECTORS       : ORIGIN = 0xFF80, LENGTH = 0x0080  /* or whatever your model uses */
    }
    
    SECTIONS
    {
      __interrupt_vectors    : { KEEP (*(__interrupt_vectors )) } > ALLVECTORS
    
      ...
    }

    You also have to change your code so that none of the old sections are used, i.e., don't use __attribute__(interrupt(number)), and change the start-up code not to place a pointer into the reset vector.

  • Ok Thanks! That's the idea ! To remove all the "attribute ..."
    Than I will have to initialize all the .bss .rodata etc section by hand. Is there any way of do that?
    thanks!
  • Interrupt handlers still need to use RETI and to save registers, so you still need to use __attribute__(interrupt); just remove the vector number so that the compiler does not try to set it.

    The startup code has more responsibilities (initializing the stack pointer, etc); you have to duplicate everything it does. Or just replace the original with one that does not define the reset vector.

  • HI!

    I tried what you 've said changing the msp430f5529 .ld provided within the MSP430 GCC v4.x

    It compiles but I can't see the changes when outputting to a dissasembly file using msp430-elf-objdump -D-S

    I tried to understand the linker file (I am not an expert, by any chance).

    I have change also the linker command line using using -nostartfiles with no luck.

    Do I have to change anything else or check something I am missing?

    thanks

    Franco
  • FAB63476 said:

    Hi!

    I just wondering if it is possible for define all the irq handlers array in c and placing it at the reset vector address:

    something like is defined for arm.

    void (* const g_pfnVectors[])(void) = {

    reset_handler,

    other_irq_handler,

    dummy_handler,

    ....
    };

    But the ARM hardware has its reset vector at the low end of addresses and other interrupt vectors at higher and higher addresses. While MSP430 hardware has its reset vector at the higher end of addresses. So what comes naturally for ARM may be awkward for MSP430. 

  • This is a minimal program that is executed directly from the reset vector and replaces the normal startup code.

    Compile with something like: msp430-gcc -Os -mmcu=msp430... -nostartfiles -o minimal.elf minimal.c

    #include <msp430.h>
    
    // defined by the linker script
    extern char __stack;
    
    __attribute__((naked))
    static void my_program(void)
    {
    	// no stack yet; cannot have local variables
    
    	_set_SP_register(&__stack);
    
    	WDTCTL = WDTPW | WDTHOLD;
    
    	P1DIR |= BIT0;
    	for (;;)
    		P1OUT ^= BIT0;
    }
    
    __attribute__((section(".resetvec"), used))
    static void (*reset_vector)(void) = my_program; 

    "Minimal" means that it does not even initialize global variables. This could be done with code like this (some sections are not used on all architectures, or might be empty), after setting SP:

    extern char __bssstart, __bsssize;
    extern char __high_bssstart, __high_bsssize;
    extern char __datastart, __romdatastart, __romdatacopysize;
    extern int __upper_data_init;
    extern char __high_datastart, __rom_highdatastart, __rom_highdatacopysize;
    ...
    
    	// initialize .bss
    	memset(&__bssstart, 0, (uintptr_t)&__bsssize);
    	// initialize .upper.bss
    	memset(&__high_bssstart, 0, (uintptr_t)&__high_bsssize);
    	// initialize .data
    	memmove(&__datastart, &__romdatastart, (uintptr_t)&__romdatacopysize);
    	// initialize .upper.data
    	if (&__rom_highdatacopysize != 0) {
    		if (__upper_data_init == 0) {
    			__upper_data_init = 1;
    			memmove(&__rom_highdatastart, &__high_datastart, (uintptr_t)&__rom_highdatacopysize);
    		} else {
    			memmove(&__high_datastart, &__rom_highdatastart, (uintptr_t)&__rom_highdatacopysize);
    		}
    	}

    This still uses the original .resetvec section. To make the interrupt vectors an array, I've put the following into the file vec.ld (this is for the F2013; others have more entries):

    MEMORY {
      ALLVECTORS       : ORIGIN = 0xFFE0, LENGTH = 0x0020
    }
    
    SECTIONS
    {
      __interrupt_vectors    : { KEEP (*(__interrupt_vectors )) } > ALLVECTORS
    }

    And the vectors are put into that section (this replaces the reset_vector pointer in the first program):

    static void __attribute((interrupt)) some_interrupt(void)
    {
    	...
    }
    
    __attribute__((section("__interrupt_vectors"), used))
    static void (*vectors[16])(void) = {
    	0,               // unused
    	0,               // unused
    	some_interrupt,  // P1
    	0,               // P2
    	0,               // USI
    	0,               // ADC10/SD16_A
    	0,               // unused
    	0,               // unused
    	0,               // Timer_A2
    	0,               // Timer_A2 CCR0
    	0,               // WDT+
    	0,               // Comp_A+
    	0,               // unused
    	0,               // unused
    	0,               // NMI
    	my_program       // reset
    };

    Compile with something like:
    msp430-gcc -Os -mmcu=msp430f2013 -nostartfiles -Xlinker "-Tvec.ld" -o whatever.elf whatever.c

  • Great explanation!
    I will try this soon!
    Thanks!

**Attention** This is a public forum