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.

MSP430F6638: Example on moving interrupt vector to ram using SYSRIVECT bit in SYCTL. Does anyone have an old application note or example?

Part Number: MSP430F6638

I have partioned my main memory into bootloader and Application area. Want try to move interrupt Vector to RAM to execute bootloader with interrupt as smooth and crisp as possible.

I've searched around for real life simpel examples of this; moving interrupt vector to ram using SYSRIVECT bit in SYCTL. Does anyone have an old application note or example(IAR example preffered but not a must)? I found a link but its dead since 2021!!

  • If you have a link (URL), try the Wayback Machine.

  • Dear David. Your input is appreciated but the wayback machine somehow only tells me when the page was removed(as the displayed on webpage). Am I missing something? 

    processors.wiki.ti.com/.../MSP430_FAQ

  • The pages seem to have been archived one or more times while/after the site was taken down. The bar at the top lets you select various dates when it was saved. Work backwards till you find the actual content. I did and found an IAR example. Not that there is much to it.

  • I haven't tried this, but it seems like the only real trick is setting aside (and finding in your code) the top of RAM, which varies between device variants.

    I'd probably start by hacking the project's linker .cmd file (or the IAR equivalent). It might be simplest to split the "RAM" memory segment so the .stack section doesn't get in the way.

  • I actually used the Chat GPT on how to move Interrupt Vector from read only memory to RAM on a MSP430 device(but not using the SYSRIVECT)

    Here's what it came up with. Not a code example but pretty nice reference instruction  

    In MSP430 microcontrollers, the interrupt vector table is typically located in read-only memory (ROM) by default. However, in certain cases, it may be necessary to move the interrupt vector table to RAM. Here's how you can do it:

    1)Disable interrupts: Before moving the interrupt vector table to RAM, it's important to disable interrupts to prevent any potential interruptions during the process. You can do this by clearing the GIE (global interrupt enable) bit in the status register.

    2)Copy the interrupt vector table to RAM: Use a memory copy routine to copy the interrupt vector table from its original location in ROM to a new location in RAM. You can use the memcpy() function in C, or write your own memory copy routine. The new location should be in RAM and must be aligned on a 2-byte boundary.

    3)Set the interrupt vector table pointer: Once the interrupt vector table has been copied to RAM, you need to update the IV (interrupt vector) register to point to the new location. The IV register is a 16-bit register that holds the address of the interrupt vector table. To set it to the new location in RAM, simply write the address of the new location to the IV register.

    4)Re-enable interrupts: After the interrupt vector table has been successfully moved to RAM and the IV register has been updated, you can re-enable interrupts by setting the GIE bit in the status register.

    Note: Be aware that moving the interrupt vector table to RAM may impact the system's interrupt response time and should be done with caution. Also, it's important to ensure that the new location in RAM is not overwritten during normal program execution.

  • Thanks - that was exactly what I was looking for. I'm still kind of impressed by the chat gpt answer :).

  • Did it say where to find the IV register? I don't see any mention of it in the User Guide nor Data Sheet.

    What I do see is in UG (SLAU208Q) Sec 1.3.6.1, which says the RAM vectors (SYSRIVECT=1) are always at the top of RAM.

    [Edit: Added UG reference.]

  • I don't see anything in the example that prevents the stack (TA1 ISR) from overwriting the alternate vector table. CCS allocates the stack up at the top of RAM; maybe IAR does it differently.

  • datasheet(MSP430F6638) contains a full blown table including location of IV. I made a simple calculation to place registers in top of RAM and it works from RAM. 

  • Dear Bruce - I see that it is quite common trick to relocate IVT to top location in RAM on MSP and Others. I guess there is a risk that ram will get occupied if one does not keep that under control in the way bootloader is designed? Is that what you are referring too? 

  • I see your point. I think IAR works like CCS and allocate from top down. But the table is defined and allocated as the very first thing but in principle that area can be overwritten - but how do you see that happen unless I do something directly stupid in my bootloader. I think I can reduce the ram space that stack will be able to allocate/use by changing linker file. That way there is an additional safety build in right (assuming I can/ and will be able to address the memory area outside the stack)?

  • I don't know how your bootloader works, so maybe it somehow avoids all this.

    Looking (only) at the .c file I think that the Example works by accident. It only enables one interrupt, and main() halts in LPM0 forever, so I suspect the interrupt stack doesn't quite reach (overwrite) the timer interrupt vector word in memory; this method would fail if you tried to use it in an actual program. (A test case would be to define e.g. a local 80-byte array in main() and fill it with 0xFF, then see if the timer interrupt still works.) 

    In CCS, I would do this by changing the linker file to break up the RAM memory segment into two pieces, by slicing off the high end into a new segment e.g. RAMIVEC so the stack (">RAM(HIGH)") wouldn't be put there. I haven't used IAR in a long time, but I vaguely recall a memory-mapping window in the Project properties where you could do something analogous.

  • I have thought about this some more since I have a project where I may wish to use a boot loader.

    It all starts with the reset vector. This must always point to the boot loader code. If you use the interrupt vectors for the application, then there will be a period between erasing the segment and writing the vectors where a bobble will brick the device. A hazard best avoided.

    So the interrupt vectors in flash can be used by the boot loader. Using interrupts in the boot loader presents extra hazards. Any peripheral configured for interrupts will have to be disabled and GIE cleared before transferring to the application.

    Reserving space in RAM for the alternate vectors is pretty easy. The linker script defines the RAM by a starting address and length. Just reduce the length by 0x80. (An alternate but tricky method would be to allocate a 128 byte array in main(). This would be placed on the stack. Just be sure to never use it and don't have any other auto variables in main().) The initial location for the stack is just after that. The MSP430 being a pre-decrement kind of CPU. Note that this only needs to be done for the application code.

    Initializing those vectors on other hand requires some work. You could alter the linker script to locate them in RAM but that would be a wasted effort. If the boot loader wrote them there they would vanish at the next power cycle. So they need to be initialized somewhere in the application. I think the easiest way is to relocate the vectors to the segment just below the reset vector. 0xfd80 - 0xfdff. The compiler will respond to the usual ISR invocation in the code and put its vectors there. Then when the application starts, use memcpy() to move them into RAM, set SYSRIVECT, and then enable interrupts.

  • Dear Bruce which c.file/ project are you referring to? I can't see I every uploaded or pasted one in here?? Anyway I think you are spot on with the definition of used area for stack in RAM. 

  • I was looking at ram_int_vect_ex.c from the project (.zip) David linked to. (I also poked through the project files, but I don't really know how to interpret them.)

  • Dear David - I think you touch upon a very important thing here that also came to my mind. When MCU resets  my bootloader code is always initiated as the first thing. From here my intention was to be able to use interrupt  by making a copy of IVT table into ram.

    But I see your point about if the flash write cycle is somehow interrupted by a zillion of different things(We are talking application with wireless module to transfer data!!).

    BUT If this risk is so obvious why is solution proposed at all  - am I missing something?. I'm seeing a lower risk with a dual image process but I/we do not have the req. space and that too can f... up things. Is interrupt in bootloader just a no go or is there something I completely misunderstand.

    PS: If I place my bootloader just below IVT table and reset vector in flash and if I ensure not to erase or overwrite those areas what is the problem then about using interrupt in bootloader. Another question: My last sequence in my Bootloader I just to fixed address where application code is stored/started. Why would I actually need to use the relocate trick to RAM ? 

  • Dear Bruce I will answer my own question on my previously answer to this threads(Hope it makes sense). I need to make the remap in application code because is has no relation to vector table associated with bootloader- right? 

  • I was not entirely correct in my last reply. Here is a rather good explanation about the exact setup I'm doing. www.electronicsforu.com/.../interrupt-bootloader-design-embedded-system-updates

  • I defer to David on more general boot loader design, since I haven't written a boot loader in 40+ years (and that was for a mainframe).

    The document you linked to seems fairly general. TI has some notes on the topic in SLAA450 here:

    https://www.ti.com/lit/an/slaa450g/slaa450g.pdf

    That has internal links to other potentially useful documents.

**Attention** This is a public forum