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 килобайт.

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

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

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

Теги

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