Объяснение:
Как следует из сообщения об ошибке, проблема связана с перемещением (кода), которое приводит к некоторому усечению .Сообщение приходит от компоновщика, который пытается отобразить фрагменты кода в соответствующие места в памяти программы.
Когда код помещается или перемещается в какое-то место («перемещение») и thisкод ссылается из другого фрагмента кода, через JMP
или CALL
(т.е. вызов функции), перемещенный адрес должен быть добавлен к инструкции JMP
или CALL
, ссылающейся на него.
Устройства AVR поддерживают два вида инструкций перехода / вызова: JMP
против RJMP
и CALL
против RCALL
.Варианты R
делают вызовы относительно текущего местоположения и более эффективны как в использовании памяти программы, так и во время выполнения.Однако это обходится дорого: RJMP
и RCALL
могут использоваться только для адресов в диапазоне +/- 4 КБ от их расположения в памяти программ.Это никогда не является проблемой для устройств с объемом памяти программ не более 8 КБ, поскольку весь диапазон 8 КБ можно адресовать из любого места с помощью RCALL
или RJMP
.
На устройствах с объемом памяти программ более 8 КБоднако это не относится к всем возможным местоположениям.Поэтому , если компоновщик решит, что он может поместить код, который будет называться , в диапазон +/- 4 КБ из RJMP
/ RCALL
, то будетбез проблем, , но , если компоновщик не может (пере) найти код в этом диапазоне, RJMP
/ RCALL
нельзя использовать для достижения нового кодаадрес, адрес, таким образом, усекается (как при выполнении uint16_t value = 12345; uint8_t truncatedValue = value;
в C), и сгенерированный код прерывается.
Обратите внимание, что может или может не произойти для любого данного проекта, превышающего 4 КБ памяти программ (на устройствах с> 8 КБ памяти программ) в какой-то момент, потому что это зависит от перемещения необходимого кода, который может в основном меняться с каждой новой строкой кода Cдобавляется или удаляется, с каждой библиотекой, добавляемой для связывания, или даже в порядке , в котором библиотеки или другие фрагменты кода связаны (например, вызов из «A» в «B» может работать, когдакомпоновщик находит код, такой как «ABC», но терпит неудачу, когда компоновщик решаетпереместить как "ACB").
Решение:
Вы должны сообщить компилятору, что ему нужно генерировать JMP
/ CALL
инструкции вместо (более эффективных) RJMP
/ RCALL
инструкции.В AVR Studio / Atmel Studio это можно сделать через свойства проекта, набор инструментов, компилятор AVR / GNU C, оптимизацию.Соответствующим параметром является «Использовать rjmp / rcall (ограниченный диапазон) на> 8k устройствах (-mshort-вызовы)» , которое должно быть unchecked , чтобы предотвратить именованную ошибку.
Как указывает метка, соответствующий параметр командной строки - -mshort-calls
, который необходимо удалить из списка параметров командной строки gcc, чтобы добиться того же при вызове gcc извне IDE.
Обновление:
Во избежание ненужной путаницы эта ошибка может привести к тому, что -mshort-calls
было устарело в avr-gcc 4.7 и будет удалено из 4.8.Источник: GCC 4.8 Изменения .
Пользователи теперь должны использовать -mrelax
вместо того, чтобы генерировать двоичные файлы, которые имеют оптимизацию вызовов, где возможно , но никогда не приведут к ошибке.