posts | comments



22Nov

Programmierung – Einrichten von AVR-Studio



Um den RP6 programmieren zu können, sind einige Vorbereitungen nötig, denn es wird eine Entwicklungsumgebung benötigt. Eine Entwicklungsumgebung ist ein Softwarepaket, welches in der Regel Editor, Präprozessor, Linker, Compiler und einen bestimmten Grundumfang von Standardbibliotheken mitbringt.

Die Programmierung kann mit Software wie Eclipse, diverser C/C++ -Entwicklungsumgebungen, Notepad2 und vieler weiterer Software erfolgen.

Wir nutzen für die Programmierung AVR Studio in der 4. Version. AVR Studio ist kostenlos aber registrierungspflichtig!

Um AVR Studio erfolgreich verwenden zu können, muss das Programm WinAVR  installiert sein! WinAVR ist der Compiler, auf welchen AVR Studio zugreift.

Einrichten von AVR Studio

Damit AVR Studio gleich so funktioniert, dass man mit der Programmierung des RP6 losstarten kann, muss man einige Schritte beachten.

AVR-Studio bedient sich einer “makefile”, welche AVR Studio selbst generiert, jedoch auch selbst gestaltet werden kann. Auf diese makefile kommen wir gleich zurück.

Auf den RP6 wird über den Bootloader eine HEX-Datei (Inhalte nur im hexadezimalen Bereich) gespielt, programmieren tun wir jedoch eine c-File in der Programmiersprache C.

Ausgang ist eine Hauptdatei, welche Quellcode der Programmiersprache C beinhaltet und mit der Extension .c endet, in unserem Beispiel Start.c

In diese Start.c kommt zu Beginn folgender Inhalt:

#include “RP6RobotBaseLib.h”               // The RP6 Robot Base Library.

// Main-part

int main(void)

{

initRobotBase();              // Always call this first! The Processor will not work

return 0;                            // Main-function always needs a return value!

}

Dieses Programm könnte kompiliert, hexadezimal dargestellt und über den Bootloader auf den RP6 übertragen werden, der Roboter würde dann genau nichts tun, außer sich zu initialisieren mit initRobotBase() und sein Programm zu beenden mit return 0.

Würde man die Funktion initRobotBase() und die Bekanntmachung von RP6RobotBaseLib.h weglassen, könnte man das Programm ohne weiteres Zutun kompilieren (nur könnte der RP6 noch nichts damit anfangen).

Da wir aber die initRobotBase() Funktion und noch viele weitere Funktionen, welche in der RP6RobotBaseLib.h definiert sind, benötigen, müssen wir diese RP6RobotBaseLib.h einbinden (inkludieren). Dies wird vorhergehend mit #include “RP6RobotBaseLib.h” getan.

Die RP6RobotBaseLib.h benötigt wiederum die RP6uart.h, RP6Config.h und die Rp6RobotBase.h. Diese Dateien müssen wir unserem Projekt bekannt machen.

Die Header-Dateien (.h) dienen der Definition (Bekanntmachung) der Funktionen, die in den zugehörigen Quelldateien (.c) vorzufinden sind! Das heißt, dass es zu jeder Header-Datei auch eine Quelldatei gibt.

Übrigens benutzen unsere Header-Dateien wiederum Header-Dateien, welche wir hier nicht in unser Projekt hinzufügen müssen, sondern weil die Entwicklungsumgebung AVR Studio diese standardmäßig bereitstellt, z. B. die IO.h (definiert Funktionen rund um die Ein-/Ausgabe von Daten).

Zu erst einmal müssen wir ein Projekt starten. Der ProjectWizard ist leicht in der Menüleiste zu finden und poppt auch gleich nach Programmstart automatisch auf. Hier wird ein neues Projekt eingerichtet, unser Projekt heißt beispielsweise einfach “Start” (für zukünftige Projekte sollten klar formulierte Namen herhalten, nachdenken lohnt sich!).

Der RP6 verfügt über ein ATmega32 Mikrocontroller von Atmel, das Gehirn des RP6. Der Compiler muss dies wissen (bzw. der richtige Compiler muss gewählt werden). Welche “Debug Platform” verwendet wird, ist eher Geschmackssache und an dieser Stelle nicht so wichtig, hauptsache das “Device” ist der ATmega32.

Nun steht das Project und es findet sich eine Datei mit Namen des Projekts unter den Quelldateien (Source Files), im Fall dieses Beispiels also Start.c

Es fehlen jedoch noch die Header-Dateien und die dazugehörigen Quelldateien. Diese müssen vorliegen. Bekommen kann man diese z. B. aus den Beispielprogrammen für den RP6 (im Verzeichnis RP6Base_Examples der mitgelieferten CD). Am einfachsten ist das Hinzufügen, indem man die Header-Dateien (.h) mit der Maus markiert und dann in den AVR GCC Tree (i. d. R. auf der linken Seite) in das Verzeichnis “Header Files” im AVR Studio zieht. Das Selbe tut man dann mit den Quelldateien (.c), jedoch in das Verzeichnis “Source Files” im AVR Studio.

Um Problemen am Anfang aus dem Weg zu gehen, empfiehlt es sich, die nötigen Dateien alle beisammen im Projektordner zu haben (so auch in diesem Beispiel). Auf Dauer ist es jedoch geschickter, die Dateien, welche man zwar benötigt aber nicht bearbeitet in einem extra angelegten Verzeichnis auf zu bewahren, dann muss man dieses Verzeichnis jedoch bei AVR Studio bekannt machen und sicherstellen, dass dies auch ins Makefile eingetragen wird (ggf. manuell nachtragen).

Die Makefile legt AVR Studio sich wie gesagt standardmäßig an, unter (in der Menüleiste) “Project” -> “Configuration Options” kann jedoch eine eigene Makefile angegeben werden.

Man kann nun das Programm (den obigen Quellcode oder ein Beispielprogramm von der RP6 CD) kompilieren, in dem man im AVR Studio im Menü auf “Build” klickt und danach, sofern nicht bereits Fehlermeldungen erscheinen, nochmals auf “Compile“.

Wenn keine Fehler im Programm-Quellcode vorliegen, werden nun Dateien erzeugt, darunter die HEX-Datei mit hexadezimalem Inhalt. Diese Datei ist von besonderer Bedeutung, denn diese können wir über den Bootloader und dem USB-Anschluss zum RP6 laden.

Nachfolgend die Makefile, die für dieses Beispiel verwendet wurde. Diese kann man als Orientierung verwenden, falls die automatisch erzeugte Makefile von AVR Studio nicht funktioniert.

###############################################################################
# Makefile for the project Start
###############################################################################

## General Flags
PROJECT = Start
MCU = atmega32
TARGET = Start.elf
CC = avr-gcc

CPP = avr-g++

## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)

## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=Start.map

## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature

HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += –set-section-flags=.eeprom=”alloc,load”
HEX_EEPROM_FLAGS += –change-section-lma .eeprom=0 –no-change-warnings

## Objects that must be built in order to link
OBJECTS = Start.o RP6I2CmasterTWI.o RP6uart.o RP6RobotBaseLib.o

## Objects explicitly added by the user
LINKONLYOBJECTS =

## Build
all: $(TARGET) Start.hex Start.eep Start.lss size

## Compile
Start.o: ../Start.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

RP6I2CmasterTWI.o: ../RP6I2CmasterTWI.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

RP6uart.o: ../RP6uart.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

RP6RobotBaseLib.o: ../RP6RobotBaseLib.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

##Link
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@

%.eep: $(TARGET)
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

%.lss: $(TARGET)
avr-objdump -h -S $< > $@

size: ${TARGET}
@echo
@avr-size -C –mcu=${MCU} ${TARGET}

## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) Start.elf dep/* Start.hex Start.eep Start.lss Start.map

## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

Categories: Allgemein