Home News

Arduino: просмотр размера кода и ассемблерного листинга программы

30.09.2017

При разработке программ для плат Arduino иногда может возникнуть необходимость оценки, возможно ли выполнить оптимизацию кода, и определения места, где эта оптимизация необходима. Для этого необходимо получить ассемблерный листинг программы, а также определить, какой размер flash-памяти занимает какая-либо часть вашего кода.

Для этих целей воспользуемся двумя инструментами из набора AVR toolchain: avr-nm и avr-objdump. Оба этих инструмента поставляются вместе с Arduino IDE.

Поиск .elf файла

Итак, предположим, что вы написали скетч для Arduino и хотите оптимизировать его размер.

После компиляции скетча, первое, что необходимо сделать, это найти скомпилированный бинарный файл. Самый простой способ сделать это – включить показ подробного вывода процесса компиляции и посмотреть путь к .elf файлу в конце лога.

Настройка вывода процесса компиляции Путь к .elf файлу

В зависимости от версии Arduino IDE файл может называться либо Blink.ino.elf, либо Blink.cpp.elf, либо Blink.elf.

Просмотр размера кода с помощью avr-nm

При оптимизации размера программы важно определить место, где эта оптимизация необходима. Используя avr-nm, вы сможете определить размер каждой функции.

Откройте командную строку и введите:

set PATH=%PATH%;C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\ avr-nm --size-sort -Crtd Blink.ino.elf

После чего в консоль будет выведен размер всех функций и данных:

00000148 T __vector_16 00000118 T init 00000114 T pinMode 00000108 T digitalWrite 00000082 t turnOffPWM 00000080 T delay 00000070 T micros 00000040 T loop 00000030 T main 00000020 T digital_pin_to_timer_PGM 00000020 T digital_pin_to_port_PGM 00000020 T digital_pin_to_bit_mask_PGM 00000016 T __do_clear_bss 00000010 T port_to_output_PGM 00000010 T port_to_mode_PGM 00000008 T setup 00000004 B timer0_overflow_count 00000004 B timer0_millis 00000002 W yield 00000002 W initVariant 00000002 t __empty

Первый столбец – это размер объекта, на который ссылается символ. Второй столбец – тип, где 't' (в верхнем или нижнем регистре) означает «текст» (код или данные PROGMEM), 'd' означает «инициализированные данные» (сохраненные во flash-памяти и скопированные в RAM при запуске), а 'b' означает «неинициализированные данные» (также известные, как «BSS», не занимают flash-память, только RAM). Регистр буквы показывает, является ли символ локальным (нижний регистр) или глобальным (верхний регистр). И последний столбец – имя символа. В данном примере вы можете увидеть, что самой большой функцией здесь является __vector_16 (обработчик прерывания по переполнению таймера 0), она занимает 148 байт во flash-памяти.

rss