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.

Alternate location for the interrupt vector

Other Parts Discussed in Thread: MSP430F5438

Hi,

In the MSP430F5438 User's Guide, it reads that  by one setting the SYSRIVECT bit in SYCTL, one can redirect the interrupt vector to RAM.

Is there sample code on this topic ?, I assume that at some point there needs to be data being copied from flash to RAM, then setting this bit.

Background:

I am doing a BSL code; the BSL boots first then gives control to the main application. This all would work just fine, except that the BSL uses the SPI bus and an interrupt, which is also used by the application code.

The objective of the BSL is to boot the uC, then if there is no request by the main processor to update the flash (via SPI commands) then jump to main application main() function, at this point all interrupts should be routed to the main application and not  to the BSL.

So, one solution is to have the interrupt vector of the main application in RAM, which is doable, but I am not very sure how to accomplish.

Thanks for the help.

God bless,

 

Saul

  • Ok,

    We have figured it out, I just need to resolve a compiler warning:

     *********     Warning[Pe767]: conversion from pointer to smaller integer C:\AMF\SpiBusTest\MasterMain.c 58

        unsigned int * NewVectorPtr = (unsigned int *)(0x5B80 + RTC_VECTOR);
        unsigned int addr = (unsigned int)funcAddr;    
        *NewVectorPtr = addr;

    functAddr is a function pointer which point to the ISR function.

     

     

    Any ideas ?

  • Saul,
    I haven't tried it out but a double-cast could do the trick. First cast to unsigned long, and then to unsigned int. Something like:

    unsigned int addr = (unsigned int)((unsigned long)funcAddr);

    On a somewhat related matter, always make sure your ISRs are located below the <64KB boundary. In case of IAR and the latest version of CCS (code generation tools V3.2.1 and later) this happens automatically when you invoke the #pragma vector directive. In case of using CCS/CCE with older code gen tools, you need to manually force each ISR to <64KB by using something like #pragma CODE_SECTION(ADC12_ISR, ".text:_isr").

    Regards,
    Andreas

  • Very good  Andreas!!!........... and yes the function address has a pragma location to lower portion of memory.

    Thanks!

    Saul

  • Hi Saul,

    Would you mind telling me how you did the address thing? I am running into the same problem. I need to rewrite the Interrupt vector but the new one will be in flash as well, so I cannot do it in runtime I tried this:

    #pragma DATA_SECTION(_hw_int53_vector, ".hw_int53")
    const u16 _hw_int53_vector = (u16)&w_radio_ISR;

    .hw_int53 is an address space which points to the 0xFFEA in CC430 which is the RF vector, I would like it to point to my own ISR and then in my ISR decide if I should call the User's ISR or mine. But I keep getting the error

    integer conversion resulted in truncation

    and the warning: conversion from pointer to smaller integer

    I tried the double casting which gets rid of the warning but not the error, the problem is the address for the function w_radio_ISR is 32 bits of which only 16 bits are useful but I it doesn't let me assign it to a u16 const. Is it wrong to try to assign the address of a function to a flash memory space? or should the linker already be able to give the value at which the ISR was put?

    Thanks for any help you can provide.

  • Hello Mx_de:

    The background of my issue was a boot loader. Essentially I had two programs running on the MSP430, the first program is the boot loader and the second is the application program. The addresses of the interrupts of the application program were stored in a know place in flash. When the boot loader was to launch the application program, one of the things it does is to get those ISR addresses and store them in the proper ISR Vector place (replacing the boot loader addresses with the application ISR addresses).  So for me the double casting that Andreas talks about was sufficient.

    Have you tried doing that operation in assembly ?

     

    Saul

     

  • Hey Saul,

    Thanks for your reply, my application is also a type of bootloader, but mine can be called from the main application, instead of it running at default, so I changed the cmd definitions for the default vector address to a lower part of Flash (outside my bootloader) and then in my bootloader another part which basically just does a Branch instruction to the main application, except for 2 interrupts which my bootloader also uses, for these I jump to an my ISR and from there decide if my ISR is to be keep running (if user has activated my bootloader) or call the ISR of the user (normal operation). I tried doing it in assembler with a asm(" mov.w &0xF3EA,PC"); 0xF3EA holds the address of one of the users ISRs. But I can't find a way to put it in flash like that. What I was able to do was to create a const value of 16 bit which has the HEX equivalent to the BR operation and the address to which to jump to. I couldn't find how to put an assembly line in a specific part of flash memory, I can only put a function or a const value using the #pragma directives. Do you know of any way?

  • What I was looking was for simething like

    org 0xF400

     w_int53:mov.w &0xF3EA,PC

    but in C, since I cannot make a assembly file and link it with C in CCS

  • In my version of IAR  ide, there were auxiliary functions:

    __data20_read_short, __data20_read_char, __data20_write_char etc. I used these functions.

    This is the instruction I used to launch my program once the ISRs are inplace:

     

            // Launch program.
            asm("mov &0x5BFE, PC;");

    I believe 0x5BFE is the reset vector in the MSP430.

  • --Solved-- The lag was an error on my side, for not getting out of sleep mode at the end of one of the ISR. Thanks for your help.

  • Hi,

    I don't do a double branch.

    Methodology:

    1. I have two programs stored in ROM.

    2. The uC boots the Boot loader first; if a certain condition is met, then I go to a specific location in ROM (which has the ISR addresses of THE application; I copy these addresses to the vector location and jump to c_startup of THE application. I'll try to review the code at lunch and write back... because I don't recall exactly how I did it, all I remember is that I read the user's guide and got some ideas from there.....

     

**Attention** This is a public forum