Программирование AVR WSL: программирование AVR в виртуальной машине Linux Mon, December 09 2024  

Поделиться

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

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


WSL: программирование AVR в виртуальной машине Linux Печать
Добавил(а) microsin   

Здесь мы рассмотрим программирование микроконтроллеров AVR на примере популярной платки Arduino Nano. И будем это делать в виртуальной машине Linux, работающей в среде WSL [1]. Вы можете спросить: зачем такие заморочки, когда под Windows есть куча готовых удобных инструментов для программирования AVR и любых микроконтроллеров? Да, конечно, это так, но вероятно рано или поздно все-таки придется переехать на Linux, и поэтому есть некий смысл выделить время на изучение нового инструментария.

Установка WSL хорошо описана как на сайте Microsoft, так и на других ресурсах сети [1]. Однако для доступа из виртуальной машины WSL к последовательным портам tty есть некоторая тонкость.

Проблема в том, что WSL существует в двух версиях: WSL1 и WSL2, и команда wsl --install по умолчанию устанавливает WSL2. И эта версия WSL2 по какой-то непонятной причине не позволяет работать с последовательными портами. А как известно, платки Arduino программируются через последовательный порт. Поэтому необходимо установить WSL1 вместо WSL2.

[Установка WSL1]

Запустите PowerShell с правами администратора. Выполните следующие команды:

> wsl --set-default-version 1

Этой командой мы задаем по умолчанию устанавливать WSL1. Далее установите виртуальную машину Ubuntu следующей командой:

> wsl --install -d Ubuntu-20.04

Проверьте, что Ubuntu установлена именно под версией WSL1:

> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         1

Примечание: если у вас уже по какой-то причине установлена виртуальная машина под управлением WSL2, то её нужно сначала удалить командами wsl --shutdown и wsl --unregister имядистрибутива, например wsl --unregister Ubuntu-20.04.

>wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu          Running         2
  Ubuntu-20.04    Stopped         1
>wsl --unregister Ubuntu
>wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         1

[Подготовка среды разработки в виртуальной машине Linux]

Далее все шаги выполняются в командной строке установленной виртуальной машины Ubuntu, если не указано что-то иное (на одном из шагов нам придется перезапустить виртуальную машину командами PowerShell).

1. Обновите пакеты для нашей виртуальной Ubuntu:

$ sudo apt-get update
$ sudo apt-get dist-upgrade

Команда sudo apt-get dist-upgrade займет довольно много времени, и будут периодически выдаваться сообщения о необходимости перезагрузки системы. Поэтому после завершения этой команды надо перезагрузить wsl из командной строки PowerShell (с правами администратора).

Для этого сначала выйдите из виртуальной машины:

$ logout

После этого в командной строке PowerShell выполните команды:

> wsl --shutdown
> wsl

Эти команды перезапустят виртуальную машину.

2. Установите cu, это программа для подключения к последовательным портам. Её можно использовать как монитор последовательного порта.

$ sudo apt install cu

3. Теперь нужно установить необходимые для программирования утилиты [2].

$ sudo apt install make
$ sudo apt-get install gcc-avr avr-libc uisp avrdude
$ sudo apt install dos2unix

4. Подключите платку Arduino Nano к компьютеру через USB. Предположим, Windows обнаружила её как COM4:

DeviceManager COM4

Тогда этот COM-порт будет виден в WSL как устройство /dev/ttyS4.

Примечание: в WSL2 по какой-то причине нумерация несколько другая, это устройство будет видно как /dev/tty4. И, повторюсь, на момент написания статьи (август 2023 года) WSL2 не позволяла получить доступ к этим последовательным портам. Возможно когда-нибудь Microsoft это исправит.

[Как программировать]

$ mkdir myprojects
$ sudo mount -t drvfs M:/work myprojects/

Примечание: команда sudo mount -t drvfs M:/work myprojects/ необязательна. Она выполнена для того, чтобы не загромождать системный диск C:. Этой командой произведено монтирование папки m:\work на другом диске, где у меня размещены проекты, с которыми я работаю.

$ mkdir helloworld
$ cd helloworld
$ nano main.c

Введите в редакторе nano текст программы, мигающей светодиодом, из статьи [2].

Примечание: WSL отлично работает с буфером обмена. Поэтому можно просто скопировать текст из статьи [2], и затем вставить его в nano путем нажатия Ctrl+V.

//Примечание: чтобы подпрограммы задержки давали корректные значения,
// нужно правильно установить значение макропеременной 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 мс
   }
}

$ nano Makefile

Введите следующий текст Makefile (опять-таки это Makefile из [2]):

Важный момент для запуска 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 

Теперь у нас в рабочем каталоге ~/myprojects/helloworld два файла: Makefile и main.c.

$ ls
Makefile  main.c

Команда make help выведет подсказку о том, как компилировать:

$ make help
Usage: make                create main.hex
       make help           show help
       make clean          remove redundant data
       make disasm         disasm main
       make flash          upload main.hex into flash
Current values:
       TARGET=main
       DEVICE=atmega328p
       CLOCK=16000000UL
       LFUSE=
       HFUSE=

[Прошивка микроконтроллера]

Если ваша платка обнаружилась как COM4, то к ней надо будет обращаться через имя /dev/ttyS4. Для начала надо разрешить права доступа к устройству /dev/ttyS4:

$ sudo chmod 666 /dev/ttyS4

Программирование:

$ avrdude -c arduino -P /dev/ttyS4 -p m328p -b 57600 -U flash:w:main.hex:i

Или:

$ make flash

[Ссылки]

1. Запуск Linux на Windows помощью WSL.
2. Программирование AVR в Linux.
3. kbatman37 / AVR-Hello-World site:github.com.
4Запуск Linux на Windows помощью WSL.

 

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


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

Top of Page