richard_damon wrote on Thursday, February 17, 2011:
The ARM (and in fact many processors) have fixed addresses for the interrupt vectors, as that is the way the hardware is built. When a given interrupt occurs, the processor goes to the fixed address to start the processing.
In the case of the LPC family, the way they handle the desire for pointing the vectors at different places is to allow several different data sources to provide the contents for the very bottom piece of address space, where the vectors are.
By default, at power up, the processor maps “boot flash”, which is a piece of flash memory at the end of the flash to location 0, and the rest into a higher address section (so on all variants, it can appear at the same address, even though the definition of “end of flash” may change). Other locations that can be mapped include the real beginning of flash, and the beginning of the ram blocks. As far as I can see, there is no way to tell things that 0x5100 is a source of the interrupt vectors, and there is no way to try and convince the hardware that it is, regardless of what the source says.
Now the good part of the way that vectored interrupts work on the ARM with the vectored interrupt module is that you load the address of the routine to go to into hardware registers, and the general vectored interrupt routine just needs to read that address and go there (which is what the LDR PC, does), in the variety I am using it isn’t quite so convenient, the vector interrupt routine typically does the common state save, and then reads the address and jumps to it.
As was said, the other interrupts are more of an issue, including the SWI. If you haven’t done what is needed to put your vectors where the hardware will look at them, the SWI will not find the FreeRTOS handler.
I note that I am a bit puzzled by the need to relocate your program up to get around the boot loader, as the boot loader should NOT be in low flash to begin with on the LPC family. If the issue is that your boot loader isn’t using the boot loader capability of the LPC, you really should do so if possible, and in fact, you must have a real boot loader of some sort as that IS what the processor starts with,
My guess is that for some reason you are actually using a second level of boot loader (something the real boot loader validates and transfer control to), and this would of course be using the flash vectors at the bottom of flash. This means that your application program (now the 3rd program in memory) can’t use those vectors. You have a couple of options:
1) Move the 2nd level boot loader into the real boot loader location, thus your application becomes the 2nd program and can use the lower flash memory for its use.
2) You application can setup its vectors in the bottom of ram and map those addresses into the interrupt vector.
3) You write your 2nd level boot loader to understand the need to revector the interrupts, and reserves some ram locations (which it preloads) for the address of the interrupt routines, the various interrupts that need revectoring then use those locations to get the address to go to. This would NOT be needed for the Vectored Interrupts, as the single instruction routine stored goes to the correct address anyway, so doesn’t need to be overridden. This is by far the most complicated option.