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:

    1. Assemblieren des Quellcodes

    2. Linken des Objektfiles

    3. Objektfile nach Intel-Hex Format konvertieren

    4. 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