0

I'm trying to understand what this code actually does. Specifically the part after declaring and initializing the pointer ramVectorTable confuses me the most.

It is about function that sets the interrupt vector of the specified system interrupt number. It's for cypress's PsoC 5 that has ARM Cortex M3 if this helps somehow.

#define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)


typedef void (* cyisraddress)(void);


cyisraddress CyIntSetSysVector(uint8 number, cyisraddress address)
    {
        cyisraddress oldIsr;
        cyisraddress *ramVectorTable = *CY_INT_VECT_TABLE;

 /* Save old Interrupt service routine. */
        oldIsr = ramVectorTable[number & CY_INT_SYS_NUMBER_MASK];

        /* Set new Interrupt service routine. */
        ramVectorTable[number & CY_INT_SYS_NUMBER_MASK] = address;

        return (oldIsr);
    }

artless noise
  • 21,212
  • 6
  • 68
  • 105

2 Answers2

1

As you have posted not enough code, I can only guess. The vector table was probably located in the RAM memory. The code just changes one of the addresses to point to the new interrupt handler.

Somewhere in the code the table is probably placed in the memory and it is aligned by 0x200. Another part of the code changes the value of the VTOR register to the address of this table.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
0___________
  • 60,014
  • 4
  • 34
  • 74
  • any comment silent dvter? – 0___________ May 25 '19 at 20:01
  • I've left a suggested edit so I can un-downvote this. Please review. – S.S. Anne May 25 '19 at 20:37
  • @P__J__ First of all, thanks for the reply. I was just trying to understand what was going on in terms of C code. I'll try to be more precise. The address `0xe000ed08u` was casted to `(cyisradress **)` which would be double pointer of type `cyisraddress`. In function `CyIntSetSysVector` pointer `ramVectorTable` points to `*CY_INT_VECT_TABLE` which should be whatever it is stored on that address and that should be pointer to pointer, and that's where I start to be confused. – Sava Krstović May 26 '19 at 10:41
  • The part where `oldIsr = ramVectorTable[number & CY_INT_SYS_NUMBER_MASK];` should mean that `ramVectorTable` is an array of `cyisraddress` elements is also something that I can't understand. I should also emphasize that I'm not that good in C, so I hope it doesn't bother you all. – Sava Krstović May 26 '19 at 10:49
1

It can be understood as follows:

cyisraddress is a function pointer (a pointer to a function). Here it has the form of a function taking no argument (void) and returning nothing (void). Since this is on ARM Cortex-M3, a pointer shall be a 4-byte value, e.g. 0x20010004. This 4-byte value is the location of the function in memory, i.e. the address of its first instruction. Here, oldIsrand address point to the existing and new ISRs (Interrupt Service Routine) respectively.

In this line #define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u), 0xe000ed08u is specified to have the type of cyisraddress **, which means pointer to a pointer to a function pointer. Note that 0xe000ed08u is the address of the register VTOR (Vector Table Offset Register), which stores the offset of the vector table base address from memory address 0x00000000 (reference)

When they use *CY_INT_VECT_TABLE, it means the value stored at address 0xe000ed08, which effectively is the address of the vector table. This value has a type of pointer to a function pointer.

Now is the interesting part. For cyisraddress *ramVectorTable, the type of ramVectorTable is a pointer to a function pointer. When reading the code further, you will notice that they use ramVectorTable as an array, which is similar to this simpler version:

int a[10];

Then you can use either a[i] (a as an array of integers) or *(a+i) (a as a pointer to an integer) to access the array elements.

Therefore, ramVectorTable can be used as an array of function pointer, thus ramVectorTable[number & CY_INT_SYS_NUMBER_MASK] is just *(ramVectorTable + number & CY_INT_SYS_NUMBER_MASK), this value has the type of cyisraddress (function pointer).

Lastly, the vector table can be thought of as an array of function pointers, thus ramVectorTable is simply an array of pointers to an ISR.

Community
  • 1
  • 1
DinhQC
  • 133
  • 10
  • 1
    Thank you so much for so detailed explanation. The part with arrays and pointers I understood after reading about it in "The C programming language" from Kernighan and Ritchie.There it is said that pointers could be used with a subscript as in, if `pa` is a pointer, `pa[i]` is identical to `*(pa + i)`, so the pointer arithmetic with `ramVectorTable` was clear at that moment. But the part with dereferencing was confusing me until now. – Sava Krstović Jun 15 '19 at 22:43