我在试着理解这段代码的实际功能。特别是声明和初始化指针ramVectorTable之后的部分最让我困惑。
它是关于设置指定系统中断号的中断向量的函数。如果这对cypress的PsoC 5有帮助的话,它的手臂皮层是M3。
#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);
}
最佳答案
可以理解为:cyisraddress
是函数指针(指向函数的指针)。这里有一个函数的形式,它不接受参数(void)
,不返回任何(void)
。由于这是在ARM Cortex-M3上,指针应为4字节值,例如0x20010004。这个4字节的值是函数在内存中的位置,即它的第一条指令的地址。这里,oldIsr
和address
分别指向现有的和新的ISRS(中断服务例程)。
在这一行中,#define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)
被指定为具有0xe000ed08u
类型,这意味着指向函数指针的指针。注意cyisraddress **
是寄存器VTOR(Vector Table Offset register)的地址,它存储Vector Table基址与内存地址0x00000000的偏移量(reference)
当它们使用0xe000ed08u
时,表示存储在地址0xe000ed08的值,该地址实际上是向量表的地址。此值具有指向函数指针的指针类型。
现在是有趣的部分。对于*CY_INT_VECT_TABLE
,cyisraddress *ramVectorTable
的类型是指向函数指针的指针。当进一步阅读代码时,您会注意到它们使用ramVectorTable
作为数组,这类似于这个更简单的版本:
int a[10];
然后可以使用
ramVectorTable
(a[i]
作为整数数组)或a
(*(a+i)
作为指向整数的指针)来访问数组元素。因此,
a
可以用作函数指针数组,因此ramVectorTable
只是ramVectorTable[number & CY_INT_SYS_NUMBER_MASK]
,该值的类型为*(ramVectorTable + number & CY_INT_SYS_NUMBER_MASK)
(函数指针)。最后,向量表可以看作是函数指针数组,因此
cyisraddress
只是指向ISR的指针数组。