试图理解 *ramVectorTable 如何进入 ramVectorTable[ ]

Trying to understand how *ramVectorTable gets to ramVectorTable[ ]

我正在尝试了解这段代码的实际作用。特别是声明和初始化指针 ramVectorTable 之后的部分最让我感到困惑。

设置指定系统中断号的中断向量函数。它适用于具有 ARM Cortex M3 的 cypress PsoC 5,如果这有帮助的话。

#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);
    }

由于您发布的代码不够,我只能猜测。向量 table 可能位于 RAM 内存中。代码只是更改其中一个地址以指向新的中断处理程序。

在代码的某处,table 可能位于内存中,并按 0x200 对齐。另一部分代码将VTOR寄存器的值更改为这个table.

的地址

可以这样理解:

cyisraddress 是一个 函数指针 (指向函数的指针)。这里它的形式是不带参数 (void) 且不返回任何内容 (void) 的函数形式。由于这是在 ARM Cortex-M3 上,指针应为 4 字节值,例如0x20010004。这个 4 字节的值是函数在内存中的位置,即它的第一条指令的地址。这里,oldIsraddress分别指向现有的和新的ISR(中断服务程序)。

在这一行#define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)中,0xe000ed08u被指定为cyisraddress **的类型,这意味着指向函数指针的指针。注意0xe000ed08u是寄存器VTOR(VectorTableOffset Register)的地址,存放的是向量table基地址相对于内存地址0x00000000(reference)

当他们使用*CY_INT_VECT_TABLE时,表示存储在地址0xe000ed08 的值,实际上是向量table 的地址。此值的类型为 指向函数指针的指针

现在是有趣的部分。对于cyisraddress *ramVectorTableramVectorTable的类型是指向函数指针的指针。进一步阅读代码时,您会注意到它们使用ramVectorTable作为一个数组,类似于这个更简单的版本:

int a[10];

然后您可以使用 a[i]a 作为 整数数组 )或 *(a+i)a 作为指向整数的指针) 以访问数组元素。

因此,ramVectorTable可以作为一个函数指针数组,因此ramVectorTable[number & CY_INT_SYS_NUMBER_MASK]就是*(ramVectorTable + number & CY_INT_SYS_NUMBER_MASK),这个值有cyisraddress 的类型(函数指针)。

最后,向量 table 可以被认为是一个函数指针数组,因此 ramVectorTable 只是一个指向 ISR 指针的数组 .