indexing into array placed at fixed address

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

indexing into array placed at fixed address

377 Views
ryanlush
Contributor IV
I have a macro defined like so...
#define RAM_VECTOR_LOCATION 0x20007000

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.

Labels (1)
0 Kudos
2 Replies

265 Views
ryanlush
Contributor IV

I think this better describes what I'm trying to do...

((unsigned int *)RAM_VECTOR_LOCATION)[UART4_RX_TX_IRQn] = (unsigned int)UART4_IRQHandler;

0 Kudos

265 Views
mjbcswitzerland
Specialist V

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
}


0 Kudos