试图理解 *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 字节的值是函数在内存中的位置,即它的第一条指令的地址。这里,oldIsr
和address
分别指向现有的和新的ISR(中断服务程序)。
在这一行#define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)
中,0xe000ed08u
被指定为cyisraddress **
的类型,这意味着指向函数指针的指针。注意0xe000ed08u
是寄存器VTOR(VectorTableOffset Register)的地址,存放的是向量table基地址相对于内存地址0x00000000(reference)
当他们使用*CY_INT_VECT_TABLE
时,表示存储在地址0xe000ed08 的值,实际上是向量table 的地址。此值的类型为 指向函数指针的指针。
现在是有趣的部分。对于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
的类型(函数指针)。
最后,向量 table 可以被认为是一个函数指针数组,因此 ramVectorTable
只是一个指向 ISR 指针的数组 .
我正在尝试了解这段代码的实际作用。特别是声明和初始化指针 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 字节的值是函数在内存中的位置,即它的第一条指令的地址。这里,oldIsr
和address
分别指向现有的和新的ISR(中断服务程序)。
在这一行#define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)
中,0xe000ed08u
被指定为cyisraddress **
的类型,这意味着指向函数指针的指针。注意0xe000ed08u
是寄存器VTOR(VectorTableOffset Register)的地址,存放的是向量table基地址相对于内存地址0x00000000(reference)
当他们使用*CY_INT_VECT_TABLE
时,表示存储在地址0xe000ed08 的值,实际上是向量table 的地址。此值的类型为 指向函数指针的指针。
现在是有趣的部分。对于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
的类型(函数指针)。
最后,向量 table 可以被认为是一个函数指针数组,因此 ramVectorTable
只是一个指向 ISR 指针的数组 .