Как включить максимальное удаление мертвого кода?
Мне не хватает памяти для кода и данных на ATMega328P.
Размер кода большой, поскольку я использовал несколько библиотек, но я использую только несколько функций из этих библиотек.
Очевидно, что IDE по умолчанию выполняет лишь частичную работу по удалению мертвого кода (удалению кода и данных, на которые нет ссылок).
Некоторые эксперименты показывают:
Обычная программа, использующая несколько библиотек Arduino, имеет размер кода 22 килобайта.
Переименуйте настройку в o_setup. Переименуйте цикл в o_loop
Добавить
void setup(){};
voidloop(){};
Размер кода составляет 8 килобайт, а программа фактически «пустая».
Запустите новую программу.
Добавить
void setup(){};
voidloop(){};
Размер кода — 0,5 килобайта
Очевидно, IDE (компоновщик, вызываемый IDE) выполняет «частичное» удаление мертвого кода, сокращая размер кода с 22 КБ до 8 КБ (случай 1 и 2) вместо 0,5 КБ ( случай 3).
Как я могу включить функцию максимального удаления мертвого кода (освободить пространство кода, занятое неиспользуемыми библиотечными функциями)?
@EEd, 👍5
Обсуждение1 ответ
Лучший ответ:
Включите подробную информацию о компиляции в вашей IDE через настройки. Оттуда вы сможете точно увидеть, что и как компилируется.
Короче говоря, IDE (и набор инструментов) скомпилирует все, что сможет найти, в объект. На этапе компоновки компилируется только используемый код, поскольку сбор мусора включается командой "--gc-sections".
Обратите внимание, что уровень оптимизации — «-Os» или «Оптимизировать по размеру». В IDE 1.0.+ это жестко запрограммировано. Если, как в IDE 1.5.+, параметры компилятора настраиваются, то в "\arduino-1.5.6-r2\hardware\arduino\avr\platform.txt" их можно настроить в соответствии с вашими потребностями.
Где вы можете использовать команду avr-objdump, как описано в https://stackoverflow.com/questions/15291750/does-importing-libraries-load-everything-in-arduino/15296808#15296808.
Я бы рекомендовал 1.5.6r2, а не 1.5.7, поскольку команды gcc не будут запускаться индивидуально без каких-либо манипуляций с путями.
вы можете попробовать изменить -Os на -O2 или -O3, чтобы уменьшить размер. Предполагается, что S включает 2. Однако я видел, как в некоторых случаях оно становилось меньше., @mpflaga
-O2
и -O3
просят компилятор оптимизировать вывод по скорости, а не по размеру. Таким образом, скомпилированный двоичный файл станет больше, а не меньше., @fuenfundachtzig
- Генерация истинного аналогового сигнала с помощью Arduino
- Ошибка в проекте ИК-приемника
- Преобразование int или float в массив байтов в ардуино
- Включает ли скомпилированный бинарный файл скетча неиспользуемые функции из библиотеки?
- Отправка и получение аналоговых данных от одного arduino к другому arduino через web/ethernet
- Ожидаемый инициализатор перед "myservo"
- C++ против языка Arduino?
- Как объявить массив переменного размера (глобально)
Имейте в виду, что некоторые библиотеки объявляют глобальные переменные, экземпляры класса, для которых код конструктора (и все его зависимости) будет связан с конечной программой. Следовательно, простой факт
#include
библиотеки, но не использования ее, все равно может добавить много кода в процессе компоновки., @jfpoilpretМне нужны все библиотеки, поскольку они являются драйверами физических аппаратных чипов. Но я использую только несколько функций каждой библиотеки. Не могли бы вы объяснить "экземпляры класса, для которых код конструктора"? Глобальную переменную можно «оптимизировать/удалить» с помощью компоновщика, который увидит, что она объявлена как никогда не используемая, просматривая карту связей языка ассемблера, верно?, @EEd
В случае 2 вы также удалили весь код за пределами цикла2 и настройки2. Например, чтобы использовать библиотеку Servo, вы должны использовать
#include <Servo.h>
Servo myservo;
. ЗдесьServo myservo;
фактически создаёт экземпляр класса Servo со всей памятью, необходимой для его частных переменных., @GerbenМожете ли вы перечислить библиотеки, которые вам нужны?, @Craig
У меня есть несколько плат аппаратных датчиков, и у каждой есть своя необходимая библиотека (драйвер) для работы. Например, драйвер ЖК-дисплея имеет множество функций для рисования линий, кругов, круговых диаграмм, заливок и т. д., но я использую только режим рисования трехмерного текста. В худшем случае я могу вручную удалить неиспользуемую часть исходного кода библиотеки. Это может занять время, поскольку взаимозависимость присутствует повсюду. LINKER должен иметь возможность выполнять эту задачу автоматически. Вопрос в том, как его включить и дать команду на выполнение? Компилятор по-прежнему может выделять пространство для кода/памяти. компоновщик - это конечные ворота, которые содержат полную и последнюю информацию, какой код где, кому звонить и кто звонил, @EEd
Например, многие библиотеки драйверов аппаратных датчиков имеют две функции для указания единиц СИ и британских единиц. Я использую только один. Некоторые из них имеют аппаратно изменяемые настройки, такие как диапазон, усиление, параметры. Многие из них мне не нужны, поскольку я использую множество настроек по умолчанию., @EEd