and then I would like to do something like this (i know this isn't right)
unsigned int vector_table[] = (unsigned int *)RAM_VECTOR_LOCATION;
vector_table[UART4_RX_TX_IRQn] = (unsigned int)UART4_IRQHandler;
Essentially I would like to index into my vector table to install new handlers but I don't know what the syntax is. This seems like a hazy question but I can't figure out how to articulate it.
I think this better describes what I'm trying to do...
((unsigned int *)RAM_VECTOR_LOCATION)[UART4_RX_TX_IRQn] = (unsigned int)UART4_IRQHandler;
Ryan
I think that your code is functionally OK.
You could also consider:
// When vector ID is referenced to the start of the vector table
//
extern void routine(int iInterruptID, void (*InterruptFunc)(void))
{
void (**processor_ints)(void) = (void (**)(void))VECTOR_TABLE_OFFSET_REG; // vector table address
processor_ints += iInterruptID; // move the pointer to the location used by this interrupt number
*processor_ints = InterruptFunc; // enter the interrupt handler into the vector table
}
// When vector ID is referenced to the start of user interrupts
//
extern void routine(int iInterruptID, void (*InterruptFunc)(void))
{
VECTOR_TABLE *ptrVect = (VECTOR_TABLE *)VECTOR_TABLE_OFFSET_REG;
void (**processor_ints)(void);
processor_ints = (void (**)(void))&ptrVect->processor_interrupts; // first processor interrupt location in the vector table
processor_ints += iInterruptID; // move the pointer to the location used by this interrupt number
*processor_ints = InterruptFunc; // enter the interrupt handler into the vector table
}
As reference, below is the interrupt handler entry function from the uTasker project which includes also interrupt priority (for M4 and M0+), and interrupt unmasking and compatibility with Flash and RAM locations, as well as Kinetis parts with INTMUX module. INTMUX video is at https://youtu.be/zKa5BoOhBrg
Regards
Mark
// Function used to enter processor interrupts
//
extern void fnEnterInterrupt(int iInterruptID, unsigned char ucPriority, void (*InterruptFunc)(void)) // {55}
{
volatile unsigned long *ptrIntSet = IRQ0_31_SER_ADD;
volatile unsigned char *ptrPriority = IRQ0_3_PRIORITY_REGISTER_ADD;
#if !defined INTERRUPT_VECTORS_IN_FLASH
VECTOR_TABLE *ptrVect = (VECTOR_TABLE *)VECTOR_TABLE_OFFSET_REG;
void (**processor_ints)(void);
#endif
#if defined INTMUX0_AVAILABLE
if (iInterruptID >= irq_INTMUX0_0_ID) {
KINETIS_INTMUX *ptrINTMUX = (KINETIS_INTMUX *)INTMUX0_BLOCK;
int iChannel = (iInterruptID - irq_INTMUX0_0_ID);
#if defined KINETIS_WITH_PCC
PCC_INTMUX0 |= PCC_CGC;
#else
POWER_UP_ATOMIC(6, INTMUX0); // power up the INTMUX0 module
#endif
ptrINTMUX += iChannel; // moved to the channel to be used
ptrINTMUX->INTMUX_CHn_IER_31_0 |= (1 << ucPriority); // enable the peripheral source interrupt to the INTMUX module
#if !defined INTERRUPT_VECTORS_IN_FLASH
processor_ints = (void(**)(void))&ptrVect->processor_interrupts; // first processor interrupt location in the vector table
processor_ints += (irq_INTMUX0_3_ID + 1 + ucPriority); // move the pointer to the location used by this interrupt number
*processor_ints = InterruptFunc; // enter the interrupt handler into the (extended) vector table
#endif
iInterruptID = (irq_INTMUX0_0_ID + iChannel);
switch (iChannel) {
case 0:
InterruptFunc = fnINTMUX0;
ucPriority = PRIORITY_INTMUX0_0_INT;
break;
case 1:
InterruptFunc = fnINTMUX1;
ucPriority = PRIORITY_INTMUX0_1_INT;
break;
case 2:
InterruptFunc = fnINTMUX2;
ucPriority = PRIORITY_INTMUX0_2_INT;
break;
case 3:
InterruptFunc = fnINTMUX3;
ucPriority = PRIORITY_INTMUX0_3_INT;
break;
default:
_EXCEPTION("Illegal INTMUX0 channel!");
break;
}
}
#endif
#if !defined INTERRUPT_VECTORS_IN_FLASH
processor_ints = (void (**)(void))&ptrVect->processor_interrupts; // first processor interrupt location in the vector table
processor_ints += iInterruptID; // move the pointer to the location used by this interrupt number
*processor_ints = InterruptFunc; // enter the interrupt handler into the vector table
#endif
ptrPriority += iInterruptID; // move to the priority location used by this interrupt
*ptrPriority = (ucPriority << __NVIC_PRIORITY_SHIFT); // {48} define the interrupt's priority (16 levels for K and 4 levels for KE/KL)
ptrIntSet += (iInterruptID / 32); // move to the interrupt enable register in which this interrupt is controlled
*ptrIntSet = (0x01 << (iInterruptID % 32)); // enable the interrupt
}