heise online
  • c't
  • iX
  • Technology Review
  • Mac & i
  • mobil
  • Security
  • Netze
  • Open Source
  • Developer
  • c't-TV
  • Download
  • Telepolis
  • Resale
  • Foto
  • Autos
  • Preisvergleich
  • Stellenmarkt
  • Abo
  • weitere Angebote
    • Shop
    • Artikel-Archiv
    • Veranstaltungen
    • Whitepapers
    • heise-marktplatz
    • IT-Markt
    • Tarifrechner
    • Jobs bei Heise

c't Magazin
  • Startseite
  • Artikel
  • c't-Projekte
  • Hotline & FAQ
  • Treiber & mehr
  • Kolumnen
Software zu Projekten Allgemeine Hinweise
Archiv-Suche Newsletter RSS-FeedRSS

c't › c't-Projekte

Trac
  • Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • Start Page
  • Index
  • History
  • Last Change

EEPROM Emulation für PC

Version 1.1 17-Sep-2007
Achim Pankalla (achim.pankalla@gmx.de)


Beschreibung
Die EEPROM Emulation für den PC stellt das EEPROM des Atmel MEGA32(644) Prozessors auch dem ct-Sim zur Verfügung. Der Zugriff auf dieses EEPROM erfolgt über gleichnamige Funktionen, wie sie auch die avr-libc bereitstellt und auch die Variablendefinition erfolgt über die gleichen Konstrukte. Eine Unterscheidung über #ifdef's ist also nicht notwendig.
Durch diese EEPROM-Emulation ist der ct-Sim dem realen Bot einen Schritt näher gekommen und Programme mit EEPROM-Zugriffe können mit der Simulation getestet werden. Mehr noch, Sie können auch den Inhalt des emulierten EEPROM auf den ct-Bot übertragen oder das EEPROM vom ct-Bot laden und für die Emulation nutzen.


Implementierung

Alle Funktionen und Einstellungen der EEPROM Emulation findet Sie in den Dateien pc/eeprom-emu_pc.c und include/eeprom-emu.h. Das EEPROM selbst wird durch eine binäre Datei (genau 1 KB bzw. 2 KB groß) repräsentiert und kann so mit einen HexEditor bearbeitet werden. Der Pfad mit Dateinamen befindet sich in den Konstanten MCU_(PC_)EEPROM_FN in der C-Datei. Standard Pfad ist das Heimatverzeichnis des ct-Bots. 
Die Datei wird automatisch neu angelegt, wenn sie noch nicht existiert, dann wird die Datei automatisch mit den aktuellen Zuweisung der EEPROM-Variablen initialisiert (mit Hilfe von ct-Bot.eep). Ist schon eine eeprom.bin vorhanden, so wird diese nicht verändert, ausser die ct-Bot.exe wird mit dem Parameter -i gestartet, dann wird auch eine schon vorhandene Datei mit den vorhandenen Zuweisungen überschrieben.
Damit die EEPROM-Funktionen des PC korrekt auf die Datei zugreifen können darf nur ein Adressraum von 0 bis 1023 (bzw. 2047) entstehen. Die Emulation muss also wissen welche Speicheradresse die erste Variable im EEPROM hat, um diesen Wert von allen anderen abzuziehen. Dafür bedarf es bei der PC Implementierung (mit PC ist allgemein der Code für den ct-Sim gemeint, mag das OS nun Win, Linux oder Mac OS X heißen) eines Tricks. 
Dafür gibt es die beiden Variablen _eeprom_start1__ und _eeprom_start2__ in 1st_init.S. Diese stehen dort, damit sie auf jeden Fall vor der ersten EEPROM Variable definiert werden und damit ihre Sections (.s1eeprom + .s2eeprom) auf jeden Fall vor der Section .eeprom liegen.
Durch diesen Trick kann die Speicheradresse der ersten EEPROM Variable auch ohne Linkerscript ermittelt werden und auch verschiedene Section-Alignments (im Moment bei MinGW und Linux unterschiedlich) haben keine Auswirkung.
Auch beim Generieren einer neuen Datei ct-Bot.exe/elf wird eine EEP mit den Initialisierungen der EEPROM-Variablen im Post-Build angelegt. Diese Datei kann  die EEPROM-Emulation auch als Initialisierung für die eeprom.bin im MCU-Modus benutzen. Sollte keine eeprom.bin existieren, wird sie auch dafür genutzt. Arbeitet man im PC-Modus, kann diese Datei auch in eeprom.bin umbenannt werden.
Damit die Emulation möglichst effektiv und schnell arbeiten kann, wird nach dem Start die gesamte Datei eeprom.bin im Hauptspeicher gecached und nach jedem Schreibzugriff komplett neu geschrieben.
Damit man die EEPROM-Datei auch auf den ct-Bot einspielen kann, oder einen EEPROM Abzug  des ct-Bot als emuliertes EEPROM nutzen kann, werden Post-Builds benötigt, die die Adressen der einzelnen Variablen auf ct-Bot und ct-Sim aufzeigen. Der EEPROM Manager wird beim Start eines Bots im ct-Sim dann eine (Adress)Konvertierungstabelle erstellen, um die Zugriffe auf das EEPROM anzupassen. Diese Tabelle wird nach aufsteigenden Adressen des ct-Sim sortiert und nur im MCU-Modus genutzt.

Nutzung der EEPROM Emulation
Die EEPROM-Emulation unterscheidet sich nur in ein paar Details von den Funktionen der avr-libc für den realen ct-Bot. Natürlich hat der PC kein EEPROM, dieses wird durch eine Datei im Binärformat emuliert. Der Dateinamen und der Pfad wird über die Konstanten MCU_EEPROM_FN und PC_EEPROM_FN in eeprom-emu_pc.c festgelegt, je nach Modus wird die entsprechende Datei angelegt. So kann man auch am Dateinamen den Aufbau des EEPROMs erkennen. Wechselt der Modus, wird die vorherige Datei gelöscht. Dadurch liegen immer die initialsierten EEPROM-Variablen an der richtigen Stelle und ein Fehlverhalten der Bots in der Simulation wird vermieden.
Ein weiterer Unterschied ist, dass beim avr-gcc über ein DEFINE der Prozessortyp festgelegt wird, entweder ATMega32 oder ATMega644. Dieses DEFINE ist beim PC Compiler normalerweise nicht gesetzt. Standardmäßig wird von einem ATMega32 mit 1024 Byte EEPROM ausgegangen, Die Emulation kennt aber die Konstante für den ATMega644 und erhöht den EEPROM Speicher auf 2048 Bytes. Sollte schon eine 1 KB Datei fürs EEPROM bestehen, so muss diese gelöscht werden, damit die Größere angelegt wird. Wird direkt die erstellte ct-bot.eep Datei im PC-Modus genutzt, ist dies natürlich nicht notwendig.
Alle wichtigen Informationen werden beim Start von ct-Bot.exe/elf im Log-Fenster angezeigt, vorrausgesetzt es ist in ct-bot.h aktiviert ist (zusätzlich bitte in eeprom-emu_pc.c die Konstante DEBUG_EEPROM aktivieren), dort sieht man auch alle eventuellen Fehler, den erreichten Emulationsmodus und ob die Emulation ordnungsgemäß arbeiten kann. Es erfolgt kein Beenden bei Problemen, die Funktion des EEPROMs ist dann aber nicht gegeben. Bei Auffälligkeiten sollte man dann die LOG Funktion aktivieren.

Generell unterscheidet die Emulation zwei Modi:

  1. PC-Modus
    In diesen Modus entspricht die eeprom.bin nicht dem EEPROM des realen ct-Bots und darf deshalb auch nicht auf ihn aufgespielt werden. Dieser Modus wird ohne jedes Zutun erreicht. Er benötigt keine weiteren Einträge im Post-Build. Wenn eine ct-bot.eep im Binärformat erstellt wird, so kann diese direkt benutzt werden.

  2. MCU-Modus
    Ist dieser Modus erreicht, kann man als EEPROM-Datei einen EEPROM Abzug vom ct-Bot verwenden. Voraussetzung ist natürlich, dass der Bot auch mit zuletzt erstelltem Programm bespielt ist. Natülich kann man auch die EEPROM-Datei eeprom.bin auf dem ct-Bot aufgespielen.
    Der MCU-Modus kann nur erreicht werden, wenn sowohl beim avr-gcc als auch unter dem ct-Sim eine map-Datei erstellt wird, dafür müssen im Post-Build die Befehle aus dem Kommentarkopf aus eeprom-emu_pc.c ausgeführt werden.

    In den Projekteinstellungen im SVN sind die nötigen Post-Build-Einstellungen für alle Betriebssysteme bereits gemacht.

Möchte man die vorhandene EEPROM-Datei mit den Daten aus der EEP-Datei initialisieren, so muss man die ct-Bot.exe/elf mit dem Parameter -i starten, dabei spielt es keine Rolle in welchen Modus die Emulation arbeitet. Der Pfad der EEP-Datei wird in der Konstante EEP_PC und die Pfade für die MAP-Dateien werden in den Konstanten EEMAP_PC und EEMAP_MCU eingetragen.
Die Variable MAX_VAR legt die Größe der Tabelle fest und beschrängt damit die maximale Anzahl der Variablen. Sollte die Fehlermeldung auftreten, dass es zu viele Variablen gibt, muss man diesen Wert nur erhöhen.

Für das Debuggen von Zugriffen auf das EEPROM stehen unter anderem die DEFINES LOG_STORE und LOG_LOAD zur Verfügung, die im MCU Modus sogar den Variablennamen anzeigen. Andere Variationen sind auch noch denkbar.

Grenzen der Implementierung
Im Moment erstellen gleiche Compilerversionen (zu überprüfen mit --version) auch (fast) gleiche EEPROM-Sections. Damit es auch mit verschiedenen Compiler Version geht (und ich mich auch nicht auf die gleichen Versionen verlasssen will) habe ich die Adresskonvertierung eingeführt, damit dies kein Problem mehr ist. Es gibt aber keine Garantien dafür, dass zukünftige Compiler Versionen nicht die Reihenfolge der Variablen im Code ändern. Ein Einfügen neuer EEPROM Variablen kann auch zu Verschiebungen der Adressen führen. Nach solchen Änderungen (auch ein ändern der Compilerversion) ist man nur auf der sicheren Seite, wenn das EEPROM initialisiert wird (sprich, Sie Ihre alte eeprom.bin bzw. auf dem Atmel das EEPROM löschen) und für MCU und ct-Sim neue Exe generiert werden. Einmal erstellte Werte sind dann natürlich futsch. Wenn man den Einfluss von Codeergänzungen kontrollieren will, kann man dies vor und nach der Änderung mit objdump machen (oder falls Sie die Befehle für die MAP-Dateien im Post-Build benutzen, schauen Sie in die MAP-Dateien), mit den richtigen Parametern kann man sich die Adressverteilung anzeigen lassen. Sie können dann sehen, ob die neuen Variablen nun hinten angehängt wurden (dann brauch das EEPROM nicht gelöscht werden) oder sie dazwischen gelandet sind (dann sind die alten Daten unbrauchbar), dafür sollten sie aber vorher in Eclipse Projekt->clean aufrufen.
Der Compiler kann aufgrund der Implementierung des EEPROMs auf dem PC nicht kontrollieren, ob mehr als 1024/2048 Bytes für die Variablen benötigt werden, er kennt diese Begrenzung nicht. Der EEPROM-Manager meckert dann aber im LOG.

Verschiedenes
Ein besonderer Dank an dieser Stelle an Timo Sandmann unter anderem für das Testen unter MacOSX und für verschiedene Anpassungen, Optimierungen und für den Assemblercode in 1st_init.S ohne den wohl ständige Probleme unvermeidlich gewesen wären.
Dank auch an alle anderen für konstruktive Kritik, die die jetzige, ich denke annehmbare, Lösung erst möglich machte und meiner Familie für ihre unendliche Geduld.
Möge sich jeder eingeladen fühlen etwas zu verbessern oder erweitern.

Funktionen
init_eeprom_man() - Erledigt alle Arbeiten zur Aktivierung der EEPROM-Emulation

Nur in eeprom-emu_pc.c sichtbare Funktionen

conv_eeaddr() - Wandelt PC Adresse in ct-Bot Adresse
create_ctab() - Erstellt Adresskonvertierungstabelle
check_eeprom_file() - Erstellt leeres EEPROM, wenn nötig und initialisiert es, wenn gewünscht
flush_eeprom_cache() - Schreibt veränderte Daten in eeprom.bin

Zugriffsfunktionen für den PC (identisch zu denen der avr-libc)
eeprom_read_byte()
eeprom_write_byte()
eeprom_read_word()
eeprom_write_word()
eeprom_write_block()
eeprom_read_block()

Dateien

eeprom-emu.h - Headerdatei mit den Deklarationen
eeprom-emu_pc.c - Implementierung der Funktionen für ct-Bot & ct-Sim
1st_init.S - Sorgt für das korrekte Anlegen der Hilfsvariablen in der Exe

Download in other formats:

  • Plain Text

Trac Powered

Powered by Trac 0.11.7
By Edgewall Software.

http://www.ctmagazin.de/
http://www.ctmagazin.de/projekte/

  • Datenschutzhinweis
  • Impressum
  • Kritik, Anregungen bitte an c't-WWW
  • Mediadaten
  • Copyright © 2011 Heise Zeitschriften Verlag
  • International: The H, The H Security, The H Open Source