Должен ли оптимизатор выкидывать из конечного кода неиспользуемые методы класса?
- Войдите на сайт для отправки комментариев
Столкнулся с такой ситуацией - беру пустой код ардуино, добавляю туда экземпляр своего класса - больше ничего. Никакого кода с участием этого экземпляра нет, только обьявление - но итоговая прошивка сразу увеличивается на 8к.
В связи с этим два вопроса:
1. разве по умолчанию оптимизатор не должен выкидывать из кода неиспользуемые методы класса?
2. если по умолчанию нет - есть ли какие-то способы заставить его это делать? Или не заставить - а скорее помочь определить, что данный код лишний и может быть выкинут....
Понятно, что задача с полностью лишним классом - надуманная. Но ситуации, когда из огромной библиотеки используется лишь пара методов -они же сплошь и рядом. я всегда думал. что это не страшно. мол все лишнее оптимизатор выкинет сам. Но тут весь класс лишний - а ничего не выкидывается.
Подпишусь
рассуждая дальше....
А с чего я взял, что ничего не выкидывается? - может, если бы не выкинулось, код бы вырос на 16к. А так всего на 8 - значит оптимизатор что мог - выкинул...
Интересно, это правильное предположение? И как все-таки помочь оптимизатору выкинуть побольше?
Для начала, видимо, выяснить, а есть ли там вообще что выкидывать
каким образом?
А с чего я взял, что ничего не выкидывается? - может, если бы не выкинулось, код бы вырос на 16к. А так всего на 8 - значит оптимизатор что мог - выкинул...
Интересно, это правильное предположение? И как все-таки помочь оптимизатору выкинуть побольше?
А в листинге что, в мап-файле?
Вот тут я хз ))
Помнится, я экспериментировал со своей кнопочной библиотекой. Вроде бы создание одного экземпляра без единого вызова его методов увеличивало код на положенные 20 байт - ровно сколько он и весит
v258 20 байт в памяти переменных видимо, тут речь про память под код
Листинг надо бы изучить и с уровнем оптимизации ничего не химичили ???
Оптимизатор не должен. Это делает компоновщик.
Никакого кода с участием этого экземпляра нет, только обьявление
Это уже минимум конструктор, деструктор, таблица виртуальных методов, и всё, от чего они зависят.
v258 20 байт в памяти переменных видимо, тут речь про память под код
Листинг надо бы изучить и с уровнем оптимизации ничего не химичили ???
Уже не помню, нужно вечером проверить ))
с уровнем оптимизации ничего не химичили ???
химичил, конечно. Самый лучший результат с -0s. с остальными уровнями размер еще больше
А код то будет ? Или так и будем гипотетически трещать ? Петрович - выходи !!!
Никакого кода с участием этого экземпляра нет, только обьявление
Это уже минимум конструктор, деструктор, таблица виртуальных методов, и всё, от чего они зависят.
виртуальных методов нет, статических тоже, класс ничему явно не наследует. Если конструктор полностью вычистить, размер занимаемого кода уменьшается незначительно.
Вообще такое впечатление, что компиляция класса подтягивает кучу системного кода ардуино. ну как если бы я использовал float - одно его упоминание в скетче увеливает размер на несколько кб. Я только не пойму. почему компоновщик его не выкидывает на этапе сборки.
Просто посмотрите на размер кода современных приложений на ББ - раньше у первых ББ размер жесткого диска был меньше чем некоторые современные программы и эти ББ при этом работали и содержали большое количество приложений.
Вся это оптимизация - фикция на бумаге в основном !!!
А код то будет ? Или так и будем гипотетически трещать ? Петрович - выходи !!!
а надо? :)))))
Класс - вот https://github.com/board707/DMD_STM32/tree/old-V1
Для определенности специально взял старую ветку проекта, потому что в ней еще не было никаких "наворотов" - ни наследования, ни виртуальных функций, ни шаблонов...
Код скетча чуть позже выложу. но он простеший. кроме создания экземпляра нет ничего.
Ассемблер наше все !
Полный USB стек для COM порта на stm32 чуть больше 1000 байт.
Ассемблер наше все !
Полный USB стек для COM порта на stm32 чуть больше 1000 байт.
зачем мне USBстек. листинг я и без него могу посмотреть. И дизассемблер тоже. Знать бы что в нем искать... это ж будет килобайт сто-двести. наверно
Ну если имена/реализация методов есть - значит ничего не обрезалось
Ну если имена/реализация методов есть - значит ничего не обрезалось
ок, гляну.
Но вопрос то был - почему так :) И как исправить это, если можно
Если конструктор полностью вычистить, размер занимаемого кода уменьшается незначительно.
Я только не пойму. почему компоновщик его не выкидывает на этапе сборки.
Конструктор инициализирует всех членов класса, то бишь всё равно вызывает кучу других конструкторов.
Не выкидывает потому что код float на avr запрограммирован на ассемблере и компиляции на уровне отдельных функций не подлежит.
код
#include <DMD_STM32.h> #define DMD_PIN_A PB1 #define DMD_PIN_B PB12 #define DMD_PIN_nOE PB1 #define DMD_PIN_SCLK PB10 SPIClass dmd_spi(2); //DMD dmd(DMD_PIN_A, DMD_PIN_B, DMD_PIN_nOE, DMD_PIN_SCLK, 1, 1, dmd_spi ); void setup(void) {} void loop(void){}В таком виде размер прошивки 12 624 байт, если раскомментировать 9 строчку - 20708 байт.
Аддон Кларка, плата STM32F103C8
Ссылка на класс та же, что в сообщении 14
Листинг надо бы изучить и с уровнем оптимизации ничего не химичили ???
посмотрел мап файл - легче не стало, практически все методы класса там перечислены... это означает, что все они попали в конечный код? Ну как так-то?
У мен нету вот этого всего.
Аддон Кларка, плата STM32F103C8
Так, что я только потеоретизировать могу.
А, кстати, как там насчёт LTO? Включено? Нет?
А, кстати, как там насчёт LTO? Включено? Нет?
выключено. При попытке включения сыпятся ошибки линковки.
У мен нету вот этого всего.
Аддон Кларка, плата STM32F103C8
плата для сборки скетча не нужна, аддон вот https://github.com/rogerclarkmelbourne/Arduino_STM32
просто скачать и положить в каталог hardware установки Ардуино ИДЕ (но надо чтобы была установлена поддержка Дуе)
Это так, на случай если вдруг будет скучно и захотите попробовать :)
b707, а какой размер получается если начать 9-ю строку cловом static?
b707, а какой размер получается если начать 9-ю строку cловом static?
такой же, 20708.
Да и с чего ему менятся?
выключено. При попытке включения сыпятся ошибки линковки.
Вот с этого надо начинать
Пока не разберётесь, что там с линковкой, не будет понятно куда уходит память.
Вот с этого надо начинать
Пока не разберётесь, что там с линковкой, не будет понятно куда уходит память.
убрал ошибку линковки, собираю с -flto, стало 18656 байт. Уже хорошо, но все равно неиспользуемый класс отьедает 6к
Ну, надо смотреть что за класс. Может это и нормально, а может и нет, тут без самого класса не поймёшь. Экземпляр же объявлен, так? Значит конструктор, деструктор, аллокаторы/деаллокаторы, если есть. Что там за поля у него. Если нетривиальные, то опять же конструктор/деструктор. Что там со статическими методами. В общем, это реально смотреть надо.
Ну, надо смотреть что за класс.
класс на гитхабе, если будет время
https://github.com/board707/DMD_STM32/blob/old-V1/DMD_STM32.h
https://github.com/board707/DMD_STM32/blob/old-V1/DMD_STM32.cpp
Я понять не могу - у тебя в конструкторе много значений, а вроде выше используется только одно (значений «по умолчанию» я не увидел), как так? Что я пропустил?
Я понять не могу - у тебя в конструкторе много значений, а вроде выше используется только одно (значений «по умолчанию» я не увидел), как так? Что я пропустил?
строчку 8 и 9 не спутал?
Ну да, спутал )))
Может это поддержка spi так объемно подтягивается из аддона ?
расшифровка размера бинарника по секциям ( вывод программы arm-none-eabi-size):
С моим классом
Без него:
Видно, что в моем классе нет статических переменных.
Отмечу, и тот и другой код компилированы с -flto опцией. Вчера я этого не заметил, но как следует из цифр - LTO никак не влияет на вклад моего класса в размер кода - после включения LTO общий размер кода уменьшился. но разница за счет включения класса в код осталось прежней - порядка 8кбайт
Символьная таблица ELF файла прошивки, отсортированная по размеру:
Тут я не вполне понимаю. Например, самый большой символ в коде - это вектор прерывания CAN_USB размером аж 1.5к. Зачем он тут? Поддержку USB я вообще выключил... а кана у меня в программе нет. Или векторы прерываний включаются в код всегда?
Да и вообще если внимательно посмотреть - в списке всего тр-четыре раза всплывают функции моего класса, остальное все - системные вызовы. Значит сделать ничего нельзя?
А где такой же файл, но без экземпляра класса?
А где такой же файл, но без экземпляра класса?
продолжаем наблюдение
Заменил ARM-GCC тулчейн с древней версии 4.8.3(такая встроена в Ардуино ИДЕ для поддержки Дуе и более новой нет) на более свежую 9.2.1, как сам же писал вот тут
Итог
"Пустой скетч" всего 6720 байт
Мой код с классом - 13544 байт
Причина такого влияния на размер кода, как пишут - более продвинутая поддержка LTO в новых версиях тулчейна.
По сравнению с началом разница огромная - "выиграли" в размере уже более 7к. НО!
Разница между "пустым" скетчем и кодом с классом в результате всех усилий почти не изменилась! - было 8к, теперь чуть менее 7к
Поэтому вопрос из заголовка остается актуальным - как помочь линкеру удалить неиспользуемые методы?
скорее всего, компилятор, когда встречает обьявление класса, сразу неявно вставляет туда RTL поддержки для классов
скорее всего, компилятор, когда встречает обьявление класса, сразу неявно вставляет туда RTL поддержки для классов
ИМХО поддержка классов идет на уровне компилятора и RTL для этого в явном виде не существует
Беглый взгляд на два листинга показывает, что Ваш класс подтащил за собой библиотеку работы с памятью (malloc ...), библиотеку вычислений повышенной точности (__udivdiv3 ..) и, наверное, что то еще кроме самого себя.
как помочь линкеру удалить неиспользуемые методы?
Удалить их самому
Беглый взгляд на два листинга показывает, что Ваш класс подтащил за собой библиотеку работы с памятью (malloc ...),
=== да. это верно, она мне нужна
=== а вот вычислений у меня нет, надо будет разобраться. откуда оно... может какой-то из системных модулей тащит
Не помню, как в GCC, но в IAR можно было получить у линкера перечень перекрестных ссылок, из него ясно, что тащит за собой Ваш класс, и вроде даже где именно тащит, в какой функции.
Не помню, как в GCC, но в IAR можно было получить у линкера перечень перекрестных ссылок, из него ясно, что тащит за собой Ваш класс, и вроде даже где именно тащит, в какой функции.
Спасибо, тут это делает строчка
результат
dmd_size_test_04.ino.elf: file format elf32-littlearm dmd_size_test_04.ino.elf architecture: armv7, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x0800270d Program Header: 0x70000001 off 0x00012d48 vaddr 0x08002d48 paddr 0x08002d48 align 2**2 filesz 0x00000008 memsz 0x00000008 flags r-- LOAD off 0x00010000 vaddr 0x08000000 paddr 0x08000000 align 2**16 filesz 0x00002d50 memsz 0x00002d50 flags rwx LOAD off 0x00020000 vaddr 0x20000000 paddr 0x08002d50 align 2**16 filesz 0x00000408 memsz 0x00000408 flags rw- LOAD off 0x00023158 vaddr 0x08003158 paddr 0x08003158 align 2**16 filesz 0x00000390 memsz 0x00000390 flags r-- LOAD off 0x00030408 vaddr 0x20000408 paddr 0x20000408 align 2**16 filesz 0x00000000 memsz 0x00000598 flags rw- private flags = 5000200: [Version5 EABI] [soft-float ABI] Sections: Idx Name Size VMA LMA File off Algn 0 .text 00002d44 08000000 08000000 00010000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .text.align 00000004 08002d44 08002d44 00012d44 2**0 ALLOC, CODE 2 .ARM.exidx 00000008 08002d48 08002d48 00012d48 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .data 00000408 20000000 08002d50 00020000 2**2 CONTENTS, ALLOC, LOAD, DATA 4 .rodata 00000390 08003158 08003158 00023158 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .bss 00000598 20000408 20000408 00030408 2**2 ALLOC 6 .debug_aranges 00000060 00000000 00000000 000234e8 2**3 CONTENTS, READONLY, DEBUGGING 7 .debug_info 00000072 00000000 00000000 00023548 2**0 CONTENTS, READONLY, DEBUGGING 8 .debug_abbrev 0000003c 00000000 00000000 000235ba 2**0 CONTENTS, READONLY, DEBUGGING 9 .debug_line 000001f5 00000000 00000000 000235f6 2**0 CONTENTS, READONLY, DEBUGGING 10 .debug_frame 0000030c 00000000 00000000 000237ec 2**2 CONTENTS, READONLY, DEBUGGING 11 .debug_str 00000164 00000000 00000000 00023af8 2**0 CONTENTS, READONLY, DEBUGGING 12 .comment 00000066 00000000 00000000 00023c5c 2**0 CONTENTS, READONLY 13 .ARM.attributes 00000029 00000000 00000000 00023cc2 2**0 CONTENTS, READONLY SYMBOL TABLE: 08000000 l d .text 00000000 .text 08002d44 l d .text.align 00000000 .text.align 08002d48 l d .ARM.exidx 00000000 .ARM.exidx 20000000 l d .data 00000000 .data 08003158 l d .rodata 00000000 .rodata 20000408 l d .bss 00000000 .bss 00000000 l d .debug_aranges 00000000 .debug_aranges 00000000 l d .debug_info 00000000 .debug_info 00000000 l d .debug_abbrev 00000000 .debug_abbrev 00000000 l d .debug_line 00000000 .debug_line 00000000 l d .debug_frame 00000000 .debug_frame 00000000 l d .debug_str 00000000 .debug_str 00000000 l d .comment 00000000 .comment 00000000 l d .ARM.attributes 00000000 .ARM.attributes 00000000 l df *ABS* 00000000 crtstuff.c 08002d18 l O .text 00000000 __EH_FRAME_BEGIN__ 080000ec l F .text 00000000 __do_global_dtors_aux 20000408 l O .bss 00000000 completed.8911 08002d3c l O .text 00000000 __do_global_dtors_aux_fini_array_entry 08000110 l F .text 00000000 frame_dummy 2000040c l O .bss 00000000 object.8916 08002d28 l O .text 00000000 __frame_dummy_init_array_entry 00000000 l df *ABS* 00000000 0800012c l F .text 0000003c SetEPRxCount.constprop.0 08000168 l F .text 00000070 _i2c_irq_error_handler 080001d8 l F .text 000003b6 _i2c_irq_handler 0800058e l F .text 0000002a _Z12digitalWritehh 080005b8 l F .text 00000024 _Z8pwmWriteht 080005dc l F .text 00000020 _ZN5Print5writeEPKvm 08002070 l F .text 00000014 set_this_dev 08002084 l F .text 00000040 _ZN13HardwareTimerC2Eh 08002084 l F .text 00000040 _ZN13HardwareTimerC1Eh 080005fc l F .text 0000001a _ZN14HardwareSerial5flushEv 08000616 l F .text 0000009c _ZN14HardwareSerial5writeEh 080006b2 l F .text 00000022 _ZN14HardwareSerial4peekEv 080006d4 l F .text 00000026 _ZN14HardwareSerial9availableEv 080006fa l F .text 00000050 _ZN14HardwareSerial4readEv 0800074a l F .text 00000002 NOP_Process 0800074c l F .text 00000030 SetDeviceAddress 0800077c l F .text 0000000e Post0_Process 0800078a l F .text 00000006 DataStageIn 08000790 l F .text 00000006 In0_Process 08000796 l F .text 00000006 Standard_ClearFeature 0800079c l F .text 00000014 Standard_GetStatus 080007b0 l F .text 0000000c Standard_GetInterface 080007bc l F .text 0000000c Standard_GetConfiguration 080007c8 l F .text 00000006 usbGetStringDescriptor 080007ce l F .text 00000006 usbGetConfigDescriptor 080007d4 l F .text 00000006 usbGetDeviceDescriptor 080007da l F .text 00000014 usbGetInterfaceSetting 080007ee l F .text 00000006 usbNoDataSetup 080007f4 l F .text 00000006 usbDataSetup 080007fa l F .text 0000000e vcomGetSetLineCoding 08000808 l F .text 00000006 usbInit 0800080e l F .text 00000022 usb_set_ep_rx_stat.lto_priv.0 0800080e l F .text 00000022 usb_set_ep_rx_stat.lto_priv.1 08000830 l F .text 00000006 usbReset 08000836 l F .text 000000b6 usb_resume 080008ec l F .text 000000c4 usart_irq 080009b0 l F .text 00000066 dispatch_general 08000a16 l F .text 0000001e nvic_irq_enable.lto_priv.0 08000a16 l F .text 0000001e nvic_irq_enable.lto_priv.1 08000a34 l F .text 0000000c bb_perip.lto_priv.1 08000a34 l F .text 0000000c bb_perip.lto_priv.2 08000a34 l F .text 0000000c bb_perip.lto_priv.3 08000a40 l F .text 0000000a bb_peri_set_bit.lto_priv.0 08000a40 l F .text 0000000a bb_peri_set_bit.lto_priv.1 08000a40 l F .text 0000000a bb_peri_set_bit.lto_priv.2 08000a4a l F .text 0000000a spi_tx_dma_disable 08000a54 l F .text 00000034 rcc_do_reset_dev.constprop.0 080020c4 l F .text 00000024 rcc_set_prescaler 08000a88 l F .text 00000024 rcc_clk_enable 08000aac l F .text 00000012 spi_init 08000aac l F .text 00000012 gpio_init 08000abe l F .text 0000004e gpio_set_mode 08000b0c l F .text 00000050 dispatch_extis 08000b5c l F .text 00000030 dispatch_single_exti 08000b8c l F .text 00000016 dma_disable 08000ba2 l F .text 0000002e dma_attach_interrupt 08000bd0 l F .text 0000001a dma_irq_handler 080020e8 l F .text 000000bc _ZL20timer_default_configP9timer_dev 080021a4 l F .text 0000007c _ZL18adc_default_configP7adc_dev 08000bea l F .text 0000002e _ZL15dev_to_spi_pinsP7spi_dev.isra.0 08000c18 l F .text 00000044 _ZL19determine_baud_rateP7spi_devm.isra.0 08002220 l F .text 00000088 _ZN8SPIClassC2Em 08002220 l F .text 00000088 _ZN8SPIClassC1Em 08000c5c l F .text 00000010 _ZL12waitSpiTxEndP7spi_dev 08000c6c l F .text 0000005c _ZN8SPIClass13EventCallbackEv 08000cc8 l F .text 0000000c _ZN8SPIClass18_spi2EventCallbackEv 08000cd4 l F .text 0000000c _ZN8SPIClass18_spi1EventCallbackEv 08000ce0 l F .text 000000fa _ZN3DMD8latchDMAEv 08000dda l F .text 000000d0 _ZN3DMD8drawLineEiiiih 08000eaa l F .text 00000038 _ZN3DMD13drawFilledBoxEiiiih 08000ee2 l F .text 000000a6 _ZN3DMD10writePixelEjjhh 08000f88 l F .text 00000204 _ZL17scan_running_dmdsv 08001198 l F .text 0000000c _ZL17SPI1_DMA_callbackv 0800118c l F .text 0000000c _ZL17SPI2_DMA_callbackv 080022a8 l F .text 0000009c _Z7pinModeh13WiringPinMode 080011a4 l F .text 00000032 _ZL11disable_pwmPK14stm32_pin_info 080011d6 l F .text 000000ce _ZN8SPIClass5beginEv 080012a4 l F .text 00000268 _ZN3DMD4initEt 0800150c l F .text 000003f6 _ZN3DMD8drawCharEiihhh.constprop.0 08001902 l F .text 00000256 _ZN3DMD11stepMarqueeEiih 08001b58 l F .text 00000020 _ZN5Print5writeEPKc 08001b78 l F .text 0000001a _ZN3DMD11clearScreenEh 08002344 l F .text 0000022c _GLOBAL__I_65535_0_dmd_size_test_04.ino.cpp.o.7405 08002572 l F .text 00000176 _Z7premainv 080026e8 l F .text 00000024 _GLOBAL__sub_D_dmd_spi 08003158 l O .rodata 00000230 PIN_MAP 200002ec l O .data 00000008 gpioa 20000030 l O .data 00000024 timer2 2000030c l O .data 00000018 adc1 20000054 l O .data 00000024 timer3 20000008 l O .data 00000028 timer1 200002f4 l O .data 00000008 gpiob 20000078 l O .data 00000024 timer4 200002fc l O .data 00000008 gpioc 08003388 l O .rodata 0000005c rcc_dev_table 080033e4 l O .rodata 00000014 masks.4505 080033f8 l O .rodata 00000080 exti_channels 08003478 l O .rodata 00000008 _ZL17bPixelLookupTable 08003480 l O .rodata 00000009 CSWTCH.6 08003489 l O .rodata 00000009 CSWTCH.5 08003494 l O .rodata 00000024 _ZTV14HardwareSerial 080034b8 l O .rodata 00000018 _ZTV3DMD 2000009c l O .data 00000007 line_coding 200000a4 l O .data 00000010 usblib 200000b4 l O .data 00000008 reset_regs.4500 200000bc l O .data 0000000c enable_regs.4496 200000c8 l O .data 00000008 spi1 200000d0 l O .data 00000040 dma1 20000110 l O .data 00000008 spi2 20000118 l O .data 00000002 _ZL8scan_int 2000011c l O .data 00000094 usart1 20000760 l O .bss 0000000c usart1_rb 20000754 l O .bss 0000000c usart1_wb 200001b0 l O .data 00000094 usart2 20000748 l O .bss 0000000c usart2_rb 2000073c l O .bss 0000000c usart2_wb 20000244 l O .data 00000094 usart3 20000730 l O .bss 0000000c usart3_rb 20000724 l O .bss 0000000c usart3_wb 200002d8 l O .data 0000000c enable_regs.4509 200002e4 l O .data 00000008 _ZN6wirish4priv15w_board_pll_cfgE 2000039c l O .data 00000004 _ZN6wirish4privL8pll_dataE 20000304 l O .data 00000008 gpiod 20000324 l O .data 00000008 adc2 2000032c l O .data 00000038 i2c2 20000364 l O .data 00000038 i2c1 20000424 l O .bss 00000004 systick_uptime_millis 20000428 l O .bss 00000001 _ZL7this_id 2000042c l O .bss 00000004 _ZL9this_devp 20000430 l O .bss 00000002 StatusInfo 20000432 l O .bss 00000002 ResumeS 20000434 l O .bss 00000004 dma2Ch4_5 20000438 l O .bss 00000004 _ZL10_spi1_this 2000043c l O .bss 00000004 _ZL10_spi2_this 20000440 l O .bss 00000001 _ZZL17scan_running_dmdsvE1i 20000444 l O .bss 00000008 _ZL12running_dmds 2000044c l O .bss 00000001 _ZL15running_dmd_len 20000450 l O .bss 00000004 Timer4 20000454 l O .bss 00000004 Timer3 20000458 l O .bss 00000004 Timer1 2000045c l O .bss 00000004 Timer2 20000460 l O .bss 00000018 Serial1 20000478 l O .bss 00000018 Serial2 20000490 l O .bss 00000018 Serial3 200004a8 l O .bss 0000004c SPI 200004f4 l O .bss 0000004c dmd_spi 20000540 l O .bss 000001e0 dmd 20000720 l O .bss 00000002 SaveRState 20000722 l O .bss 00000002 SaveTState 2000076c l O .bss 00000004 pbreak.4664 20000770 l O .bss 00000100 vcomBufferRx 20000870 l O .bss 00000100 vcomBufferTx 20000970 l O .bss 00000001 transmitting 20000974 l O .bss 00000004 tx_tail 20000978 l O .bss 00000004 tx_head 2000097c l O .bss 00000004 rx_tail 20000980 l O .bss 00000004 rx_head 20000984 l O .bss 00000001 line_dtr_rts 080034d0 l O .rodata 00000008 _ZL14board_spi_pins 080034d8 l O .rodata 00000004 _ZL18board_alt_spi_pins 080034dc l O .rodata 00000008 _ZL10baud_rates 00000000 l df *ABS* 00000000 C:\Users\Dmit\AppData\Local\Temp\arduino_build_926675\core\wirish\start.S.o 00000000 l df *ABS* 00000000 exc.S.o 08002734 l F .text 00000000 __default_exc 0800276c l .text 00000000 NVIC_CCR 08002770 l .text 00000000 SYSTICK_CSR 08002760 l .text 00000000 CPSR_MASK 08002768 l .text 00000000 TARGET_PC 08002764 l .text 00000000 EXC_RETURN 00000000 l df *ABS* 00000000 isrs.S.o 00000000 l df *ABS* 00000000 errno.c 00000000 l df *ABS* 00000000 init.c 00000000 l df *ABS* 00000000 memset.c 00000000 l df *ABS* 00000000 malloc.c 00000000 l df *ABS* 00000000 memcpy-stub.c 00000000 l df *ABS* 00000000 nano-mallocr.c 00000000 l df *ABS* 00000000 nano-mallocr.c 00000000 l df *ABS* 00000000 sbrkr.c 00000000 l df *ABS* 00000000 lib_a-strlen.o 00000000 l df *ABS* 00000000 mlock.c 00000000 l df *ABS* 00000000 lock.c 00000000 l df *ABS* 00000000 _aeabi_ldivmod.o 00000000 l df *ABS* 00000000 libgcc2.c 00000000 l df *ABS* 00000000 _dvmd_tls.o 00000000 l df *ABS* 00000000 c:/users/dmit/appdata/local/arduino15/packages/arduino/tools/arm-none-eabi-gcc/gcc-9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/thumb/v7-m/nofp/crti.o 00000000 l df *ABS* 00000000 c:/users/dmit/appdata/local/arduino15/packages/arduino/tools/arm-none-eabi-gcc/gcc-9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/thumb/v7-m/nofp/crtn.o 00000000 l df *ABS* 00000000 impure.c 200003a4 l O .data 00000060 impure_data 00000000 l df *ABS* 00000000 reent.c 08002728 g F .text 00000000 __exc_memmanage 08002774 w F .text 00000000 __stm32reservedexception9 08000000 g O .text 000000ec __stm32_vector_table 08001da0 g F .text 00000018 __irq_usart2 08001f60 g F .text 0000000c __irq_dma1_channel3 20000000 g .data 00000000 __data_start__ 08001ed0 g F .text 0000000c __irq_i2c2_er 20000994 g O .bss 00000001 __lock___atexit_recursive_mutex 08001edc g F .text 0000000c __irq_i2c1_er 00000000 *UND* 00000000 __irq_sdio 00000000 *UND* 00000000 __irq_fsmc 00000000 *UND* 00000000 __irq_tim6 080029a0 g F .text 0000000c __malloc_unlock 08001b92 g F .text 0000018e __irq_usb_lp_can_rx0 20000995 g O .bss 00000001 __lock___arc4random_mutex 08002d50 g .ARM.exidx 00000000 __exidx_end 08001df4 g F .text 00000050 __irq_tim1_cc 08002778 g F .text 0000000c __errno 08002d48 g .text.align 00000000 __text_end__ 08001f3c g F .text 0000000c __irq_dma1_channel6 08000000 g .text 00000000 __text_start__ 20000990 g O .bss 00000004 errno 08001de8 g F .text 0000000c __irq_tim2 00000000 *UND* 00000000 __irq_uart5 08002774 w F .text 00000000 __exc_debug_monitor 08001f78 g F .text 0000000c __irq_dma1_channel1 00000000 *UND* 00000000 __irq_adc3 080027fc g F .text 0000001c memcpy 00000000 *UND* 00000000 __irq_dma2_channel2 08002774 w F .text 00000000 __exc_svc 08002d44 g .text 00000000 __fini_array_end 080027dc g F .text 00000010 malloc 20000408 g .bss 00000000 __bss_start__ 08001f54 g F .text 0000000c __irq_dma1_channel4 08001f84 g F .text 00000058 __irq_adc 08001dd0 g F .text 0000000c __irq_tim4 00000000 *UND* 00000000 __irq_tim8_brk 08002a50 g F .text 000002c4 .hidden __udivmoddi4 08002964 g F .text 00000020 _sbrk_r 08001f2e g F .text 0000000e __irq_dma1_channel7 08001f28 g F .text 00000006 __irq_exti0 08002730 g F .text 00000000 __exc_usagefault 08002774 w F .text 00000000 __irq_can_rx1 08002d48 g .text.align 00000000 __exidx_start 20000996 g O .bss 00000001 __lock___env_recursive_mutex 20000997 g O .bss 00000001 __lock___sinit_recursive_mutex 08002784 g F .text 00000048 __libc_init_array 08002028 g F .text 00000048 start_c 08001fde g F .text 0000004a _sbrk 08002d18 g F .text 00000000 _init 08002774 w F .text 00000000 __irq_spi2 20000998 g O .bss 00000001 __lock___malloc_recursive_mutex 08002774 w F .text 00000000 __irq_can_sce 00000000 *UND* 00000000 __irq_tim8_up 200009a0 g .bss 00000000 _lm_heap_start 080029ae g F .text 00000002 __retarget_lock_release_recursive 08001f1c g F .text 00000006 __irq_exti2 08001ec0 g F .text 00000010 __exc_systick 20000408 g .data 00000000 __data_end__ 200009a0 g .bss 00000000 __bss_end__ 08001e78 g F .text 00000024 __irq_tim1_up 00000000 *UND* 00000000 __irq_uart4 08002818 g F .text 00000098 _free_r 080034e4 g .rodata 00000000 _lm_rom_img_cfgp 08001f16 g F .text 00000006 __irq_exti3 08001d20 g F .text 00000068 __error 08001f08 g F .text 00000008 __irq_exti9_5 0800272c g F .text 00000000 __exc_busfault 00000000 *UND* 00000000 __irq_dma2_channel4_5 08002774 w F .text 00000000 __irq_pvd 08002774 w F .text 00000000 __irq_tamper 08002774 g F .text 00000000 __default_handler 08002774 w F .text 00000000 __irq_wwdg 08002d14 w F .text 00000002 .hidden __aeabi_ldiv0 08002774 w F .text 00000000 __stm32reservedexception10 08002774 w F .text 00000000 __irq_flash 08002994 g F .text 0000000c __malloc_lock 08002d3c g .text 00000000 __fini_array_start 08001ee8 g F .text 0000000c __irq_i2c2_ev 080029ac g F .text 00000002 __retarget_lock_acquire_recursive 080027cc g F .text 00000010 memset 08002570 g F .text 00000002 main 20005000 g .text 00000000 __msp_init 08002d30 g .text 00000000 __init_array_end 080028b0 g F .text 000000b4 _malloc_r 08001e9c g F .text 00000024 __irq_tim1_brk 0800270c g F .text 00000000 __exc_reset 08001f6c g F .text 0000000c __irq_dma1_channel2 00000000 *UND* 00000000 __irq_tim8_trg_com 08001db8 g F .text 00000018 __irq_usart1 08001f48 g F .text 0000000c __irq_dma1_channel5 08002774 w F .text 00000000 __stm32reservedexception13 08002724 g F .text 00000000 __exc_hardfault 08002d30 g F .text 00000000 _fini 08002774 w F .text 00000000 __irq_rtc 00000000 *UND* 00000000 __irq_tim5 08002774 w F .text 00000000 __irq_spi1 08001e44 g F .text 00000034 __irq_tim1_trg_com 200003a0 g O .data 00000004 _impure_ptr 08002d24 g .text 00000000 __preinit_array_end 08002774 w F .text 00000000 __stm32reservedexception7 08002774 w F .text 00000000 __irq_usb_hp_can_tx 00000000 *UND* 00000000 __irq_tim8_cc 08001f00 g F .text 00000008 __irq_exti15_10 08001f10 g F .text 00000006 __irq_exti4 08002720 g F .text 00000000 __exc_nmi 00000000 *UND* 00000000 __irq_dma2_channel3 00000000 *UND* 00000000 __irq_tim7 08002774 w F .text 00000000 __irq_rtcalarm 200009a0 g .bss 00000000 _end 20000999 g O .bss 00000001 __lock___at_quick_exit_mutex 00000000 *UND* 00000000 __irq_spi3 08002774 w F .text 00000000 __stm32reservedexception8 00000000 *UND* 00000000 __irq_dma2_channel1 08002d14 w F .text 00000002 .hidden __aeabi_idiv0 08002d24 g .text 00000000 __init_array_start 08002774 w F .text 00000000 __exc_pendsv 08001ef4 g F .text 0000000c __irq_i2c1_ev 08001fdc w F .text 00000002 _exit 08002774 w F .text 00000000 __irq_usbwakeup 2000099a g O .bss 00000001 __lock___dd_hash_mutex 2000099b g O .bss 00000001 __lock___tz_mutex 08002984 g F .text 00000010 strlen 0800270c g F .text 00000000 __start__ 2000098c g O .bss 00000004 __malloc_sbrk_start 08001f22 g F .text 00000006 __irq_exti1 08002774 w F .text 00000000 __irq_rcc 08001ddc g F .text 0000000c __irq_tim3 20000988 g O .bss 00000004 __malloc_free_list 08001d88 g F .text 00000018 __irq_usart3 08002d24 g .text 00000000 __preinit_array_start 080029b0 g F .text 00000000 .hidden __aeabi_ldivmod 28008158 g .rodata 00000000 _lm_heap_end 2000099c g O .bss 00000001 __lock___sfp_recursive_mutex 080027ec g F .text 00000010 freeпосле перерыва вновь вернулся к изысканиям насчет размера кода.
Напомню суть - разбираюсь, как в аддоне Кларка для СТМ избавится от включения в код неиспользуемых функций и процедур.
Например - из листинга в #38 видно, что самой большой секцией в коде является вектор __irq_usb_lp_can_rx0. Это тем более обидно, что в коде CAN и USB не используется, USB-загрузчик отключен (загрузка через St-link)
Похоже, что аддон Кларка тянет USBlib в код по умолчанию Все дефайны типа STM32_MCU_HAS_USB выключил - и все равно вижу в логе сборки, что usb-lib компилируется.
Вопрос - как ее убрать? Она точно влияет на код. Попробовал тупо заменить вектор __irq_usb_lp_can_rx0 на заглушку - код сразу уменьшился более чем на 1к
PS оптимизация с опцией -0s, LTO включено
Похоже, что аддон Кларка тянет USBlib в код по умолчанию
Вопрос - как ее убрать? Она точно влияет на код. Попробовал тупо заменить вектор __irq_usb_lp_can_rx0 на заглушку - код сразу уменьшился более чем на 1к
отвечаю сам себе.
Хоть я жутко ленивый, но в выходные выполнил тупую работу - методично заменил все функции и методы USBlib на пустые заглушки. Результат - размер прошивки не изменился.
Вывод1 - работа была лишней, компилятор с линкером отлично справляются с выкидыванием неиспользуемых функций из кода. А то, что их компиляция видна в логе - ничего не значит, они только компилируются. но в итоговый бинарник не попадают.
Однако у векторов прерывания поведение другое. Как уже писал выше, замена вектора __irq_usb_lp_can_rx0 на пустышку дала уменьшение размера кода на 1к. Тоже самое когда почистил вектора __irq_i2c и __irq_i2c_error(в точных названиях могу наврать, пишу по памяти) - выиграл суммарно еще 1к.
Вывод2 - оптимизатор не удаляет вектора прерываний из кода, да если они ни разу не вызываются в программе.
Хотелось бы услышать мнение старших, мои предположения верные?
Вывод2 - оптимизатор не удаляет вектора прерываний из кода, да если они ни разу не вызываются в программе.
Дак он и не может предсказать, будут ли они вызываться, поэтому оставляет все, на всякий случай. Прерывания на то и прерывания, что в явном виде ниоткуда не вызываются.
Спасибо.
не знаю, стоит ли возиться и добавлять в вектора прерываний директивы условной компиляции, чтобы их можно было "выключать", когда они не используются? Или это криво и костыльно?
Цель - ширше задействовать для проектов плату STM32F103C6, у которой флеш 32К вместо 64к/128к у блюпила