Попытка понять, как * ramVectorTable добирается до ramVectorTable [] - PullRequest
0 голосов
/ 25 мая 2019

Я пытаюсь понять, что на самом деле делает этот код.Конкретно часть после объявления и инициализации указателя ramVectorTable меня смущает больше всего.

Речь идет о функции, которая устанавливает вектор прерывания указанного номера системного прерывания.Это для Cypress PsoC 5, который имеет ARM Cortex 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);
    }

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Это можно понять следующим образом:

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 .

1 голос
/ 25 мая 2019

Поскольку вы разместили недостаточно кода, я могу только догадываться. Таблица векторов, вероятно, находилась в оперативной памяти. Код просто меняет один из адресов, указывая на новый обработчик прерываний.

Где-то в коде таблица, вероятно, помещена в память и выровнена по 0x200. Другая часть кода изменяет значение регистра VTOR на адрес этой таблицы.

...