Программирование AVR Программирование AVR в Linux Sun, October 06 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Программирование 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].

eXtreme Burner atmega328

[Первая программа в Arduino IDE]

Программирование в среде разработки Arduino IDE происходит одинаково в Windows, Linux и Mac OS. Установка в Linux:

$ sudo apt install arduino

После этого можно запускать Arduino IDE командой arduino в строке терминала:

$ arduino

Ubuntu Arduino IDE first start

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. Загрузится скетч:

Ubuntu Arduino IDE Blink

Проверьте настройки выбранной платы и порта подключения, это делается через меню Сервис. Например, если у вас платка Arduino Nano с микроконтроллером ATmega328P, то выберите Сервис -> Плата -> Arduino Nano w/ATmega328. Если у вас подключено несколько последовательных портов, то порт подключения можно выбрать в меню Сервис -> Последовательный порт.

Теперь все просто. Для компиляции и загрузки кликните на тулбаре в круглую кнопку со стрелкой (Загрузить).

Ubuntu Arduino IDE Blink compile and load

Программа скомпилируется и загрузится. Светодиод на плате начнет зажигаться и гаснуть с периодом 2 секунды.

Диагностика проблем. Если что-то пошло не так, то полезно вывести диагностику. Для этого выберите в меню Файл -> Настройки, и поставьте галочки "Показывать подробный вывод при:".

Ubuntu Arduino IDE show verbose log

[Чистый 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).
make help Подсказка по командам.
make clean Полная очистка (удаление временных файлов).
make disasm Дизассемблирование двоичного кода.
make flash Запрограммировать двоичный код в память микроконтроллера.

Создайте в текстовом редакторе следующий файл 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():
    # Генерация ELF-файла:
    env.Program(Target+'.elf', [Target+'.c'])

    # Генерация 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.
2. Running AVRDUDE site:ladyada.net.
3. GUI Software for USBasp based USB AVR Programmers site:extremeelectronics.co.in.
4Утилиты для программатора USBasp с графическим интерфейсом.
5. AVR Programming in Linux site:swharden.com.
6. SCons: руководство пользователя, быстрый старт.
7. metala / avr-gcc-scons-skel site:github.com.
7. Настройка VSCode для программирования AVR в Linux site:habr.com.

 

Добавить комментарий


Защитный код
Обновить

Top of Page