ГлавнаяСтатьиЭлектроника → Программирование AVR в Linux

Программирование AVR в Linux

25 апреля 2013 года
Ключевые слова: программатор , AVR , Linux

Введение

Не секрет, что большая часть инженерного софта является коммерческой и работает исключительно в операционной системе Windows. Тем не менее и в Linux есть неплохие свободные программы, решающие многие практические задачи. В этой статье дан обзор технологии разработки программ для микроконтроллеров AVR при помощи свободного ПО, имеющегося в ОС ALT Linux.

Готовим софт.

Установим необходимые программы, набрав в консоли:
su -
password:
apt-get install avr-gcc avr-libc avr-binutils avrdude

Первые три программы это компилятор GCC для AVR с библиотеками, а четвертая - утилита программирования. Надо отметить, что в старых дистрибутивах ALT Linux (4-ая и 5-ая платформа) в avr-binutils была ошибка (компилятор не находил пути к заголовочным файлам). В 6-м Альте начиная с версии avr-binutils-2.21 эта ошибка исправлена [1]. Для проверки создадим в домашней папке текстовый файл main.c следующего содержания:

#include <avr/io.h>
int main(void)
{   DDRD|=(1<<7); // PD7 как выход
   PORTD|=(1<<7); // и установим на нем лог 1
   return 0;
}
 

Пробуем скомпилировать его под микроконтроллер ATMEGA16 набрав в консоли от имени пользователя:
$ avr-gcc -mmcu=atmega16 -Os -o main.o main.c
$ avr-objcopy -O ihex main.o main.hex

Должны появится два файла: объектный main.o и файл прошивки main.hex.

Программатор и отладочная плата.

Чтобы залить прошивку в микроконтроллер Вам понадобится программатор. Лично я пользуюсь программатором для COM порта . Но можно собрать и USB программатор. Наиболее прост и дешев USBASP [2] , однако его придется где-то запрограммировать, а чтобы он работал устойчиво нужно после 1 контакта разъема USB поставить два диода, которые понизят напряжение питания микроконтроллера до 3,8 В.

Для прототипирования схем удобно воспользоваться платой Pinboard. Помимо разной полезной периферии там имеется переходник USB/RS232 и бутлоадер от Мартина Томаса позволяющие загружать программы прямо по USB. У меня тоже есть такая плата, поэтому вкратце опишу ее запуск [3]. В консоли набираем команду:

$ avrdude -p m16 -c avr109 -P /dev/ttyUSB0 -b 19200

Затем жмем кнопку сброса на плате и сразу же вводим эту команду. Если все в порядке плата ответит:

Connecting to programmer:
Found programmer: Id = "AVRBOOT"; type = S
Software Version = 0.8; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x75
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9403
avrdude done. Thank you.

Теперь можно изменить команду:
$ avrdude -p m16 -c avr109 -P /dev/ttyUSB0 -b 19200 -U flash:w:main.hex

и прошить в плату нашу тестовую программу. Ничего особенного не произойдет, лишь загорится зеленый светодиод подключенный к ножке PD7

Конечно, пользоваться командной строкой не всегда удобно. Легче применить графическую оболочку AVRFuse. В ее настройках на вкладке Program выбираем Device Atmega16, в списке Programmer находим avr109, а на вкладке Settings пишем Port location /dev/ttyUSB0 и Baudrate 19200 Далее на вкладке Program выбираем Input file и наш файл с прошивкой, затем жмем кнопку сброса на плате, и сразу же кнопку Program.

IDE для программирования на Си.

К сожалению, в Linux нет программ, аналогичных по функциональности IDE Avr Studio. Существовал способ [4] позволяющий запустить ее под wine, но с тех пор скрипт winetricks несколько раз поменялся, часть библиотек была перемещена или переименована и, в общем, все тут довольно сложно. Есть avr-плагины для Eclipce и CodeBlock, но настройка их трудоемка, а особых удобств в отладке нету. Остается воспользоваться IDE KontrollerLab. Программа довольно аскетичная, но необходимый минимум функционала все же имеет.

Устанавливаем ее:
su -
password:
apt-get install kontrollerlab

Запускаем:
$ kontrollerlab

Сразу же закроем мешающее окошко терминала. Далее в главном меню Project выберем New Project, дадим ему имя и откроем. Следом File/New/C Source, присвоим имя исходнику. Переходим к свойствам проекта. Project/Configure project на вкладке Common выбираем настройки процессора CPU: Atmega16, clock 16 000 000. На вкладке Compiler ставим галку напротив -g: Produce debugging information. Чтобы отладка работала выберем Optimization level 0 (без оптимизации) и сохраним эти настройки как исходные Set as default.
После отладки потребуется сменить уровень оптимизации на s (оптимизация по размеру) и повторно скомпилировать исходник.

Скопируем в исходник наш тестовый файл main.c и скомпилируем его нажав Rebuild all. Для отладки выберем в главном меню Debug/PC only debugging затем Enable и Restart. Жмем кнопочку Step into и шагаем по строкам программы. Справа в окошке memory view показано содержимое ячеек ОЗУ и регистров. В списке выбираем нужный регистр, например DDRD, и смотрим как он меняется. Окошко можно убрать или восстановить в меню View/Show memory view.

А вот значения именованных Си переменных посмотреть нельзя, да еще надо поискать, в какие ячейки памяти забросил их компилятор. Но можно определить вспомогательную регистровую переменную и копировать байты нужной переменной в нее. Для регистровых переменных разрешено брать регистры r2-r7 [5]. Пример:

#include <avr/io.h>
#define lo8(x) ((x)& 0xFF)
#define hi8(x) ((x)>>8)
register unsigned char l asm("r3"); 
register unsigned char h asm("r4");
 
int main(void)
{
unsigned int test;
test=0x110; l=lo8(test); h=hi8(test);
DDRD|=1<<7;
PORTD|=1<<7;
PORTB=test;
test=0x20; l=lo8(test); h=hi8(test);
return 0;
 }
 

Осталось настроить программирование. Идем в Project/Configure programmer. На вкладке Choose programmer выбираем галку Avrdude. Далее на вкладке Avrdude настроим наш программатор. Для Pinboard выберем Baud  = 19200, Specify programmer type = Atmel AppNote AVR109 Boot Loader и Specify connection port Serial port  = /dev/ttyUSB0
Далее все просто, жмем сброс на плате и следом Upload (круглую синюю кнопку со стрелкой вверх) .

Терминальная программа.

Чаще всего микроконтроллер и компьютер связываются по протоколу UART. Соответственно, понадобится преобразователь RS232/UART или USB/UART на FT232RL и терминальная утилита. В KontrollerLab она имеется (см. пункт меню View/Show serial terminal), но я предпочитаю программу Cutecom от Александра Нуендорфа. Ставим ее как обычно:

#  apt-get install cutecom

Программа может посылать и принимать текстовые символы, строки и 16-ричные HEX числа и сохранять информацию в log файл, но работает лишь с первыми 4-мя COM портами   /dev/ttyS0 .. /dev/ttyS3 .
Если в компьютере нет COM порта и используется переходник USB/UART, то он опознается в Linux как устройство /dev/ttyUSB0.
Чтобы сделать его виртуальным COM портом ttyS2 надо от рута скомандовать [6]:

rm    /dev/ttyS2
ln   -s  /dev/ttyUSB0   /dev/ttyS2


И на время текущего сеанса система будет видеть USB устройство как виртуальный COM порт.
Чтобы не вводить каждый раз эти команды можно добавить их в скрипт автозапуска rc.local. Если его не существует, то создадим его с правами 755:

# touch   /etc/rc.d/rc.local
# chmod   755   /etc/rc.d/rc.local

И напишем в нем (не забыв добавить в конце файла пустую строку):

#!/bin/sh
rm /dev/ttyS2
ln -s  /dev/ttyUSB0  /dev/ttyS2
exit 0
 

Ассемблер.

Для программирования AVR обычно используют стандартный ассемблер Atmel и, гораздо реже, ассемблер avr-gcc. Последний отличается запутанным синтаксисом, но его приходится использовать для ассемблерных вставок в Си код [7,8].
Среди свободных ассемблеров наиболее близок к стандартному проект Avra, подробнее см [9]. Его установка в Alt Linux p6 обычная:

# apt-get install avra

Еще надо добавить файлы макроопределений (они находятся в архиве) скопировав содержимое папки Asm1 в каталог /usr/share/avra
У Atmel есть два варианта ассемблера. Хотя hex файлы будут безошибочно компилироваться для обоих вариантов, лучше использовать первый, иначе Avra засыплет предупреждениями "PRAGMA directive currently ignored".

К сожалению, программной отладки в Avra нет, поэтому придется использовать ретро-технологию — текстовый редактор Geany + железный контроль (мигание светодиодами, посылка контрольных байт по UART).
Настройка Geany для работы с Avra не сложная [10]. Сначала сделаем подсветку кода. Для этого скопируем в домашнюю папку в скрытую директорию ~/.config/geany/filedefs файл filetypes.asm с этой страницы. Затем в Geany в меню Сборка/Установить команды сборки в пункте Команды для языка: Файл Assembler в графе Скомпилировать пишем команду avra "%f"

Далее создаем файл test.asm со следующим содержанием:

Открыть test.asm:
.includepath "/usr/share/avra/" ; указали папку с инклудами
.include "m16def.inc" ; присоединили описание микроконтроллера Atmega16
.list ; включаем листинг
 
.def temp=R16 ; определим временный регистр
 
.cseg ; выбираем сегмент программного кода
.org 0 ; установили нулевой адрес
 
ldi temp, low(RAMEND) ; установим вершину стека
out SPL, temp
ldi temp, high(RAMEND)
out SPH, temp
 
ldi temp, (1<<7)
out DDRD, temp ; PD7 на вывод
out PORTD,temp ; зажигаем светодиод
 
main: ; и крутимся в цикле 
   rjmp main

И компилируем его нажав кнопку Скомпилировать текущий файл (на рисунке отмечена красной стрелкой).



Geany может не только компилировать, но и записывать прошивку. Для этого в меню Сборка/Установить команды сборки в пункте Команды для языка: Файл Assembler жмем кнопку после цифры 2 и в появившемся окошке вводим _Сборка, а в поле Команда вводим команду прошивки.
Для Pinboard она выглядит так: avrdude "%f" -p m16 -c avr109 -P /dev/ttyUSB0 -b 19200 -U flash:w:%e.hex
В ней %f и %e - спецификаторы Geany, %f подставляет подставляет полное имя ассемблерного файла, а %e его имя без расширения. Для прошивки жмем кнопку Собрать текущий файл.

Отладка программ на ассемблере.

Как уже говорилось применяем ретро-технологию; текстовый редактор + посылка контрольных байт по uart. Подключим микроконтроллер к переходнику rs232/uart или usb/uart и поместим в конце отлаживаемого кода две процедуры: uart_init (инициализация uart) и uart_snt (передача байта). Чтобы посмотреть значение какого-нибудь регистра (обозначим его псевдонимом xreg) пишем команды:

mov temp, xreg; или in temp, xreg
rcall uart_snt

Вот пример отладочного кода (взято у Ревича и Ди Хальта ):

Смотреть код
; Пример посылки отладочных байтов по UART
.includepath "/usr/share/avra/" 
.include "m16def.inc"  ; тип процессора Atmega16
.list 
.def temp=R16
.def char=R17 
.cseg 
.org 0 
	ldi temp, low(RAMEND) ; установим вершину стека
	out SPL, temp
	ldi temp, high(RAMEND)
	out SPH, temp
 
	rcall uart_init ; настраиваем uart
	ldi char, 'A'   ; поместим ASCII код англ буквы A
 
main:                ; Основной цикл	
	mov temp, char   ; буква A
	rcall uart_snt   ; вывод
 
	ldi temp, 0x0d;  ; ASCII код конца строки
	rcall uart_snt   ; вывод	
	rjmp main
 
;**** Настройка UART *************************
uart_init:
.equ XTAL=16000000 ; Частота кварца Гц
.equ b_rate=9600   ; Скорость бит/с
.equ b_div=XTAL/(16*b_rate-1); Коэффициент деления для UART
 
	ldi temp,low(b_div) ; настройка скорости
	out UBRRL, temp
	ldi temp,high(b_div)
	out UBRRH, temp
 
	ldi temp, 0         ; обнуление UCSRA
	out UCSRA, temp
 
	ldi temp, (1<<TXEN)|(0<<RXEN)|(0<<TXCIE)|(0<<RXCIE)
	out UCSRB, temp     ; включим передачу, выключим прием и прерывания
 
	ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
	out UCSRC, temp     ; формат кадра 8 бит 1 стоп
	ret
 
;**** Посылка байта из регистра temp *********
uart_snt:
	sbis UCSRA, UDRE   ; ждем готовности
	rjmp uart_snt      ; пока не готов бегаем в цикле
	out UDR, temp	   ; шлем байт
	ret   

Прошиваем микроконтроллер, запускаем Cutecom и открываем порт. Затем подаем питание на микроконтроллер и в окне терминала побегут строки с символами "A". Все работает, но на практике, для устойчивой работы протокола UART символы лучше передавать не сразу друг за другом, а с некоторой задержкой.

Выводы.

Таким образом программирование микроконтроллеров AVR в ALT Linux вполне решаемая задача.
Желаю Вам творческих успехов!

Ссылки.

  1. Ошибка 24743 - avr-gcc не находит библиотек и стабов
  2. USB программатор AVR — USBAsp
  3. Pinboard on Linux
  4. AVR Studio в Linux.
  5. How to permanently bind a variable to a register?
  6. How to permanently change /dev/ttyS0
  7. AVR-GCC: руководство по встраиванию кода на ассемблере
  8. AVR-GCC: Совмещение C и ассемблера в одном проекте
  9. AVRA: Свободу AVR ATMEL
  10. Пишем на AVR ассемблере в Ubuntu: Geany + AVRA

Комментарии

#1. 18 мая 2013 года, 01:47. Dion пишет:
Спасибо за статью! KontrollerLab только с C работает? Ассемблер не поддерживает?
#2. 18 мая 2013 года, 11:54. Андрей пишет:
Поддерживается gnu ассемблер avr-gcc. Но он неудобный, чтобы использовать символические имена регистров нужно весь текст замусорить макросами подстановки _SFR_IO_ADDR и не разобрался, как располагать в нем байты данных по фиксированным адресам (наподобие .org .db .dw в атмеловском ассемблере).

Еще в ассемблере avr-gcc есть любопытная бага. Чтобы использовать _SFR_IO_ADDR ассемблерный файл обязательно должен иметь расширением большую букву S, если будет маленькая s происходит ошибка компиляции.

Бага нашлась, когда разбирал пример со странички Давида Меллиса http://fab.cba.mit.edu/classes/MIT/863.09/ … ntrollers/

;led.S
#include <avr/io.h>
sbi _SFR_IO_ADDR(DDRB), 2
sbi _SFR_IO_ADDR(PORTB), 2

led.S компилируется, а led.s нет:

[andrew@localhost bags]$ avr-gcc -c -mmcu=attiny44 -o led.out led.s
led.s: Assembler messages:
led.s:3: Error: constant value required
led.s:3: Error: `,' required
led.s:3: Error: constant value required
led.s:3: Error: garbage at end of line
led.s:4: Error: constant value required
led.s:4: Error: `,' required
led.s:4: Error: constant value required
led.s:4: Error: garbage at end of line

[andrew@localhost bags]$ avr-gcc -c -mmcu=attiny44 -o led.out led.S
[andrew@localhost bags]$ avr-objcopy -j .text -O ihex led.out led.hex

В File/New Kontrollerlab создается ассемблерный файл с маленькой s. Поэтому, чтобы нормально работать с ассемблером лучше cоздать пустой проект, затем в блокноте пустой файл с расширением S и уже после открыть его в контроллерлабе.
#3. 18 мая 2013 года, 14:24. Dion пишет:
Понятно. Спасибо. Останусь на Geany с avra. Хардкор, так хардкор)

Оставьте свой комментарий

Ваше имя:

Комментарий:

Формулы на латехе: $$f(x) = x^2-\sqrt{x}$$ превратится в $$f(x) = x^2-\sqrt{x}$$.
Для выделения используйте следующий код: [i]курсив[/i], [b]жирный[/b].
Цитату оформляйте так: [q = имя автора]цитата[/q] или [q]еще цитата[/q].
Ссылку начните с http://. Других команд или HTML-тегов здесь нет.

Сколько будет 32+5?