0

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

它是关于设置指定系统中断号的中断向量的函数。如果这有帮助的话,它适用于具有 ARM Cortex M3 的赛普拉斯 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);
    }

4

2 回答 2

1

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

在代码中的某处,该表可能放置在内存中,并由0x200. 代码的另一部分将 VTOR 寄存器的值更改为该表的地址。

于 2019-05-25T19:58:15.780 回答
1

可以这样理解:

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

在这一行#define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)中,0xe000ed08u被指定为具有 的类型cyisraddress **,这意味着指向函数指针的指针。注意0xe000ed08u是寄存器VTOR(Vector Table Offset Register)的地址,它存储了向量表基地址相对于内存地址0x00000000的偏移量(参考

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

现在是有趣的部分。对于cyisraddress *ramVectorTable, 的类型ramVectorTable指向函数指针的指针。进一步阅读代码时,您会注意到它们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函数指针)。

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

于 2019-06-12T06:07:46.617 回答