Программирование AVR в Linux |
![]() |
Добавил(а) microsin |
Установка компилятора GCC, библиотек и утилит программирования: $ sudo apt-get install gcc-avr avr-libc uisp avrdude
[Как пользоваться AVRDUDE] Программатор USBasp. Чтобы запрограммировать AVR с помощью программатора USBasp, используйте вместе с утилитой avrdude имя программатора usbasp (список поддерживаемых программаторов можно получить командой (avrdude -c ?). Пример прошивки ATmega328P файлом blink.hex: $ avrdude -c usbasp -p m328p -U flash:w:blink.hex
Arduino. Платки Arduino прошиваются с помощью подключения через виртуальный последовательный порт (обычно реализован на отдельном чипе FT232RL или CH340). Пример прошивки платки Arduino Nano тем же файлом blink.hex: $ avrdude -c arduino -P /dev/ttyUSB0 -p m328p -b 57600 -U flash:w:blink.hex
Имя виртуального последовательного порта для опции -P можно узнать командой $ sudo tail -f /var/log/kern.log. Если вы встретились с ошибкой "programmer is not responding", попробуйте подобрать скорость соединения для опции -b. Чаще всего используются скорости 19200, 57600 и 115200. [eXtreme Burner] Для программатора USBasp существует отличная утилита с графическим интерфейсом - eXtreme Burner, которая работает на Windows и Linux [3, 4]. [Первая программа в Arduino IDE] Программирование в среде разработки Arduino IDE происходит одинаково в Windows, Linux и Mac OS. Установка в Linux: $ sudo apt install arduino
После этого можно запускать Arduino IDE командой arduino в строке терминала: $ arduino
1. Перейдите по ссылке [1], кликните на ссылку Linux AppImage 64 bits (X86-64). Скачается файл arduino-ide_2.1.1_Linux_64bit.AppImage (цифры 2.1.1 в имени файла могут поменяться в зависимости от версии). 2. Перепишите этот файл в каталог, где у вас находятся все загруженные программы. Например в папку ~/install. Установите у него атрибут, разрешающий выполнение: $ chmod +x ~/install/arduino-ide_2.1.1_Linux_64bit.AppImage
После этого Arduino IDE можно будет запускать простым кликом на файл arduino-ide_2.1.1_Linux_64bit.AppImage. Для удобства можно создать для arduino-ide_2.1.1_Linux_64bit.AppImage символическую ссылку, и поместите её в каталог, где система может её запустить без необходимости указания прямого пути, такие каталоги можно узнать командой printenv PATH. Например, создайте символическую ссылку в каталоге /home/имядомена/имяпользователя/.local/bin, и назовите её ardide. Тогда можно будет запускать Arduino IDE из любой командной строки, просто введя команду ardide. Hello World (blink). Чтобы понять, как работает система компиляции и программирования, можно начать с простейшей программы мигания светодиодом (Blink). Запустите Arduino IDE, войдите в меню Файл -> Примеры -> 01.Basics -> Blink. Загрузится скетч: Проверьте настройки выбранной платы и порта подключения, это делается через меню Сервис. Например, если у вас платка Arduino Nano с микроконтроллером ATmega328P, то выберите Сервис -> Плата -> Arduino Nano w/ATmega328. Если у вас подключено несколько последовательных портов, то порт подключения можно выбрать в меню Сервис -> Последовательный порт. Теперь все просто. Для компиляции и загрузки кликните на тулбаре в круглую кнопку со стрелкой (Загрузить). Программа скомпилируется и загрузится. Светодиод на плате начнет зажигаться и гаснуть с периодом 2 секунды. Диагностика проблем. Если что-то пошло не так, то полезно вывести диагностику. Для этого выберите в меню Файл -> Настройки, и поставьте галочки "Показывать подробный вывод при:". [Чистый GCC] Установка: $ sudo apt update
$ sudo apt install gcc-avr
Пример использования по шагам показан ниже. Шаг 1. Создание модуля исходного кода main.c: $ mkdir blink
$ cd blink
$ touch main.c
$ gedit main.c
Вставьте в файл main.c такой текст: //Примечание: чтобы подпрограммы задержки давали корректные значения,
// нужно правильно установить значение макропеременной F_CPU
// в соответствие с используемой тактовой частотой микроконтроллера.
//Например так:
#ifndef F_CPU
#define F_CPU 16000000UL // тактовая частота 16 МГц #endif
//Подключение заголовков, в которых определены порты микроконтроллера,
// и имя подпрограммы задержки:
#include < avr/io.h>
#include < util/delay.h>
//Объявление имени LED для ножки порта, куда подключен светодиод.
//На разных макетных платах светодиод подключен к разным ножкам,
// поэтому раскомментируйте одно из определений ниже в зависимости
// от используемой макетной платы.
//#define LED PB0 //Для платы AVR-USB-MEGA16.
#define LED PB5 //Для плат Arduino Uno, Arduino Nano и metaboard. //#define LED PB7 //Для платы Arduino MEGA 2560.
// Основная функция, где находится главный цикл программы.
int main(void) { //До начала главного цикла всегда делаются предварительные настройки. DDRB = (1 << LED); // настройка порта LED как выхода. // Эквивалентно записи 0b00100000 в регистр DDRB. //Главный бесконечный цикл программы. while(1) { PORTB |= (1 << LED); // зажечь светодиод _delay_ms (5); // задержка на 5 мс PORTB &= ~(1 << LED); // погасить светодиод _delay_ms (50); // задержка на 50 мс } } Шаг 2, компиляция. Для компиляции под ATmega328P (установлен на Arduino Nano) выполните команды: $ avr-gcc -Os -mmcu=atmega328p -c -o main.o main.c
$ avr-gcc -w -mmcu=atmega328p main.o -o main.elf
Шаг 3, получение двоичного кода. Для преобразования файла в формат Intel HEX выполните команду: $ avr-objcopy -O ihex main.elf main.hex
Для вывода информации по скомпилированной прошивке выполните команду: $ avr-size --format=avr --mcu=atmega328p main.elf
Прошивка. Для записи в память микроконтроллера скомпилированной программы выполните команду: $ avrdude -c arduino -P /dev/ttyUSB0 -p m328p -b 57600 -U flash:w:$1
[clean.sh] Этот скрипт делает полную очистку, т. е. удаляет выходные файлы *.elf, *.hex, *.o. #!/bin/bash
rm *.elf *.hex *.o Пример запуска: $ ./clean.sh
[compile.sh] Шаги 2 и 3 можно выполнить с помощью скрипта: #!/bin/bash
if [ -z "$1" ]; then echo "Usage: $0 main_source_file (without *.c extension)" exit fi
./clean.sh avr-gcc -Os -mmcu=atmega328p -c -o $1.o $1.c avr-gcc -w -mmcu=atmega328p $1.o -o $1.elf avr-size --format=avr --mcu=atmega328p $1.elf avr-objcopy -O ihex $1.elf $1.hex Пример запуска: $ ./compile.sh main
[flash.sh] Прошить ATmega328P на плате Arduino Nano можно с помощью следующего скрипта: #!/bin/bash
if [ -z "$1" ]; then echo "Usage: $0 hex_file" exit fi
avrdude -c arduino -P /dev/ttyUSB0 -p m328p -b 57600 -U flash:w:$1
Пример запуска: $ ./flash.sh main
Создайте следующий файл с именем Makefile в корневом каталоге проекта (где находится файл main.c). Важный момент для запуска make: в строках после целей "%.o:", "clean:", "help:", "flash:" и "disasm": символы пробелов нужно заменить на табуляцию. Ниже в тексте символы табуляции показаны символом стрелочки →. MCU = atmega328p F_CPU = 16000000UL OPTIMIZATION = s TARGET = main SRC = $(wildcard *.S) $(wildcard *.c) COMPILER = avr-gcc INC=-I. #COMX=COM4
#COMX=/dev/ttyUSB0
COMX=/dev/ttyS4 CFLAGS = -c -gdwarf-2 -g2 -mmcu=$(MCU) -fshort-enums -fno-inline-small-functions -fpack-struct -Wall \ -fno-strict-aliasing -funsigned-char -funsigned-bitfields -ffunction-sections $(INC) \ -DF_CPU=$(F_CPU) -mrelax -fno-jump-tables -x c -O$(OPTIMIZATION) -std=gnu99 -Wstrict-prototypes \ -MMD -MP #LDFLAGS = -Wl,-u,vfprintf -lprintf_flt
#LDFLAGS = -lm -Wl,-Map=main.map,--cref -Wl,--gc-sections -Wl,--relax -mmcu=$(MCU) \
# -Wl,-u,vfscanf -lscanf_flt -lm -Wl,-u,vfprintf -lprintf_flt
LDFLAGS = -mmcu=$(MCU) AVRDUDE = avrdude -c arduino -P $(COMX) -p m328p -b 57600 all: $(TARGET).elf OBJECTS = $(patsubst %.c, %.o, $(SRC)) HEADERS = $(wildcard *.h) %.o: %.c $(HEADERS) →$(COMPILER) $(CFLAGS) $< -o $@ $(TARGET).elf: $(OBJECTS) →$(COMPILER) $(OBJECTS) -w -mmcu=$(MCU) -o $@ →avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $(TARGET).elf $(TARGET).hex →avr-objcopy -I ihex -O binary $(TARGET).hex $(TARGET).bin #avr-size main.bin →avr-size --mcu=$(MCU) --format=avr $(TARGET).elf clean: →-rm -f *.o *.d *.bin *.hex *.map *.elf help: →@echo "Usage: make create main.hex" →@echo " make help show help" →@echo " make clean remove redundant data" →@echo " make disasm disasm main" →@echo " make flash upload main.hex into flash" →@echo "Current values:" →@echo " TARGET=${TARGET}" →@echo " DEVICE=${MCU}" →@echo " CLOCK=${F_CPU}" →@echo " LFUSE=${LFUSE}" →@echo " HFUSE=${HFUSE}" flash: $(TARGET).elf →$(AVRDUDE) -U flash:w:main.hex:i disasm:$(TARGET).elf →avr-objdump -d $(TARGET).elf После этого используйте команды: make Генерация двоичного файла программы (make.hex). Создайте в текстовом редакторе следующий файл SConstruct, и поместите его в корень проекта (где находится файл main.c): env = Environment() mcu = 'atmega328p' Target = 'main' Avrdude = 'avrdude -c arduino -P /dev/ttyUSB0 -b 57600 -p m328p -u' AvrObjcopy = 'avr-objcopy -j .text -j .data -O ihex' # Уровень оптимизации, может быть [0, 1, 2, 3, s]. opt = "s" env['CC'] = 'avr-gcc -mmcu='+mcu+' -O'+opt env.Append(CCFLAGS = "-Wall") def MakeExec(): # Генерация HEX-файла: env.Command(Target+".hex", Target+".elf", AvrObjcopy+' $SOURCE $TARGET') # Показать расход памяти: env.Command(None, Target+".hex", "avr-size $SOURCE") def FlashExec(): # Прошивка микроконтроллера: env.Command(None, Target+".hex", Avrdude+' -U flash:w:$SOURCE') if len(COMMAND_LINE_TARGETS): if COMMAND_LINE_TARGETS[0] == '-p': MakeExec() FlashExec() else:
MakeExec()
После этого для компиляции, очистки и программирования используйте команды: # Компиляция проекта (генерация файлов main.elf и main.hex):
$ scons
# Очистка проекта:
$ scons -c
# Запрограммировать двоичный код в память микроконтроллера:
$ scons -- -p
[Ссылки] 1. Arduino IDE download. |