WinAVR. Использование инструментов GNU #01. Опции C-компилятора AVR-GCC
Это краткая сводка характерных для AVR аспектов использования инструментов GNU. Обычно общая документация этих инструментов довольно велика. В этом разделе руководства детально раскрыты опции командной строки.
Опции C-компилятора avr-gcc
Опции для платформы AVR
Следующие характерные для платформы опции распознаются препроцессором C-компилятора. В дополнение к макросам препроцессора, показанным в таблице ниже, препроцессор будет определять макросы __AVR
и __AVR__
(в значение 1), когда компилирует для AVR. Макрос AVR будет также определятся, когда используется стандарт уровней gnu89 (по умолчанию) и gnu99, но не c89 и c99.
- -mmcu=архитектура
- Компилирует код для архитектуры.
В настоящее время известны следующие архитектуры:
Архитектура | Макросы | Описание |
---|---|---|
avr1 | __AVR_ARCH__=1 __AVR_ASM_ONLY__ __AVR_2_BYTE_PC__ [2] | “простое” ядро, поддерживает только ассемблер |
avr2 | __AVR_ARCH__=2 __AVR_2_BYTE_PC__ [2] | “классическое” ядро с размером программной области памяти до 8 кбайт |
avr25 [1] | __AVR_ARCH__=25 __AVR_HAVE_MOVW__ [1]__AVR_HAVE_LPMX__ [1]__AVR_2_BYTE_PC__ [2] | “классическое” ядро с инструкциями ‘MOVW ’ и ‘LPM Rx, Z[+] ’ и размером программной области памяти до 8 кбайт |
avr3 | __AVR_ARCH__=3 __AVR_MEGA__ [5]__AVR_HAVE_JMP_CALL__ [4]__AVR_2_BYTE_PC__ [2] | “классическое” ядро с размером программной области памяти от 16 до 64 кбайт |
avr31 | __AVR_ARCH__=31 __AVR_MEGA__ __AVR_HAVE_RAMPZ__ [4]__AVR_HAVE_ELPM__ [4]__AVR_2_BYTE_PC__ [2] | “классическое” ядро с размером программной области памяти 128 кбайт |
avr35 [3] | __AVR_ARCH__=35 __AVR_MEGA__ [5]__AVR_HAVE_JMP_CALL__ [4]__AVR_HAVE_MOVW__ [1]__AVR_HAVE_LPMX__ [1]__AVR_2_BYTE_PC__ [2] | “классическое” ядро с инструкциями ‘MOVW ’ и ‘LPM Rx, Z[+] ’ и размером программной области памяти от 16 до 64 кбайт |
avr4 | __AVR_ARCH__=4 __AVR_ENHANCED__ [5]__AVR_HAVE_MOVW__ [1]__AVR_HAVE_LPMX__ [1]__AVR_HAVE_MUL__ [1]__AVR_2_BYTE_PC__ [2] | “расширенное” ядро с размером программной области памяти до 8 кбайт |
avr5 | __AVR_ARCH__=5 __AVR_MEGA__ [5]__AVR_ENHANCED__ [5]__AVR_HAVE_JMP_CALL__ [4]__AVR_HAVE_MOVW__ [1]__AVR_HAVE_LPMX__ [1]__AVR_HAVE_MUL__ [1]__AVR_2_BYTE_PC__ [2] | “расширенное” ядро с размером программной области памяти от 16 до 64 кбайт |
avr51 | __AVR_ARCH__=51 __AVR_MEGA__ __AVR_ENHANCED__ __AVR_HAVE_MOVW__ [1]__AVR_HAVE_LPMX__ [1]__AVR_HAVE_MUL__ [1]__AVR_HAVE_RAMPZ__ [4]__AVR_HAVE_ELPM__ [4]__AVR_HAVE_ELPMX__ [4]__AVR_2_BYTE_PC__ [2] | “расширенное” ядро с размером программной области памяти 128 кбайт |
avr6 [2] | __AVR_ARCH__ =6__AVR_MEGA__ [5]__AVR_ENHANCED__ [5]__AVR_HAVE_JMP_CALL__ [4]__AVR_HAVE_MOVW__ [1]__AVR_HAVE_LPMX__ [1]__AVR_HAVE_MUL__ [1]__AVR_HAVE_RAMPZ__ [4]__AVR_HAVE_ELPM__ [4]__AVR_HAVE_ELPMX__ [4]__AVR_3_BYTE_PC__ [2] | “расширенное” ядро с размером программной области памяти 256 кбайт |
- [1] Начиная с GCC 4.2
- [2] Неофициальный патч для GCC 4.1
- [3] Начиная с GCC 4.2.3
- [4] Начиная с GCC 4.3
- [5] Устаревшее.
По умолчанию код генерируется для архитектуры avr2.
Обратите внимание, что, когда используется -mmcu=архитектура, а не -mmcu=тип МК, присоединяемый файл <avr/io.h> не сможет работать до тех пор, пока не сможет решить, описание какого устройства выбрать.
- -mmcu=тип МК
- Задает тип МК.
В настоящее время avr-gcc понимает следующие типы микроконтроллеров. Таблица сопоставляет их именам архитектур, передаваемых avr-gcc, и показывает обозначение препроцессора объявляемое опцией -mmcu.
Архитектура | Тип МК | Макрос |
---|---|---|
avr1 | at90s1200 | __AVR_AT90S1200__ |
avr1 | attiny11 | __AVR_ATtiny11__ |
avr1 | attiny12 | __AVR_ATtiny12__ |
avr1 | attiny15 | __AVR_ATtiny15__ |
avr1 | attiny28 | __AVR_ATtiny28__ |
avr2 | at90s2313 | __AVR_AT90S2313__ |
avr2 | at90s2323 | __AVR_AT90S2323__ |
avr2 | at90s2333 | __AVR_AT90S2333__ |
avr2 | at90s2343 | __AVR_AT90S2343__ |
avr2 | attiny22 | __AVR_ATtiny22__ |
avr2 | attiny26 | __AVR_ATtiny26__ |
avr2 | at90s4414 | __AVR_AT90S4414__ |
avr2 | at90s4433 | __AVR_AT90S4433__ |
avr2 | at90s4434 | __AVR_AT90S4434__ |
avr2 | at90s8515 | __AVR_AT90S8515__ |
avr2 | at90c8534 | __AVR_AT90C8534__ |
avr2 | at90s8535 | __AVR_AT90S8535__ |
avr2/avr25 [1] | at86rf401 | __AVR_AT86RF401__ |
avr2/avr25 [1] | ata6289 | __AVR_ATA6289__ |
avr2/avr25 [1] | attiny13 | __AVR_ATtiny13__ |
avr2/avr25 [1] | attiny13a | __AVR_ATtiny13A__ |
avr2/avr25 [1] | attiny2313 | __AVR_ATtiny2313__ |
avr2/avr25 [1] | attiny24 | __AVR_ATtiny24__ |
avr2/avr25 [1] | attiny25 | __AVR_ATtiny25__ |
avr2/avr25 [1] | attiny261 | __AVR_ATtiny261__ |
avr2/avr25 [1] | attiny43u | __AVR_ATtiny43U__ |
avr2/avr25 [1] | attiny44 | __AVR_ATtiny44__ |
avr2/avr25 [1] | attiny45 | __AVR_ATtiny45__ |
avr2/avr25 [1] | attiny461 | __AVR_ATtiny461__ |
avr2/avr25 [1] | attiny48 | __AVR_ATtiny48__ |
avr2/avr25 [1] | attiny84 | __AVR_ATtiny84__ |
avr2/avr25 [1] | attiny85 | __AVR_ATtiny85__ |
avr2/avr25 [1] | attiny861 | __AVR_ATtiny861__ |
avr2/avr25 [1] | attiny87 | __AVR_ATtiny87__ |
avr2/avr25 [1] | attiny88 | __AVR_ATtiny88__ |
avr3 | atmega603 | __AVR_ATmega603__ |
avr3 | at43usb355 | __AVR_AT43USB355__ |
avr3/avr31 [3] | atmega103 | __AVR_ATmega103__ |
avr3/avr31 [3] | at43usb320 | __AVR_AT43USB320__ |
avr3/avr35 [2] | at90usb82 | __AVR_AT90USB82__ |
avr3/avr35 [2] | at90usb162 | __AVR_AT90USB162__ |
avr3/avr35 [2] | attiny167 | __AVR_ATtiny167__ |
avr3 | at76c711 | __AVR_AT76C711__ |
avr4 | atmega48 | __AVR_ATmega48__ |
avr4 | atmega48p | __AVR_ATmega48P__ |
avr4 | atmega8 | __AVR_ATmega8__ |
avr4 | atmega8515 | __AVR_ATmega8515__ |
avr4 | atmega8535 | __AVR_ATmega8535__ |
avr4 | atmega88 | __AVR_ATmega88__ |
avr4 | atmega88p | __AVR_ATmega88P__ |
avr4 | atmega8hva | __AVR_ATmega8HVA__ |
avr4 | at90pwm1 | __AVR_AT90PWM1__ |
avr4 | at90pwm2 | __AVR_AT90PWM2__ |
avr4 | at90pwm2b | __AVR_AT90PWM2B__ |
avr4 | at90pwm3 | __AVR_AT90PWM3__ |
avr4 | at90pwm3b | __AVR_AT90PWM3B__ |
avr4 | at90pwm81 | __AVR_AT90PWM81__ |
avr5 | at90pwm216 | __AVR_AT90PWM216__ |
avr5 | at90pwm316 | __AVR_AT90PWM316__ |
avr5 | at90can32 | __AVR_AT90CAN32__ |
avr5 | at90can64 | __AVR_AT90CAN64__ |
avr5 | at90usb646 | __AVR_AT90USB646__ |
avr5 | at90usb647 | __AVR_AT90USB647__ |
avr5 | atmega16 | __AVR_ATmega16__ |
avr5 | atmega161 | __AVR_ATmega161__ |
avr5 | atmega162 | __AVR_ATmega162__ |
avr5 | atmega163 | __AVR_ATmega163__ |
avr5 | atmega164p | __AVR_ATmega164P__ |
avr5 | atmega165 | __AVR_ATmega165__ |
avr5 | atmega165p | __AVR_ATmega165P__ |
avr5 | atmega168 | __AVR_ATmega168__ |
avr5 | atmega168p | __AVR_ATmega168P__ |
avr5 | atmega169 | __AVR_ATmega169__ |
avr5 | atmega169p | __AVR_ATmega169P__ |
avr5 | atmega16hva | __AVR_ATmega16HVA__ |
avr5 | atmega16m1 | __AVR_ATmega16M1__ |
avr5 | atmega16u4 | __AVR_ATmega16U4__ |
avr5 | atmega32 | __AVR_ATmega32__ |
avr5 | atmega323 | __AVR_ATmega323__ |
avr5 | atmega324p | __AVR_ATmega324P__ |
avr5 | atmega325 | __AVR_ATmega325__ |
avr5 | atmega325p | __AVR_ATmega325P__ |
avr5 | atmega3250 | __AVR_ATmega3250__ |
avr5 | atmega3250p | __AVR_ATmega3250P__ |
avr5 | atmega328p | __AVR_ATmega328P__ |
avr5 | atmega329 | __AVR_ATmega329__ |
avr5 | atmega329p | __AVR_ATmega329P__ |
avr5 | atmega3290 | __AVR_ATmega3290__ |
avr5 | atmega3290p | __AVR_ATmega3290P__ |
avr5 | atmega32c1 | __AVR_ATmega32C1__ |
avr5 | atmega32hvb | __AVR_ATmega32HVB__ |
avr5 | atmega32m1 | __AVR_ATmega32M1__ |
avr5 | atmega32u4 | __AVR_ATmega32U4__ |
avr5 | atmega32u6 | __AVR_ATmega32U6__ |
avr5 | atmega406 | __AVR_ATmega406__ |
avr5 | atmega64 | __AVR_ATmega64__ |
avr5 | atmega640 | __AVR_ATmega640__ |
avr5 | atmega644 | __AVR_ATmega644__ |
avr5 | atmega644p | __AVR_ATmega644P__ |
avr5 | atmega645 | __AVR_ATmega645__ |
avr5 | atmega6450 | __AVR_ATmega6450__ |
avr5 | atmega649 | __AVR_ATmega649__ |
avr5 | atmega6490 | __AVR_ATmega6490__ |
avr5 | atmega64c1 | __AVR_ATmega64C1__ |
avr5 | atmega64m1 | __AVR_ATmega64M1__ |
avr5 | at94k | __AVR_AT94K__ |
avr5 | at90scr100 | __AVR_AT90SCR100__ |
avr5/avr51 [3] | atmega128 | __AVR_ATmega128__ |
avr5/avr51 [3] | atmega1280 | __AVR_ATmega1280__ |
avr5/avr51 [3] | atmega1281 | __AVR_ATmega1281__ |
avr5/avr51 [3] | atmega1284p | __AVR_ATmega1284P__ |
avr5/avr51 [3] | at90can128 | __AVR_AT90CAN128__ |
avr5/avr51 [3] | at90usb1286 | __AVR_AT90USB1286__ |
avr5/avr51 [3] | at90usb1287 | __AVR_AT90USB1287__ |
avr6 | atmega2560 | __AVR_ATmega2560__ |
avr6 | atmega2561 | __AVR_ATmega2561__ |
avrxmega2 | atxmega16a4 | __AVR_ATxmega16A4__ |
avrxmega2 | atxmega16d4 | __AVR_ATxmega16D4__ |
avrxmega2 | atxmega32d4 | __AVR_ATxmega32D4__ |
avrxmega3 | atxmega32a4 | __AVR_ATxmega32A4__ |
avrxmega4 | atxmega64a3 | __AVR_ATxmega64A3__ |
avrxmega5 | atxmega64a1 | __AVR_ATxmega64A1__ |
avrxmega6 | atxmega128a3 | __AVR_ATxmega128A3__ |
avrxmega6 | atxmega256a3 | __AVR_ATxmega256A3__ |
avrxmega6 | atxmega256a3b | __AVR_ATxmega256A3B__ |
avrxmega7 | atxmega128a1 | __AVR_ATxmega128A1__ |
- [1] Архитектура ‘avr25’, начиная с GCC 4.2
- [2] Архитектура ‘avr35’, начиная с GCC 4.2.3
- -morder1
-morder2 - Меняет порядок распределения регистров.
- по умолчанию: r24, r25, r18, r19, r20, r21, r22, r23, r30, r31, r26, r27, r28, r29, r17, r16, r15, r14, r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r0, r1
- порядок 1: r18, r19, r20, r21, r22, r23, r24, r25, r30, r31, r26, r27, r28, r29, r17, r16, r15, r14, r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r0, r1
- порядок 2: r25, r24, r23, r22, r21, r20, r19, r18, r30, r31, r26, r27, r28, r29, r17, r16, r15, r14, r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0
- -mint8
- Принимает int за 8-разрядное целое. Обратите внимание, что это на самом деле не поддерживается avr-libc и поэтому обычно не используется. По умолчанию используются 16-разрядные целые.
- -mno-interrupts
- Генерирует код, который изменяет указатель стека без отключения прерываний. Обычно состояние регистра статуса
SREG
сохраняется во временном регистре, прерывания отключаются на время изменения указателя стека, после чегоSREG
восстанавливается. Таким образом, данная опция уменьшает размер кода за счет генерации кода, несовместимого с аппаратными прерываниями.
Установка этой опции определяет макрос препроцессора__NO_INTERRUPTS__
в значение 1. - -mcall-prologues
- Использует подпрограммы пролога и эпилога функций. Для сложных функций, которые используют много регистров (которые нуждаются в сохранении/восстановлении при входе/выходе из функции), это уменьшает размер генерируемого кода за счёт незначительного увеличения времени выполнения.
- -mtiny-stack
- Изменение только восьми младших разрядов указателя стека.
- -mno-tablejump
- Не приветствуется, используйте вместо неё -fno-jump-tables.
- -mshort-calls
- Использование rjmp/rcall (в ограниченном диапазоне) в устройствах более 8 кбайт. Это всегда используется в случае работы с архитектурами avr2 и avr4 (меньше 8 кбайт или flash-память). В архитектурах avr3 и avr5 вызовы и переходы по умолчанию будут использовать инструкции
jmp/call
, которые могут охватить весь диапазон адресов, но которые требуют большей памяти программ и большего времени выполнения. - -mrtl
- Выводит внутренний результат компиляции вызова “
RTL
” в комментарии генерируемого ассемблерного кода. Используется для отладки avr-gcc. - -msize
- Выводит адрес, размер и относительные затраты для каждого операторав комментарии генерируемого ассемблерного кода. Используется для отладки avr-gcc.
- -mdeb
- Генерирует всю отладочную информацию для stderr.
Некоторые основные опции компилятора
Следующие основные опции компилятора могут быть интересными пользователям AVR.
- -On
- Уровень оптимизации.
Увеличение n означает увеличение оптимизации. Уровень оптимизации 0 означает, что оптимизации нет совсем (это значение по умолчанию, когда опция -O не выставлена). Специальная опция -Os похожа на -O2, но при этом будет пропускаться несколько шагов, увеличивающих размер кода.
Обратите внимание, что при -O3, gcc пытается сделать инлайновыми все “простые” функции. Для AVR это обычно очень ухудшает программу из-за увеличения размера кода. Поэтому вместе с оптимизацией -O3 включаются и другие опции, например, -frename-registers, которые лучше включать вручную.
Простая опция -O эквивалентна -O1.
Обратите также внимание, что отключение всех оптимизаций предотвращает при компиляции выдачу некоторых предупреждений, зависящих от шагов анализа кода, которые выполняются только при оптимизации (невыполняемый код, неиспользуемые переменные).
Смотрите также соответствующий раздел FAQ для получения желаемого отлаженного и оптимизированного кода.
- -Wa,опции ассемблера
-Wl,опции компоновщика - Передача перечисленных опций ассемблеру и компоновщику соответственно.
- -g
- Формирование отладочной информации, которая может быть использована avr-gdb.
- -ffreestanding
- Предполагает “автономную” среду согласно стандарту Си. Это отключает автоматически встроенные функции (хотя они всё же могут быть переданы присоединением
__builtin_
к реальному имени функции). Это также заставляет компилятор жаловаться, когдаmain()
объявляется с пустым возвращаемым типом, что вполне логично в микроконтролерной среде, где приложение не может обеспечить значимую возвращаемую величину этой среде (в большинстве случаев из main() всё равно никак не возвращается). Однако, это также выключает все оптимизаци, выполняемые компилятором, который предполагает, что функции известны под определенными именами, описанными в стандарте. Например, применяя функциюstrlen()
к строковой константе обычно заствляет компилятор сразу заменить её вызов фактической длиной строки, хотя с -ffreestanding это всегда будет вызыватьstrlen()
в реальном времени. - -funsigned-char
- Приводит тип
char
без каких-либо условий кunsigned char
. Без этой опции он по умолчаниюsigned char
. - -funsigned-bitfields
- Приводит тип
bitfield
без каких-либо условий кunsigned
. По умолчанию онsigned
. - -fshort-enums
- Назначает тип enum как набор байтов, так как он нужен для объявленного диапазона возможных значений. В частности, тип enum эквивалентен наименьшему целочисленному типу, который имеет достаточную размерность.
- -fpack-struct
- Упаковывает вместе все члены структуры без пустот.
- -fno-jump-tables
- Выключает формирование инструкций табличных переходов. По умолчанию таблицы переходов могут использоваться для оптимизации операторов
switch
. При выключении же вместо этого используется последовательность операторов сравнения. Таблица переходов обычно в среднем быстрее, но, в частности, для операторовswitch
, где большинство переходов обращаются к меткеdefault
, они излишне расточительны к flash-памяти.
ВНИМАНИЕ: Инструкции табличных переходов используют ассемблерную инструкцию LPM
для доступа к таблицам переходов. Всегда используйте переключатель -fno-jump-tables, если компилируете загрузчик для устройств с памятью программ более 64 килобайт.