Arduino Assembler
Arduino in Assembler programmieren
Um was gehts:
Arduino ist eine kostengünstige Variante um in die Mikroprozessor Programmierung einzusteigen. Mit dem Paket erhält man alles nötige und braucht nicht erst Teile kaufen und dann eventuell noch zusammenlöten.
Jedenfalls wird das Arduino mit einer eigenen Programmiersprache programmiert. Diese „Sketches“ werden dann mit Hilfe von AVR in Maschinensprache übersetzt und auf den Chip geladen.
Grundgerüst schaffen:
Um das ganze zu tun, sollte man sich zuerst die Arduino Software runterladen. Die Seite findet man hier: http://arduino.cc/en/Main/Software.
Unter den heruntergeladenen Files findet man dann im Verzeichnis reference/Guide_index.html eine Anleitung, wie man das erste Programm am Board zum Laufen bekommt. Das sollte man erstmal tun, dass man sicherstellt, das alles richtig läuft.
Und jetzt Assembler:
Funktioniert das, können wir nun zum Teil übergehen, dass wir Assembler Programme direkt auf das Arduino bringen. Die Informationen dazu habe ich von www.cypherpunk.at.
Die gute Nachricht ist, dass wir alles was wir benötigen im Download der Arduino Software finden. Und schechte Nachricht gibts keine! Folgende Schritte müssen nun durchgeführt werden:
Assemblieren des Quellcodes
Linken des Objektfiles
Objektfile nach Intel-Hex Format konvertieren
Upload auf das Arduino Board
Diese Schritte findet man auch auf der erwähnten cypherpunk Seite. Der Mehrwert meines Beitrags besteht dahin, auf die Anpassungen an die verschiedenen Arduino Boards hinzuweisen. Sonst tut sich nämlich nichts.
Die Schritte im Detail:
Zu Beginn sollte man sich in die Windows PATH Variable eventuell den Pfad zu dem Verzeichnis <ArduinoVerzeichis>\hardware\tools\avr\bin anlegen um die Befehle aus jedem Verzeichnis aufrufen zu können.
Folgende angegebenen Befehle sind alle für das Arduino Diecimila angegeben! Weiters gehe ich von einem ASM-Quellcode „led.asm“ aus.
In diesem Beitrag erkläre ich nicht die Hintergründe von Objektfiles, Linken usw. Bitte dazu in anderen Quellen nachlesen.
Der Quellcode
Wieder der www.cypherpunk.at Seite entnommen und geringfügig angepasst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
.equ RAMEND, 0x4FF ;Last On-Chip SRAM Location siehe C:\Users\fettinger\Desktop\arduino-1.0.6\hardware\tools\avr\avr\include\avr
.equ SREG, 0x3f ;liegt auf Adresse 3F
.equ SPL, 0x3d ;Stack Pointer Low Register
.equ SPH, 0x3e ;Stack Pointer High Register
.equ PORTB, 0x05 ;Port B Data Register
.equ DDRB, 0x04 ;Port B data direction register 1=output 0=input
.equ PINB, 0x03 ;Port B Input pins address
.org 0
rjmp main
main:
ldi r16,0 ; reset system status Wert 0 in Register R16
out SREG,r16 ; init stack pointer Jetzt R16 Wert nach SREG
ldi r16,lo8(RAMEND)
out SPL,r16 ;Stack Pointer Low ramend
ldi r16,hi8(RAMEND)
out SPH,r16 ;Stack Pointer high ramend
ldi r16,0x20 ; set port bits to output mode 0x20=DDB5 of DDRB
out DDRB,r16
clr r17
mainloop:
eor r17,r16 ; invert output bit r16 ist immer 1
out PORTB,r17 ; write to port
call wait ; wait some time
rjmp mainloop ; loop forever
wait:
push r16
push r17
push r18
ldi r16,0x80 ; loop 0x400000 times
ldi r17,0x00 ; ~12 million cycles
ldi r18,0x00 ; ~0.7s at 16Mhz
_w0:
dec r18
brne _w0
dec r17
brne _w0
dec r16
brne _w0
pop r18
pop r17
pop r16
ret
Ganz wichtig ist hier, dass man die Variable „RAMEND“ an das Board anpassen muss! Die Information dazu findet man im File ‚boards.txt‘ im Verzeichnis \hardware\tools\avr\avr\include\avr der Arduino Software. Im meinem Falle hat das Diecimila Board den Prozessor AtMega168 – daher musste ich im file iom168.h nachsehen und nach „RAMEND“ suchen. Dann findet man den Eintrag
1
#define RAMEND 0x4FF
Diese muss man dann eventuell im obigen Programm anpassen. Stimmt der Parameter nicht, läuft das Programm nicht!
Assemblieren des Quellcodes
Der Befehl dazu lautet
1
avr-as -g -mmcu=atmega168 -o led.o led.asm
Hier ist es wichtig den Parameter -mmcu=atmega168 an das jeweilige Board anzupassen. Am besten man sieht im File „board.txt“ der Arduino Software im Verzeichnis hardware\arduino\ nach. Dort nach dem Board und den Parameter mcu suchen. Beim Diecimila sieht der Eintrag so aus:
1
diecimila.build.mcu=atmega168
Als vorletzten Parameter gibt man den Namen des Quellfiles mit der Endung ‚.o‘ an. Welches dann das zu erzeugende Object File darstellt.
Der letze Parameter muss das ASM-Quellfile sein
Geht alles glatt, hat man am Ende das File ‚led.o‘
Linken des Objektfiles
Befehl:
1
avr-ld -o led.elf led.o
Hier als vorletzten Paremeter <Dateiname> mit Endung ‚.elf‘ angeben und als letzen das im vorigen Schritt erzeugte Objektfile.
Objektfile nach Intel-Hex Format konvertieren
Befehl:
1
avr-objcopy -O ihex -R .eeprom led.elf led.hex
Jetzt ist der vorletze Parameter das ELF-File aus dem vorigen Schritt und der letzte das zu erzeugende mit Endung ‚.hex‘.
Upload auf das Arduino Board
Befehl:
1
avrdude -C c:\avrdude.conf -p atmega168 -c arduino -P com11 -b 115200 -D -U flash:w:led.hex:i
Der Paremeter -C gibt das Configfile an, welches benötigt wird. In der Arduino Software findet man diese im Verzeichnis \hardware\tools\avr\etc.
Mit -p muss wieder das Board wie im Schritt 1 angegeben werden.
Mit -P wird der Port angegeben, auf dem das Arduino Board angeschlossen ist. Das sollte bekannt sein, denn sonst hättest du unter „Grundgerüst schaffen“ das Testprogramm nicht zum Laufen gebracht. Muss auch im Programm arduino.exe unter „Serieller Port“ hinterlegt sein.
Mit -b wird die Baudrate, mit der an den Port geschrieben wird angegeben. Dies ist wichtig, nachzulesen im schon erwähnten File „board.txt“
1
diecimila.upload.speed=19200
Beim letzen Parameter -U muss dann noch das erstellte hex-File eingetragen werden.
Bravo, nun sollte das Programm laufen!
Ergänzungen
Ich habe ein kleines Batch Programm geschrieben, dass die Befehle der Reihe nach aufruft
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@echo off
echo Assemblieren
avr-as -g -mmcu=atmega168 -o %1.o %1.asm
echo Linken
avr-ld -o %1.elf %1.o
echo Intel-Hex erstellen
avr-objcopy -O ihex -R .eeprom %1.elf %1.hex
echo Upload
avrdude -C c:\avrdude.conf -p atmega168 -c arduino -P com11 -b 19200 -D -U flash:w:%1.hex:i
echo Fertig
pause
Bitte darin nur die Bezeichnug des Boards im Befehl 1 und 4 anpassen. Weiters im Upload Befehl die Baud-Rate und das Port.
Aufzurufen ist das Batch Programm mit dem ASM-Quellcode Programmnamen ohne Endung als Parameter. z.B. ‚dojob.bat led‘ für das Programm ‚led.asm‘ und falls der Batch unter ‚dojob.bat‘ gespeichert ist.
Hoffe ich habe nichts vergessen!
Ciao und viel Spass