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.

АрхитектураТип МКМакрос
avr1at90s1200__AVR_AT90S1200__
avr1attiny11__AVR_ATtiny11__
avr1attiny12__AVR_ATtiny12__
avr1attiny15__AVR_ATtiny15__
avr1attiny28__AVR_ATtiny28__
avr2at90s2313__AVR_AT90S2313__
avr2at90s2323__AVR_AT90S2323__
avr2at90s2333__AVR_AT90S2333__
avr2at90s2343__AVR_AT90S2343__
avr2attiny22__AVR_ATtiny22__
avr2attiny26__AVR_ATtiny26__
avr2at90s4414__AVR_AT90S4414__
avr2at90s4433__AVR_AT90S4433__
avr2at90s4434__AVR_AT90S4434__
avr2at90s8515__AVR_AT90S8515__
avr2at90c8534__AVR_AT90C8534__
avr2at90s8535__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__
avr3atmega603__AVR_ATmega603__
avr3at43usb355__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__
avr3at76c711__AVR_AT76C711__
avr4atmega48__AVR_ATmega48__
avr4atmega48p__AVR_ATmega48P__
avr4atmega8__AVR_ATmega8__
avr4atmega8515__AVR_ATmega8515__
avr4atmega8535__AVR_ATmega8535__
avr4atmega88__AVR_ATmega88__
avr4atmega88p__AVR_ATmega88P__
avr4atmega8hva__AVR_ATmega8HVA__
avr4at90pwm1__AVR_AT90PWM1__
avr4at90pwm2__AVR_AT90PWM2__
avr4at90pwm2b__AVR_AT90PWM2B__
avr4at90pwm3__AVR_AT90PWM3__
avr4at90pwm3b__AVR_AT90PWM3B__
avr4at90pwm81__AVR_AT90PWM81__
avr5at90pwm216__AVR_AT90PWM216__
avr5at90pwm316__AVR_AT90PWM316__
avr5at90can32__AVR_AT90CAN32__
avr5at90can64__AVR_AT90CAN64__
avr5at90usb646__AVR_AT90USB646__
avr5at90usb647__AVR_AT90USB647__
avr5atmega16__AVR_ATmega16__
avr5atmega161__AVR_ATmega161__
avr5atmega162__AVR_ATmega162__
avr5atmega163__AVR_ATmega163__
avr5atmega164p__AVR_ATmega164P__
avr5atmega165__AVR_ATmega165__
avr5atmega165p__AVR_ATmega165P__
avr5atmega168__AVR_ATmega168__
avr5atmega168p__AVR_ATmega168P__
avr5atmega169__AVR_ATmega169__
avr5atmega169p__AVR_ATmega169P__
avr5atmega16hva__AVR_ATmega16HVA__
avr5atmega16m1__AVR_ATmega16M1__
avr5atmega16u4__AVR_ATmega16U4__
avr5atmega32__AVR_ATmega32__
avr5atmega323__AVR_ATmega323__
avr5atmega324p__AVR_ATmega324P__
avr5atmega325__AVR_ATmega325__
avr5atmega325p__AVR_ATmega325P__
avr5atmega3250__AVR_ATmega3250__
avr5atmega3250p__AVR_ATmega3250P__
avr5atmega328p__AVR_ATmega328P__
avr5atmega329__AVR_ATmega329__
avr5atmega329p__AVR_ATmega329P__
avr5atmega3290__AVR_ATmega3290__
avr5atmega3290p__AVR_ATmega3290P__
avr5atmega32c1__AVR_ATmega32C1__
avr5atmega32hvb__AVR_ATmega32HVB__
avr5atmega32m1__AVR_ATmega32M1__
avr5atmega32u4__AVR_ATmega32U4__
avr5atmega32u6__AVR_ATmega32U6__
avr5atmega406__AVR_ATmega406__
avr5atmega64__AVR_ATmega64__
avr5atmega640__AVR_ATmega640__
avr5atmega644__AVR_ATmega644__
avr5atmega644p__AVR_ATmega644P__
avr5atmega645__AVR_ATmega645__
avr5atmega6450__AVR_ATmega6450__
avr5atmega649__AVR_ATmega649__
avr5atmega6490__AVR_ATmega6490__
avr5atmega64c1__AVR_ATmega64C1__
avr5atmega64m1__AVR_ATmega64M1__
avr5at94k__AVR_AT94K__
avr5at90scr100__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__
avr6atmega2560__AVR_ATmega2560__
avr6atmega2561__AVR_ATmega2561__
avrxmega2atxmega16a4__AVR_ATxmega16A4__
avrxmega2atxmega16d4__AVR_ATxmega16D4__
avrxmega2atxmega32d4__AVR_ATxmega32D4__
avrxmega3atxmega32a4__AVR_ATxmega32A4__
avrxmega4atxmega64a3__AVR_ATxmega64A3__
avrxmega5atxmega64a1__AVR_ATxmega64A1__
avrxmega6atxmega128a3__AVR_ATxmega128A3__
avrxmega6atxmega256a3__AVR_ATxmega256A3__
avrxmega6atxmega256a3b__AVR_ATxmega256A3B__
avrxmega7atxmega128a1__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 килобайт.

Перевод раздела Using the GNU tools из AVR Libc v.1.6.6

Дополнительные источники по теме:

  • Гриффитс Артур. GCC. Настольная книга пользователей, программистов и системных администраторов. 2004

Теги

AVRavr-gccMCUWinAVRКомпиляторМикроконтроллер