2016-08-01 3 views
3

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

typedef void (*const ISRFunction)(void); 

__attribute__((weak)) void ISR0(void){ for(;;); } 
__attribute__((weak)) void ISR1(void){ for(;;); } 
... 
__attribute__((weak)) void ISR78(void){ for(;;); } 
... 

ISRFunction __vector_table[0x79] = 
{ 
    (ISRFunction)&ISR0, 
    (ISRFunction)&ISR1, 
    ... 
    (ISRFunction)&ISR78, 
    ... 
} 

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

void blinkLed(void) 
{ ... } 

Наконец, у меня есть главный исходный файл, с main функции и конфигурации устройства. На прерывании 78, я хотел бы моргнуть во главе. Итак, я пишу сильную функцию ISR78 так:

void ISR78(void) 
{ 
    blinkLed(); 
} 

Интересно, есть ли решение отменить слабую функцию ISR78 непосредственно blinkLed, т.е. хранящий адрес blinkLed внутри __vector_table без изменения или переименовать функцию?

РЕДАКТИРОВАТЬ:

Я использую GNU GCC 4.9.3 и связанного с линкера (ГНУ Л.Д. 2.24.0). Я могу изменить main.c и Makefile, связанные проецировать

+0

Некоторые компиляторы (не знают о ваших) поддерживают псевдонимы символов, которые могут быть чем-то интересным. – user694733

+0

Кроме того, вы должны быть очень конкретны в отношении типов функций: 'void func (void)' (без аргументов) и 'void func()' (неопределенное количество аргументов) - это разные типы. Используйте 'void' всегда для функций без аргументов, чтобы избежать проблем. – user694733

+0

@ user694733 спасибо за совет, я позабочусь об этом – Garf365

ответ

0

Единственный способ я вижу, чтобы добиться того, что вы хотите сделать, это исправить таблицу символов объектного файла, содержащего blink символ с ISR78 символом.

objcopy [...] --redefine-SYM мигания = ISR78

должны сделать это. Затем компоновщик должен автоматически вставить адрес таблицы blink в таблицу векторов. Очевидно, что ваш символ blink исчез после этого и не должен вызываться из других мест.

Я хотел бы, однако, считать это взломом.

В случае _vector_table глобально доступен и в записываемой памяти (не предполагается, что это, вероятно, слишком просто ...), вы могли бы просто залатать его с вашего собственного кода,

_vector_table [0x78] = blink; 

во время выполнения.

+0

. Я рассмотрю этот метод. Я предпочитаю метод с '__attribute__' или любым конкретным или общим кодом C или с компоновщиком (компоновщик или скрипт компоновщика), но это уже первый метод. Я согласен с вами, рассматривая это как взломать. Кроме того, может быть опасно, если 'blink' используется в другом месте (но поскольку он управляет ISR, он не должен вызывать else где) – Garf365

+0

@ Garf365, возможно, вы могли бы использовать команду' ld' '--defsym' с аргументом, подобным 'ISR78 = blink' (или это наоборот?) - я, однако, никогда не пробовал это сам и не знаю, какие другие последствия могут иметь это или он будет работать вообще. – tofro

+0

Наконец, это не тот ответ, который я хотел, но он кажется единственным возможным ответом. Большое спасибо – Garf365

0

tl; dr: у вас уже есть рабочее решение, которое, по-видимому, является решением, которое явно поддерживается и поощряется с использованием слабых символов в первую очередь. Какое улучшение вы ожидаете от другого решения?

символы

Linker ищутся по имени, поэтому единственными альтернативами использования ожидаемого имени являются: предложение

  1. tofro, чтобы изменить шаг ссылок непосредственно
  2. изменить таблицу функции указателя себя

Все дело в том, чтобы сделать ISR78 слабым символом в первую очередь, чтобы разрешить только переопределение (по имени символа), которое вы уже использовали.

Я не вижу никакого способа изменить таблицу векторов прерываний: лучше, чем просто использовать ожидаемое имя функции напрямую, даже если это возможно.

+0

Я могу понять, что OP хочет удалить одно одностороннее обращение (которое обычно оценивается одной инструкцией о ветвях). Есть проблемы, когда каждый цикл подсчитывается. – tofro

+0

_Which_ one anirection? Вы звоните через таблицу, и компоновщик фиксирует таблицу - включая выбор между слабыми и другими символами - во время соединения. Существует _no impact_ во время вызова функции независимо от того, какой из них вы выберете (если вы не используете динамическую компоновку и, по крайней мере, функцию батута). – Useless

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