Ошибка линковщика в непонятном месте, кто-то сталкивался?
- Войдите на сайт для отправки комментариев
Пнд, 28/03/2016 - 18:24
/tmp/build2401421066527260655.tmp/Arhat/arhat.c.o: In function `__vector_23': /home/arhat109/Arduino/libraries/Arhat/arhat.h:601:(.text.__vector_23+0x3a): relocation truncated to fit: R_AVR_7_PCREL against `no symbol' /home/arhat109/Arduino/libraries/Arhat/arhat.h:601:(.text.__vector_23+0x42): relocation truncated to fit: R_AVR_7_PCREL against `no symbol' collect2: error: ld returned 1 exit status
Погуглил. Типа ситуация когда линкер не может переместить код из-за использованных относительных коротких переходов. ?!? как это?
Дело в том, что он указывает на .. точку входа в обработчик прерывания от таймера (__vector_23) .. Компиляция и сборка под ИДЕ 1.6.4, плата Ардуино Мега. Установки с тех пор "как инсталлировалась ИДЕ", так линкеру и не менялись..
То есть, выходит что компилятор не может передать управление на точку входа из таблицы векторов относительным переходом RJMP / RCALL?!?
Кто-то может пояснить в чем дело?
P.S.
Потребовалось использовать хук для вызова процедур без параметров из под прерывания от таймера и тут-то и обнаружилось, что такой вызов "портит" несохраненные регистры. Добавил в обработчик сохранение и восстановление контекста и получил эту ошибку...
Опции с которыми ИДЕ запускает компилятор:
~/progs/arduino-1.6.4/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -MMD -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10604 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -I~/progs/arduino-1.6.4/hardware/arduino/avr/cores/arduino -I~/progs/arduino-1.6.4/hardware/arduino/avr/variants/mega -I~/Arduino/libraries/Arhat -I~/progs/arduino-1.6.4/hardware/arduino/avr/libraries/Wire -I~/Arduino/libraries/LiquidCrystal_I2C -I~/Arduino/libraries/Arhat/utility ~/Arduino/libraries/Arhat/arhat.c -o /tmp/build2401421066527260655.tmp/Arhat/arhat.c.o
Теперь я ваще не понимаю в чем дело. Версия компилятора и линковщика 4.8.1 .. в которой опция предпочитать короткие относительные переходы (--) УДАЛЕНА вовсе!
"Update: To avoid the unnecessary confusion this error may cause
-mshort-calls
was deprecated in avr-gcc 4.7 and will be removed from 4.8. Source: GCC 4.8 Changes."Что я сделал не так?
скачай https://downloads.arduino.cc/arduino-1.6.8-windows.zip и попробуй всё заново.
?!? вроде раз сто уже писал, что нет у меня батута, тьфу ты винды. У меня стоит (и это видно по тексту выше!) - рассовоправильный ЛИНУКС.
Да и вопрос вроде как не про какую-то сборку .. а в каких случаях такая ошибка может вылезти в "казалось бы" верном коде .. тем более, что опция линкера, её создающая - УДАЛЕНА из этой версии линковщика..
.. тут скорее всего какой-то косяк в коде или чем ещё... но вот с какой стороны копать - пока не доперло. Сталкивался? Когда, как .. адреса, пароли явки. Вдруг поможет...
?!? вроде раз сто уже писал, что нет у меня батута, тьфу ты винды. У меня стоит (и это видно по тексту выше!) - рассовоправильный ЛИНУКС.
мне плевать под чем ты сидишь: под виндой или под спайсами - скачай последню версию ИДЕ. начиная с версии 1.6.7 они многое исправили.
в каких случаях такая ошибка может вылезти в "казалось бы" верном коде
в случае, если используешь гавно мамонта, а не последнюю финальную версию ИДЕ.
Ха, нашел!
Меня заинтриговала тестовка ошибки:
.text.__vector_23+0x42 .. типа 42 байт от начала обработчика. Скомпилял в ассемблер и пошукал .. и упс, вот оно!
Код обработчика:
Отличие от репозиторного в том, что для сохранения контексту добавил команды push/pop на весь регистровый файл .. и смещения 0x3a, 0x42 - это как раз переходы на метку .L1
то бишь он не смог сгенерить адрес перехода из-за большого числа команд push/pop и "версия кумпилятора" тут ни при чем.
Решено, можно закрыть тему.
Одно не понял почему регистры пушатся в одном порядке, а обратно в другом, это кто так сделал? Выглядит жутковато :)
Это я - тормоз .. спать уже сильно хотелось, уже исправлено конечно же. :)
Так, все заработало как надо. Итого теперь имеем:
а) вариант короткого обработчика, без Хука вовсе: позволяет шустро и компактно считать время, не отвлекаясь если не требуется;
б) вариант с хуком, но без контекста сохранения (push/pop) .. не проверял, но похоже что если у процедур хука требовать выставление атрибута signal или volatile, то полное сохранение регистров будет им прописано компилятором автоматом .. надо попгобовать. Но тогда каждой, что не есть рассово-верно..
в) вариант с хуком И контекстом сохранения - для целей RTOS он получается самый компактный, даже в случае единственной процедуры хука. И, при таком указании места сохранения/восстановления контекста, в случае отсутствия процедуры или срабатывании защелки имеет наикратчайшее время исполнения самого обработчика. Удаление из описания обработчика NAKED - приведет к появлению глобального контекста сохранения, что негативно скажется на обработке прерывания независимо от режимов: есть проведура хука или нет ее, вызвана уже или ещё нет..
Хочется сохранить возможность компиляций по варианту "а" .. опять вводить "режим компиляции" константами препроцессора?
Да, и кстати, тут подумалось: а что если типовой процедуре из wiring.c просто устанавливать атрибу weak .. кумпилятыр перестанет матерится на два определения обработчиков? Может тогда будет и не надо выносить wiring.c? Да и для построения библиотек можно будет в целом рекомендовать такой подход .. интересно сочетание used и weak компилятор верно распознает что "втыкать обязательно, но не настырно"?