Это можно понять следующим образом:
cyisraddress
- это указатель на функцию (указатель на функцию). Здесь он имеет форму функции, не принимающей аргумент (void)
и ничего не возвращающей (void)
. Так как это на ARM Cortex-M3, указатель должен быть 4-байтовым значением, например 0x20010004. Это 4-байтовое значение является местоположением функции в памяти, то есть адресом ее первой инструкции. Здесь oldIsr
и address
указывают на существующие и новые ISR (подпрограмма обработки прерываний) соответственно.
В этой строке #define CY_INT_VECT_TABLE ((cyisraddress **) 0xe000ed08u)
, 0xe000ed08u
имеет тип cyisraddress **
, что означает указатель на указатель на указатель функции. Обратите внимание, что 0xe000ed08u
является адресом регистр VTOR (регистр смещения векторной таблицы), в котором хранится смещение базового адреса таблицы векторов по адресу памяти 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 .