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.

Relocating Exception Vectors on ARM R4F (Hercules)

Hello All,

Is there a way to relocate the __vectors after initial boot time for the ARM Hercules R4F?
I am using SWI's - and would like to move the vector.  I am using a bootloader that 'owns'
the default vector table starting at 0x00 - I would like the app that gets loaded to point to another
vector table - for instance; if an SWI is called I don't want it to jump to 0x08 from the app but to
0xXXXXx that has been relocated.
I see there is a HIVECS option in the SCTRL MMU register - the V bit - but I was hoping there was another way to relocate the vector table while in 'application run-time'.
I see some other processors have what looks like a lib routine that does this - I am not sure with the R4F.
Thanks,
John W.
  • John,
    HIVECS maps to an area of memory on Hercules that's control registers so not useable.
    No other way to remap the SWI() handler.
    You can remap the IRQs though through the VIM - in vectored mode they don't go through 0x18.
    And there are 'System Software Interrupts' on the device that you might try instead of SWI if you need to relocate the vector. There are some subtle differences for example if you trigger a system software interrupt inside an IRQ handler you have to treat this as nesting IRQs. Also the system software interrupt can be masked - which may be undeseriable but of course you could be careful to not mask them..
  • Hello Anthony,

    Yes - I have remapped via the VIM and had assumed the SWI was following that. I was hoping to set the V bit in SCTLR but noticed the processor wasn't too happy when I tried that as you've pointed out. I read on the ARM infocenter site in their UG's that should be possible for this processor family.

    The reason I am having this issue is due to adding a bootloader - which 'owns' the vector starting at 0x00...
    The app is calling SWI #0 - and that was causing the jump to 0x08 - which of course in this case is incorrect since via the bootloader
    and the way I am building the app - the apps '__vector' is now in Bank 1. Of course when SWI #0 is hit (to force a context switch or to
    check for one) - it understandably crashes.

    So, I need to either be able to relocate the 0x08 vector and/or find another way to solve this. If there are other system software IRQ's I can use for this - where is the reference for that? This is the main mechanism the code uses to solve a context switch in this build.

    I am using the F021 API tools and can only execute out of FLASH at the moment; and want that to be in Bank 0 and the app resides in Bank 1.
    It runs until someone calls SWI #0.

    Thanks,
    John W.
  • John,

    Yes - the CPU supports HIVECS, but the Hercules memory map has evolved from the original memory map of the TMS470R1x which was ARM7 based.   And at that time it made a lot of sense to put the critical system registers like the hardware interrupt vector up at 0xFFFFFFxx because you could reach this with a LDR using PC offset by -#imm12 from the vector table,  so you could read the hardware generated index without loading any pointers or using any registers.    Big advantage at the time.  unfortunately it conflicts w. HIVECS now.

    The system software interrupts are documented in the TRM - they're part of the system module.

    Pasting image of one of the SSIR registers from the RM57L TRM but they should be on all the devices.

    These go to VIM like any other interrupt - hence the slight differences I mentioned above w. regard to masking and the possibility that you may need to setup for nesting if you call from IRQ mode.  But otherwise - they're similar to SWI.   You can even pass a code like you do on a SWI through the SSIR register.

    Ok all this said - i should say that I believe the bootloader from QJ is designed to have a fixed branch at the SWI vector - into the next sector of flash where you could put your own code.    A fixed branch also doesn't use registers, so it's good unless you cannot execute from flash when you're making the SWI call for some reason.     So if you can use that mechanism, it's probably worth looking at first.

    Last, there is an ability to swap the addresses of FLASH and RAM in the device memory map but it's kind of a drastic thing to do and you may run into issues with the flash APIs - not sure.   More of an FYI rather than a recommendation.   Register for this is also in the system module (BMMCR1) and you need to follow it with a CPU reset in order to make the swap take effect.

     

  • Anthony,

    Thanks for the quick response.

    I agree that I should just fix the branch from QJ's original code. That is certainly the easiest right now.

    I think what has been done vs. the early days of ARM is absolutely fantastic; but the one offs such as not being able to use the HIVECS now; hmmm - it still isn't bad but would be nice if the original ARM docs could be annotated - but maybe that is impossible due to all the variants.
    The infocenter site ARM has is a God-send though - compared to what we were working with in circa 1997.

    And, thanks for letting me know about the CPU reset being necessary after that swap - I wasn't aware of that; that's an important point as you've pointed out.

    I will take a look at this and report back.

    Again, thank you for the fast response,
    John W.

  • Anthony,

    Patching QJ's vector is the easiest solution here.

    It's working - so; good enough for now.

    Again, thanks for such a quick response!

    Best Regards,
    John W.
  • Hi!
    Just today I finish my own CAN bootloader. Both bootloader & main application uses FreeRtos. To solve problems with SWI interrupts I use custom interrupt handler. This handler check LR register. If LR < 0x20000 - b to handler from bootloader. If LR > 0x20000 - bx to interrupt table from application. This is very simple solution.