Оптимизация размера программы
Я пытаюсь сэкономить несколько байт размера программы. Я столкнулся с проблемой, которую не могу понять, и надеюсь, что кто-нибудь мне поможет.
Взгляните на этот пустой скетч. Это занимает всего 444 байта:
void setup()
{
}
void loop()
{
}
Однако этот – уже 1332 байта!
void f() {
Serial.println(1);
}
void setup()
{
}
void loop()
{
}
- Почему?
Предполагается, что функция f()
будет отключена на этапе связывания. Но это не так.
И что я могу сделать, чтобы отрезать такие вещи, поскольку они не используются в коде?
@zhekaus, 👍1
Обсуждение1 ответ
Использование последовательного
объекта вытягивает HardwareSerial0.o в вашу программную
компоновку. Этот файл определяет, среди прочего, ISR (
процедуры прерывания службы), связанные с последовательным портом. ISR определяются
с помощью макроса ISR()
из acr-libc. Этот макрос создает прототип
функции и присваивает ей некоторые атрибуты,
включая атрибут used
, который говорит компоновщику, что он
должен считать функцию используемой, даже если он не может обнаружить ни одного
вызова этой функции в скомпилированной программе. ISR не может быть удален,
и он, в свою очередь, сохраняет много кода из последовательной
реализации.
Edit: Как указал busybee в комментарии, хотя f()
не может быть удален во время ссылки, он может быть удален во время компиляции, если вы
даете ему статический
квалификатор. Это имеет дополнительное преимущество, вызывая
предупреждение компилятора:
предупреждение: 'void f()' определен, но не используется [-Wunused-function]
Вы могли бы добавить, что отсутствующий static
заставляет компилятор включать f()
в первую очередь. Все остальное потом втягивается этим., @the busybee
@thebusybee: Верно, я отредактировал свой ответ., @Edgar Bonet
- Экран LCD 16*02 I2C показывает только первый напечатанный символ
- неопределенная ссылка на `PPMintIn::PPMintIn(int)'
- Что мне делать с StackOverflow при ошибке компиляции?
- Ошибка компиляции с использованием arduino-mk в Arch Linux (неопределенная ссылка на __dso_handle)
- Не могу понять как исправить эту ошибку компиляции
- Как скомпилировать без добавления загрузчика?
- Компиляция/загрузка скетча Arduino Nano/Uno и js из браузера
- Как использовать SPI на Arduino?
Проблема не в
f()
, а в том, что вы теперь используете объектSerial
, который является массивным., @Majenko@Majenko Можно ли как-то его оптимизировать?, @zhekaus
Не вставляйте код, который вам не нужен? Если вы хотите, чтобы необязательный код использовал #ifdef и т. Д., чтобы включить/исключить его, чтобы компилятор никогда его не видел., @Majenko
@Majenko, Как я знаю, неиспользуемый код должен быть оптимизирован во время связывания или около того., @zhekaus
Вы *можете* обнаружить, что создание
f()
static
, как вstatic void f () {
, даст компилятору достаточно информации, чтобы на ранней стадии распознать, чтоf
не используется, и не позволит ему создавать зависимости дляprintln
, которые он позже должен будет работать, чтобы выяснить, может ли он устранить; это не особенно связано с Arduino., @timemageЕсли вам не нравится большая "Последовательная" реализация, вы можете реализовать какой-нибудь голый металлический драйвер UART, например https://exploreembedded.com/wiki/Serial_UART_Interface_with_AVR..., @Maximilian Gerhardt