2015-12-17 2 views
1

Я пишу загрузчик для процессора ARM Cortex-M0. Мне нужно перенаправить IRQ в целевое приложение, к сожалению, вектор IRQ в этом CPU имеет фиксированный адрес, и я не могу его переместить, поэтому мне нужно немного обмануть.Двойная функция косвенности в C

Я знаю адрес, в котором хранятся адреса IRQ целевого приложения. Так скажем, по адресу 0x5008 есть адрес ничтожной x_IRQHandler (ничтожной) (целевое приложение)

То, что я хочу сделать, это:

  • при запуске сохранить адреса всех x_IRQHandler() (так что он не рассчитывается во время выполнения);
  • всякий раз, когда вызов IRQ принимается загрузчиком, вызовите связанную функцию IRQ в целевом приложении со своего адреса.

Это то, что я сделал в загрузчике, я не могу найти правильный синтаксис для него.

//pointers to x_IRQHandler() functions 
void(* x_IRQ_addr)(void); 
x_IRQ_addr = (void(*)(void))(0x5008); 

//here I should call the function pointed by x_IRQ_addr; but this syntax is not valid 
void x_IRQ_Handler(void) 
{ 
    *x_IRQ_addr(); 
} 

Я пробовал разные подходы без успеха, как я могу это исправить?

+0

Поместите указатель косвенность в скобках: '(* x_IRQ_addr)()' –

+1

It'ld быть хорошей идеей, чтобы немного ознакомиться с языком перед тем, как войти в загрузчики и все эти низкоуровневые вещи ... – 3442

+0

Может ли этот контроллер не переназначить векторы в ОЗУ? –

ответ

3

Оператор вызова функции () имеет более высокий приоритет, чем оператор косвенности *.

Попробуйте использовать (*x_IRQ_addr)(); вместо *x_IRQ_addr();.

Вы также можете написать его как x_IRQ_addr();, потому что *x_IRQ_addr является функцией целеуказатель, и он будет преобразован в указатель, указывающий на функцию операнда () оператора, поэтому разыменовать идет в отходы.

+0

Приоритет подхода является хорошим моментом. –

0

Просто позвоните

x_IRQ_addr(); 

Нет необходимости * - *x_IRQ_addr() означает, что вы хотите разыменования значения, возвращаемого функцией (которая является недействительным и не возвращает ничего так или иначе).

0

Подсказка о использовании (*x_IRQ_addr)(); или *x_IRQ_addr(); сработало; Однако возникла другая проблема с присвоением ему адреса. Действительно, для того, чтобы сохранить адрес x_IRQ_addr я должен был сделать

x_IRQ_addr = *(void(**)(void))(0x5008); 

вместо

x_IRQ_addr = (void(*)(void))(0x5008); 

Но мой вопрос был, вероятно, не достаточно

0

обычным способом, чтобы обойти ясный основная проблема заключается в том, чтобы файл команды компоновщика помещал вектор вектора прерываний в другое место в целевой программе,

использовать «скопировать» в нужное место в качестве одного из элементов файла команды компоновщика.

Затем целевой код, при запуске, перед вводом 'main()' скопирует массив векторов прерываний в правильное местоположение, наложив массив векторов прерывания загрузочного кода.

В общем, это означает, что загрузочный код будет прыгать (при его загрузке) в местоположение кода «start.s» в целевом коде.

Пишешь/связи пользовательского start.s файл, который выполняет требуемую копию прерывания векторного массива в правильное место

Смежные вопросы