Usually I work with interrupt vectors in SRAM but recently I have had the need to have then fixed in Flash and during some work with this the following effect was observed:
1. K20DX256(72MHz) with a few interrupt operating but two of them are used to explain. One is the USB interrupt at vector 89 (counting from 0 being the stack pointer vector) and the other is the UART0 status interrupt at vector 61.
If the vectors are fixed in Flash at the start (0x00000000) these vector locations are physicaly at:
- USB - 4 x 89 = 0x164
- UART0 - 4 x 61 = 0xf4
This is standard and works as expected.
2. Now I link the vectors to 0x8000 instead and set the vector table offset (VTOR) in the Cortex to 0x8000 and the vectors are now physically at
- USB 0x8164
- UART0 0x80f4
Again all works as expected.
3. Now I link to 0x8080 (noting that the vector table offset register has its lower 7 bits unimplemented, so this is the next highest location possible) and the vectors are physically at
- USB 0x81e4
- UART0 0x8174
In this case the USB operates normally but as soon as there is a UART0 interrupt there is an undefined interrupt exception and it turns out that it is vector 29 (DMA channel 13) that unexpectedly interrupts, although there is no DMA operatung and its interrupts are all disabled. This vector would be physially at 0x80f4, which matches the UART0 vector if the vector table were still at 0x8000.....
So, for fun, the UART0 vector is set to the DMA channel 13 vector location and all starts working completely again.
This suggests therefore that some interrupt vectors are moved by the vector table offset value of 0x8080 by 0x8080 (eg, the USB vector which is at 0x00000164 is shifted by 0x8080 to 0x000081e4 (as expected) but some are not - eg. UART0, which is at 0x000000f4 is not shifted by 0x8080 to 0x00008174 (as expected) but instead only shfted by 0x8000 to 0x000080f4.
Expresed in a different way, the vector table offset is not behaving as the same offset for all vectors.
For the USB vector it is + 0x8080 but for the UAR0 vector it is only + 0x8000. [or it is implemented as | 0x8080 and not + 0x8080]
Therefore the question - is this expected or is something wrong??