|
 |
 |
 |
|
|
c't Projekte - c't-Bot und c't-Sim -
Mailinglisten
[Voriger (Datum)]
[Nächster (Datum)]
[Voriger (Thread)]
[Nächster (Thread)]
[Nach Datum][Nach Thread]
Absender: Achim Pankalla
Datum: Mo, 17.09.2007 19:01:53
In-reply-to:
<46EC2190.1060306@xxxxxx>
References:
<000601c7f702$605cacb0$fe78a8c0@mexpnew> <FAAB09B3-2B6D-4A53-96F7-3AEAF1C2563E@xxxxxxxxxxxxxxx> <46EC2190.1060306@xxxxxx>
hallo,
hier nun das update für die eeprom-emulation. :-)
bei einen modus-wechsel wird nun die datei des alten modus gelöscht und
eine neue, gültige, angelegt. da die debug-ausgaben, an der man den
erreichten modus erkennen kann, normalerweise aus sind. habe ich es so
geändert, das man für jeden modus einen dateinamen angeben kann.
vorgegeben sind mcu_eeprom.bin und pc_eeprom.bin. das macht es doch
schön offensicht, im welchen modus die emulation ist oder ? ;-)
anbei auch die angepasste docu.
Mit freundlichen Grüßen
achim
Index: E:/eclipse/ct-bot devel/ct-Bot/pc/eeprom-emu_pc.c
===================================================================
--- E:/eclipse/ct-bot devel/ct-Bot/pc/eeprom-emu_pc.c (revision 1247)
+++ E:/eclipse/ct-bot devel/ct-Bot/pc/eeprom-emu_pc.c (working copy)
@@ -1,510 +1,518 @@
-/*
- * c't-Bot
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * This program is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307, USA.
- *
- */
-
-/*!
- * @file eeprom-emu_pc.c
- * @brief Low-Level Routinen fuer den Zugriff auf das emulierte EEPROM des Sim-c't-Bots
- * @author Achim Pankalla (achim.pankalla@xxxxxx)
- * @date 07.06.2007
- */
-
-// Post-Build AVR:
-// avr-objcopy -O ihex -R .eeprom ct-Bot.elf ct-Bot.hex; avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex ct-Bot.elf ct-Bot.eep; avr-size ct-Bot.elf; avr-objdump -t ct-Bot.elf | grep "O \.eeprom" > eeprom_mcu.map
-
-// Post-Build Linux:
-// objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary ct-Bot.elf ct-Bot.eep; objdump -t -j .eeprom -C ct-Bot.elf | grep "g" > eeprom_pc.map
-
-// Post-Build Mac OS X:
-// objcopy -j LC_SEGMENT.__DATA..eeprom --change-section-lma LC_SEGMENT.__DATA..eeprom=0 -O binary ct-Bot ct-Bot.eep; objdump -t -j LC_SEGMENT.__DATA..s2eeprom -C ct-Bot | grep "g" > eeprom_pc.map
-
-// Post-Build Windows:
-// objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary ct-Bot.exe ct-Bot.eep;objdump -t ct-Bot.exe | grep "(sec 5)" | grep "(nx 0)" > eeprom_pc.map
-
-
-#include "ct-Bot.h"
-
-#ifdef PC
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "log.h"
-#include "gui.h"
-
-//#define DEBUG_EEPROM // Schalter um LOG-Ausgaben anzumachen
-
-#ifndef DEBUG_EEPROM
- #undef LOG_INFO
- #define LOG_INFO(a, ...) {}
-#endif
-
-extern uint8 __attribute__ ((section (".s1eeprom"),aligned(1))) _eeprom_start1__;
-extern uint8 __attribute__ ((section (".s2eeprom"),aligned(1))) _eeprom_start2__;
-
-/*! Normiert PC EEPROM Adressen*/
-#define EEPROM_ADDR(x) ((uint32)x - (uint32)&_eeprom_start2__ - ((uint32)&_eeprom_start2__ - (uint32)&_eeprom_start1__))
-/*! Makros zum Mitloggen von EEPROM Zugriffen*/
-#define LOG_LOAD if(addrconv) {LOG_DEBUG("LOAD:%s : %u", ctab[lastctabi].varname, eeprom[address]);}\
- else {LOG_DEBUG("load-addr=0x%x/%u", address, eeprom[address]);}
-#define LOG_STORE if(addrconv) {LOG_DEBUG("STORE:%s : %d", ctab[lastctabi].varname, value);}\
- else {LOG_DEBUG("load-addr=0x%x/%d", address, value);}
-
-/*! Positionen der Daten in den Map-Dateien */
-#ifdef WIN32
- #define SADDR_POS 54 /*!< Pos. der Adresse in PC Map Datei */
- #define SNAME_POS 60 /*!< Pos. des Variablennamen ohne _ */
- #define BADDR_POS 0 /*!< Pos. der Adresse in MCU Map Datei */
- #define BNAME_POS 34 /*!< Pos. des Variablennamen in MCU Map */
- #define BSIZE_POS 28 /*!< Pos. der Variablengroesse in MCU Map */
-#endif
-#ifdef __linux__
- #define SADDR_POS 0 /*!< Pos. der Adresse in PC Map Datei */
- #define SNAME_POS 46 /*!< Pos. des Variablennamen ohne _ */
- #define BADDR_POS 0 /*!< Pos. der Adresse in MCU Map Datei */
- #define BNAME_POS 34 /*!< Pos. des Variablennamen in MCU Map */
- #define BSIZE_POS 28 /*!< Pos. der Variablengroesse in MCU Map */
-#endif
-#ifdef __APPLE__
- #define SADDR_POS 0 /*!< Pos. der Adresse in PC Map Datei */
- #define SNAME_POS 45 /*!< Pos. des Variablennamen ohne _ */
- #define BADDR_POS 0 /*!< Pos. der Adresse in MCU Map Datei */
- #define BNAME_POS 34 /*!< Pos. des Variablennamen in MCU Map */
- #define BSIZE_POS 28 /*!< Pos. der Variablengroesse in MCU Map */
-#endif
-
-#ifdef __AVR_ATmega644__ // Dieser Prozessor hat 2048 Bytes EEPROM
- #define EE_SIZE 2048
-#else
- #define EE_SIZE 1024
-#endif
-
-#define EEPROM_FILENAME "./eeprom.bin" /*!< Name und Pfad der EEPROM Datei. Verzeichnis muss existieren. Backslash doppeln!*/
-#define MAX_VAR 200 /*!< Maximale Anzahl von Variablen*/
-#define EEMAP_PC "./eeprom_pc.map" /*!< Pfad fuer PC-MAP Datei */
-#define EEP_PC "./ct-Bot.eep" /*!< Pfad fuer PC-EEP Datei */
-#ifdef WIN32
- /* Windows */
- #define EEMAP_MCU "../debug-mcu-w32/eeprom_mcu.map" /*!< Pfad fuer MCU MAP Datei */
-#else
- /* Linux und OS X */
- #define EEMAP_MCU "../Debug-MCU-Linux/eeprom_mcu.map" /*!< Pfad fuer MCU MAP Datei */
-#endif
-
-typedef struct addrtab {
- char varname[30];
- size_t simaddr;
- size_t botaddr;
- uint16_t size;
-// uint32 access; // ??? wird nie ausgewertet
-} AddrCTab_t; /*!< Spezieller Datentyp fuer Adresskonvertierung */
-
-static AddrCTab_t ctab[MAX_VAR]; /*!< Adresskonvertierungstabelle */
-static uint16 tsize=0; /*!< Anzahl Eintraege in der Tabelle */
-static uint16 esize=0; /*!< Summe der EEPROM Variablen */
-static uint8 addrconv = 0; /*!< Adresskonvertierung ein-/ausschalten */
-static uint16 lastctabi = 0; /*!< Letzter Zugriffsindex auf ctab */
-static uint8 eeprom[EE_SIZE]; /*!< EEPROM Speicher im RAM */
-static FILE * ee_file; /*!< Zeiger auf EEPROM-Datei */
-
-/*!
- * Diese Funktion konvertiert die Adressen der EEPROM Variablen des PC so,
- * dass sie den Adressen im realen ct-Bot entsprechen. Dafuer wird mit der Funktion
- * create_ctab ein Adresstabelle angelegt, diese nutzt diese Funktion.
- * @param addr Adresse im EEPROM zwischen 0 und EE_SIZE-1
- * @return Die neue Adresse fuer den realen Bot
- */
-static uint32 conv_eeaddr(uint32 addr){
- int8 i;
- int32 adiff;
-
- if(!addrconv) //Keine Adresskonvertierung
- return(addr);
- for(i=0; i<tsize; i++){
- adiff = addr - ctab[i].simaddr;
- if(adiff < 0)
- return(0xfffffffe);
- if(adiff < ctab[i].size){
- lastctabi = i; //Letzer guelten Index merken
- return(ctab[i].botaddr + adiff);
- }
- }
- return(0xffffffff);
-}
-
-/*!
- * Diese Funktion uberprueft das vorhanden sein der eeprom.bin und initialisiert sie
- * gegebenenfalls mit der Initwerten der eep Datei.
- * Es wird dabei die Adresskovertierung benutzt, wenn die EEPROM Simulation im MCU-Modus
- * ist.
- * -----
- * 0 = EEPROM Datei OK
- * 1 = Fehler aufgetreten
- * -----
- * @param initfile EEP-Datei des PC Codes
- * @param eeprom_init Flag fuer Initialisierung (1 ja, 0 nein)
- * @return Status der Funktion
- */
-static uint16 check_eeprom_file(char *initfile, uint8_t eeprom_init){
- FILE *fpr, *fpw; //Filepointer fuer Dateizugriffe
- uint16 i; //Laufvariable
- char data[2]; //Datenspeicher
-
- /*eeprom file vorhanden*/
- if(!(fpw = fopen(EEPROM_FILENAME, "r+b"))){ //Testen, ob Datei vorhanden ist.
- if(!(fpw = fopen(EEPROM_FILENAME, "w+b"))){ //wenn nicht, dann erstellen
- LOG_INFO("->Kann EEPROM-Datei nicht erstellen");
- return(1);
- }
- if(!addrconv) {
- /* EEPROM mit .eeprom-Section des .elf-Files initialisieren, wenn PC Modus */
- uint8_t * ram_dump = (uint8_t *)(&_eeprom_start2__ + (&_eeprom_start2__ - &_eeprom_start1__));
- fwrite(ram_dump, EE_SIZE, 1, fpw);
- } else {
- /* alternativ: leeres EEPROM erstellen und init setzen bei MCU Modus*/
- for(i = 0; i < EE_SIZE; i++)
- fwrite("\377", 1, 1, fpw);
- eeprom_init = 1;
- }
-
- fclose(fpw);
- LOG_INFO("->Leere EEPROM-Datei erstellt");
- }
-
- /*Initialsieren der eeprom.bin, wenn gewuenscht*/
- if(eeprom_init){
- if(!(fpr = fopen(initfile, "rb"))){ //Datei oeffnen
- LOG_INFO("->EEP nicht gefunden");
- return(1);
- }
- if(!(fpw = fopen(EEPROM_FILENAME, "rb+"))){ //Datei oeffnen
- LOG_INFO("->EEPROM-Datei kann nicht beschrieben werden");
- return(1);
- }
-
- /*EEP-Datei in EEPROM-Datei kopieren*/
- for(i=0; i<EE_SIZE; i++){
- /*Daten kopieren*/
- if(!fread(data, 1, 1, fpr))
- break;
- if(addrconv){ //EEPROM-Datei im MCU-Modus
- uint32 naddr;//Konvertierte Adresse
-
- naddr = conv_eeaddr((uint32)i);
- if(naddr < 0xfffffffe){
- fseek(fpw, (int32)naddr, SEEK_SET);
- }
- else{
- continue; //Nichts schreiben Adresse nicht belegt
- }
- }
- fwrite(data, 1, 1, fpw);
- }
- fclose(fpr);
- fclose(fpw);
- LOG_INFO("->EEPROM-Datei mit Daten init.");
- }
- return(0);
-}
-
-/*!
- * Diese Funktion erstellt aus den beiden im Post erstellten MAP Dateien eine Tabelle
- * zum umrechnen der PC-Adressen in die des avr-Compilers. Dadurch kann die EEPROM
- * Datei in einen zum EEPROM des Bot kompatiblen Format gehalten werden.
- * Wichtige Informationen werden ueber LOG_INFO angezeigt.
- * ----
- * Ergebniscodes der Funktion
- * 0 = Fehlerfrei
- * 1 = Sim Mapfile nicht vorhanden
- * 2 = Bot Mapfile nicht vorhanden
- * 3 = Unterschiedlicher Variablenbestand
- * 4 = Zuviele Variablen
- * 5 = EEPROM voll
- * 6 = Unterschiedliche Variablenanzahl
- *
- * @param simfile MAP mit den Adressen der EEPROM-Variablen in der PC exe/elf
- * @param botfile MAP mit den Adressen der EEPROM-Variablen im MCU elf
- * @return Statuscode
- */
-static uint16 create_ctab(char *simfile, char *botfile){
- FILE *fps, *fpb;
- char sline[250], bline[250]; //Textzeilen aus Dateien
- char vname_s[30], vname_b[30]; //Variablennamen
- size_t addr_s, addr_b; //Adressen der Variablen
- uint16_t size; //Variablengroesse
- uint16 vc = 0; //Variablenzaehler
- size_t first_botaddr = 0xffffffff; //Erste ct-bot EEPROM Adressse
-
- /*Dateien oeffnen*/
- if(!(fps=fopen(simfile,"r"))){
- LOG_INFO("->EEPROM-MAP fuer PC fehlt");
- return(1);
- }
- if(!(fpb=fopen(botfile,"r"))){
- LOG_INFO("->EEPROM-MAP fuer MCU fehlt");
- return(2);
- }
-
- /*Anzahl Variablen vergleichen*/
- while(fgets(sline, 249, fps)) vc++;
- while(fgets(sline, 249, fpb)) vc--;
- if(vc){
- fclose(fps);
- fclose(fpb);
- LOG_INFO("->Unterschiedliche Variablenanzahl");
- return(6);
- }
- rewind(fps);
- rewind(fpb);
-
- /*Tabelle erstellen*/
- while(fgets(sline, 249, fps)){
- rewind(fpb);
- sscanf(&sline[SNAME_POS], "%s", vname_s);
-// printf("vname_s=%s\n", vname_s);
- addr_s = strtol(&sline[SADDR_POS], NULL, 16);
-// printf("addr_s=0x%lx\n", addr_s);
- while(fgets(bline, 249, fpb)){
- /*Variablennamen suchen*/
- sscanf(&bline[BNAME_POS], "%s", vname_b);
-// printf("vname_b=%s\n", vname_b);
- addr_b = strtol(&bline[BADDR_POS], NULL, 16);
-// printf("addr_b=0x%lx\n", addr_b);
- if(addr_b < first_botaddr)//Kleinste ct-bot Adresse bestimmen
- first_botaddr = addr_b;
- size = strtol(&bline[BSIZE_POS], NULL, 16);
-// printf("size=0x%x\n", size);
-
- if(!strcmp(vname_s, vname_b)){
- /*Daten kopieren*/
- strcpy(ctab[tsize].varname, vname_b);
- ctab[tsize].simaddr = addr_s;
- ctab[tsize].botaddr = addr_b;
- ctab[tsize++].size = size;
- //ctab[tsize++].access = 0; // ??? wird nie ausgewertet
- esize += size;
- /*Fehlerabbrueche*/
- if(tsize == MAX_VAR){
- LOG_INFO("->Mehr als %n Variablen",MAX_VAR);
- return(4);
- }
- if(esize > EE_SIZE){
- LOG_INFO("->EEPROM voll");
- return(5);
- }
-
- /*Erfolg markieren*/
- addr_b = -1;
- break;
- }
- }
- if(addr_b > -1){ //Keine passende Variable gefunden
- LOG_INFO("->Unterschiedliche Variablen");
- return(3);
- }
- }
-
- /*Dateien schliessen*/
- fclose(fps);
- fclose(fpb);
-
- /*Tabelle nach Sim-Adressen sortieren*/
- uint16_t i, j;
- for(j=tsize-1; j > 0; j--){
- for(i=0; i < j; i++){
- if(ctab[i].simaddr > ctab[i+1].simaddr){
- size_t simaddr, botaddr, size;
- char vname[30];
-
- /*Daten umkopieren*/
- strcpy(vname, ctab[i+1].varname);
- simaddr = ctab[i+1].simaddr;
- botaddr = ctab[i+1].botaddr;
- size = ctab[i+1].size;
-
- strcpy(ctab[i+1].varname, ctab[i].varname);
- ctab[i+1].simaddr = ctab[i].simaddr;
- ctab[i+1].botaddr = ctab[i].botaddr;
- ctab[i+1].size = ctab[i].size;
-
- strcpy(ctab[i].varname, vname);
- ctab[i].simaddr = simaddr;
- ctab[i].botaddr = botaddr;
- ctab[i].size = size;
- }
- }
- }
-
- /*Die EEPROM-Startadressen vom ct-bot und/oder Ct-Sim auf Null normieren*/
- size_t first_simaddr = ctab[0].simaddr;
- if(first_simaddr || first_botaddr) {
- LOG_INFO("->Adressen werden normiert");
- for(i=0; i<tsize; i++){
- if(first_simaddr) ctab[i].simaddr -= first_simaddr;
- if(first_botaddr) ctab[i].botaddr -= first_botaddr;
-// printf("addr_b=0x%x addr_b=0x%x\n", ctab[i].botaddr, ctab[i].simaddr);
- }
- }
-
-// for (i=0; i<tsize; i++) {
-// printf("i=%u\n", i);
-// printf("varname=%s\n", ctab[i].varname);
-// printf("simaddr=0x%lx\n", ctab[i].simaddr);
-// printf("botaddr=0x%lx\n", ctab[i].botaddr);
-// printf("size=0x%x\n\n", ctab[i].size);
-// }
- return(0);
-}
-
-/*!
- * Diese Funktion initialisiert die eeprom-emulation. Sie sorgt fuer die Erstellung der
- * eeprom.bin, falls nicht vorhanden und erstellt ueber eine Hilfsfunktion eine Adress-
- * konvertierungstabelle fuer die EEPROM-Adressen, wenn die benoetigten Daten vorliegen.
- * Statusinformationen werden ueber DEBUG_INFO angezeigt.
- * @param init gibt an, ob das EEPROM mit Hilfer einer eep-Datei initialisiert werden soll (0 nein, 1 ja)
- * @return 0: alles ok, 1: Fehler
- */
-uint8_t init_eeprom_man(uint8_t init) {
- uint16 status; //Status von create_ctab
- uint16 sflag; //Sectionstatus
-
- LOG_INFO("EEPROM-Manager");
-
- /*Adresskonvertierungstabelle anlegen*/
- if((status=create_ctab(EEMAP_PC, EEMAP_MCU))){
- LOG_INFO("->EEPROM im PC-Modus");
- }
- else {
- LOG_INFO("->EEPROM im MCU-Modus");
- addrconv = 1;
- }
-
- /*Sections ueberpruefen*/
- if((&_eeprom_start2__ - &_eeprom_start1__) > 0 && (&resetsEEPROM - &_eeprom_start2__) >0){
- LOG_INFO("->Sections liegen wohl korrekt");
- LOG_INFO("->Section Abstand 0x%X", (&_eeprom_start2__ - &_eeprom_start1__));
- sflag = 0;
- }
- else{
- LOG_INFO("->Sections liegen falsch");
- sflag = 1;
- }
-
- /*eeprom.bin checken*/
- if(sflag || check_eeprom_file(EEP_PC, init)){
- LOG_INFO("EEPROM-Emulation fehlerhaft");
- return 1;
- }
- else{
- LOG_INFO("->EEPROM Groesse: %d Bytes", EE_SIZE);
- if(addrconv)
- LOG_INFO("->Belegter EEPROM Speicher: %d Bytes", esize);
- LOG_INFO("EEPROM-Emulation einsatzbereit");
- }
-
- if((ee_file = fopen(EEPROM_FILENAME, "r+b")) == NULL) return 1;
- if (fread(eeprom, 1, EE_SIZE, ee_file) != EE_SIZE) return 1;
- return 0;
-}
-
-/*!
- * Schreibt den kompletten Inhalt des EEPROM-Caches in die Datei zurueck
- */
-static inline void flush_eeprom_cache(void) {
- fseek(ee_file, 0, SEEK_SET);
- fwrite(eeprom, 1, EE_SIZE, ee_file);
- fflush(ee_file);
-}
-
-/*!
- * Laedt ein Byte aus dem EEPROM.
- * @param addr Adresse im EEPROM zwischen 0 und 1023
- * @return Wert der Speicheraddresse im EEPROM
- */
-uint8_t eeprom_read_byte(const uint8_t * addr) {
- uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
- if (address >= EE_SIZE) return 0xff;
- return eeprom[address];
-}
-
-/*!
- * Laedt ein Word aus dem EEPROM.
- * @param addr Adresse im EEPROM zwischen 0 und 1023
- * @return Wert der Speicheraddresse im EEPROM
- */
-uint16_t eeprom_read_word(const uint16_t * addr) {
- uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
- if (address >= EE_SIZE-1) return 0xffff;
- uint8_t * ptr = eeprom + address;
- return *(uint16_t *)ptr;
-}
-
-/*!
- * Kopiert einen Block aus dem EEPROM ins RAM
- * @param pointer_ram Adresse im RAM
- * @param pointer_eeprom Adresse im EEPROM
- * @param size Groesse des Blocks in Byte
- */
-void eeprom_read_block(void *pointer_ram, const void *pointer_eeprom, size_t size) {
- uint16_t address = conv_eeaddr(EEPROM_ADDR(pointer_eeprom));
- if (address+size >= EE_SIZE) return;
- uint8_t * ptr = eeprom + address;
- memcpy(pointer_ram, ptr, size);
-}
-
-/*!
- * Speichert ein Byte im EEPROM.
- * @param addr Adresse im EEPROM zwischen 0 und 1023
- * @param value Das abzulegende Byte
- */
-void eeprom_write_byte(uint8_t * addr, uint8_t value) {
- uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
- if (address >= EE_SIZE) return;
- eeprom[address] = value;
- flush_eeprom_cache();
-}
-
-/*!
- * Speichert ein Word im EEPROM.
- * @param addr Adresse im EEPROM zwischen 0 und 1023
- * @param value Das abzulegende Word
- */
-void eeprom_write_word(uint16_t * addr, uint16_t value) {
- uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
- if (address >= EE_SIZE-1) return;
- uint8_t * ptr = eeprom + address;
- *(uint16_t *)ptr = value;
- flush_eeprom_cache();
-}
-
-/*!
- * Kopiert einen Block vom RAM in das EEPROM
- * @param pointer_ram Adresse im RAM
- * @param pointer_eeprom Adresse im EEPROM
- * @param size Groesse des Blocks in Byte
- */
-void eeprom_write_block(const void *pointer_ram, void *pointer_eeprom, size_t size) {
- uint16_t address = conv_eeaddr(EEPROM_ADDR(pointer_eeprom));
- if (address+size >= EE_SIZE) return;
- uint8_t * ptr = eeprom + address;
- memcpy(ptr, pointer_ram, size);
- flush_eeprom_cache();
-}
-
-#endif // PC
+/*
+ * c't-Bot
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ */
+
+/*!
+ * @file eeprom-emu_pc.c
+ * @brief Low-Level Routinen fuer den Zugriff auf das emulierte EEPROM des Sim-c't-Bots
+ * @author Achim Pankalla (achim.pankalla@xxxxxx)
+ * @date 07.06.2007
+ */
+
+// Post-Build AVR:
+// avr-objcopy -O ihex -R .eeprom ct-Bot.elf ct-Bot.hex; avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex ct-Bot.elf ct-Bot.eep; avr-size ct-Bot.elf; avr-objdump -t ct-Bot.elf | grep "O \.eeprom" > eeprom_mcu.map
+
+// Post-Build Linux:
+// objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary ct-Bot.elf ct-Bot.eep; objdump -t -j .eeprom -C ct-Bot.elf | grep "g" > eeprom_pc.map
+
+// Post-Build Mac OS X:
+// objcopy -j LC_SEGMENT.__DATA..eeprom --change-section-lma LC_SEGMENT.__DATA..eeprom=0 -O binary ct-Bot ct-Bot.eep; objdump -t -j LC_SEGMENT.__DATA..s2eeprom -C ct-Bot | grep "g" > eeprom_pc.map
+
+// Post-Build Windows:
+// objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary ct-Bot.exe ct-Bot.eep;objdump -t ct-Bot.exe | grep "(sec 5)" | grep "(nx 0)" > eeprom_pc.map
+
+
+#include "ct-Bot.h"
+
+#ifdef PC
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "log.h"
+#include "gui.h"
+
+//#define DEBUG_EEPROM // Schalter um LOG-Ausgaben anzumachen
+
+#ifndef DEBUG_EEPROM
+ #undef LOG_INFO
+ #define LOG_INFO(a, ...) {}
+#endif
+
+extern uint8 __attribute__ ((section (".s1eeprom"),aligned(1))) _eeprom_start1__;
+extern uint8 __attribute__ ((section (".s2eeprom"),aligned(1))) _eeprom_start2__;
+
+/*! Normiert PC EEPROM Adressen*/
+#define EEPROM_ADDR(x) ((uint32)x - (uint32)&_eeprom_start2__ - ((uint32)&_eeprom_start2__ - (uint32)&_eeprom_start1__))
+/*! Makros zum Mitloggen von EEPROM Zugriffen*/
+#define LOG_LOAD if(addrconv) {LOG_DEBUG("LOAD:%s : %u", ctab[lastctabi].varname, eeprom[address]);}\
+ else {LOG_DEBUG("load-addr=0x%x/%u", address, eeprom[address]);}
+#define LOG_STORE if(addrconv) {LOG_DEBUG("STORE:%s : %d", ctab[lastctabi].varname, value);}\
+ else {LOG_DEBUG("load-addr=0x%x/%d", address, value);}
+
+/*! Positionen der Daten in den Map-Dateien */
+#ifdef WIN32
+ #define SADDR_POS 54 /*!< Pos. der Adresse in PC Map Datei */
+ #define SNAME_POS 60 /*!< Pos. des Variablennamen ohne _ */
+ #define BADDR_POS 0 /*!< Pos. der Adresse in MCU Map Datei */
+ #define BNAME_POS 34 /*!< Pos. des Variablennamen in MCU Map */
+ #define BSIZE_POS 28 /*!< Pos. der Variablengroesse in MCU Map */
+#endif
+#ifdef __linux__
+ #define SADDR_POS 0 /*!< Pos. der Adresse in PC Map Datei */
+ #define SNAME_POS 46 /*!< Pos. des Variablennamen ohne _ */
+ #define BADDR_POS 0 /*!< Pos. der Adresse in MCU Map Datei */
+ #define BNAME_POS 34 /*!< Pos. des Variablennamen in MCU Map */
+ #define BSIZE_POS 28 /*!< Pos. der Variablengroesse in MCU Map */
+#endif
+#ifdef __APPLE__
+ #define SADDR_POS 0 /*!< Pos. der Adresse in PC Map Datei */
+ #define SNAME_POS 45 /*!< Pos. des Variablennamen ohne _ */
+ #define BADDR_POS 0 /*!< Pos. der Adresse in MCU Map Datei */
+ #define BNAME_POS 34 /*!< Pos. des Variablennamen in MCU Map */
+ #define BSIZE_POS 28 /*!< Pos. der Variablengroesse in MCU Map */
+#endif
+
+#ifdef __AVR_ATmega644__ // Dieser Prozessor hat 2048 Bytes EEPROM
+ #define EE_SIZE 2048
+#else
+ #define EE_SIZE 1024
+#endif
+
+#define MCU_EEPROM_FN "./mcu_eeprom.bin" /*!< Name und Pfad der EEPROM Datei fuer MCU-Modus*/
+#define PC_EEPROM_FN "./pc_eeprom.bin" /*!< Name und Pfad der EEPROM Datei fuer PC-Modus*/
+#define MAX_VAR 200 /*!< Maximale Anzahl von Variablen*/
+#define EEMAP_PC "./eeprom_pc.map" /*!< Pfad fuer PC-MAP Datei */
+#define EEP_PC "./ct-Bot.eep" /*!< Pfad fuer PC-EEP Datei */
+#ifdef WIN32
+ /* Windows */
+ #define EEMAP_MCU "../debug-mcu-w32/eeprom_mcu.map" /*!< Pfad fuer MCU MAP Datei */
+#else
+ /* Linux und OS X */
+ #define EEMAP_MCU "../Debug-MCU-Linux/eeprom_mcu.map" /*!< Pfad fuer MCU MAP Datei */
+#endif
+
+typedef struct addrtab {
+ char varname[30];
+ size_t simaddr;
+ size_t botaddr;
+ uint16_t size;
+// uint32 access; // ??? wird nie ausgewertet
+} AddrCTab_t; /*!< Spezieller Datentyp fuer Adresskonvertierung */
+
+static AddrCTab_t ctab[MAX_VAR]; /*!< Adresskonvertierungstabelle */
+static uint16 tsize=0; /*!< Anzahl Eintraege in der Tabelle */
+static uint16 esize=0; /*!< Summe der EEPROM Variablen */
+static uint8 addrconv = 0; /*!< Adresskonvertierung ein-/ausschalten */
+static uint16 lastctabi = 0; /*!< Letzter Zugriffsindex auf ctab */
+static uint8 eeprom[EE_SIZE]; /*!< EEPROM Speicher im RAM */
+static FILE * ee_file; /*!< Zeiger auf EEPROM-Datei */
+
+/*!
+ * Diese Funktion konvertiert die Adressen der EEPROM Variablen des PC so,
+ * dass sie den Adressen im realen ct-Bot entsprechen. Dafuer wird mit der Funktion
+ * create_ctab ein Adresstabelle angelegt, diese nutzt diese Funktion.
+ * @param addr Adresse im EEPROM zwischen 0 und EE_SIZE-1
+ * @return Die neue Adresse fuer den realen Bot
+ */
+static uint32 conv_eeaddr(uint32 addr){
+ int8 i;
+ int32 adiff;
+
+ if(!addrconv) //Keine Adresskonvertierung
+ return(addr);
+ for(i=0; i<tsize; i++){
+ adiff = addr - ctab[i].simaddr;
+ if(adiff < 0)
+ return(0xfffffffe);
+ if(adiff < ctab[i].size){
+ lastctabi = i; //Letzer guelten Index merken
+ return(ctab[i].botaddr + adiff);
+ }
+ }
+ return(0xffffffff);
+}
+
+/*!
+ * Diese Funktion uberprueft das vorhanden sein der eeprom.bin und initialisiert sie
+ * gegebenenfalls mit der Initwerten der eep Datei.
+ * Es wird dabei die Adresskovertierung benutzt, wenn die EEPROM Simulation im MCU-Modus
+ * ist.
+ * -----
+ * 0 = EEPROM Datei OK
+ * 1 = Fehler aufgetreten
+ * -----
+ * @param initfile EEP-Datei des PC Codes
+ * @param eeprom_init Flag fuer Initialisierung (1 ja, 0 nein)
+ * @param fn Dateiname der EEPROM-Datei
+ * @return Status der Funktion
+ */
+static uint16 check_eeprom_file(char *initfile, uint8_t eeprom_init, char *fn){
+ FILE *fpr, *fpw; //Filepointer fuer Dateizugriffe
+ uint16 i; //Laufvariable
+ char data[2]; //Datenspeicher
+
+ /*eeprom file vorhanden*/
+ if(!(fpw = fopen(fn, "r+b"))){ //Testen, ob Datei vorhanden ist.
+ if(!(fpw = fopen(fn, "w+b"))){ //wenn nicht, dann erstellen
+ LOG_INFO("->Kann EEPROM-Datei nicht erstellen");
+ return(1);
+ }
+ if(!addrconv) {
+ /* EEPROM mit .eeprom-Section des .elf-Files initialisieren, wenn PC Modus */
+ uint8_t * ram_dump = (uint8_t *)(&_eeprom_start2__ + (&_eeprom_start2__ - &_eeprom_start1__));
+ fwrite(ram_dump, EE_SIZE, 1, fpw);
+ LOG_INFO("->Initialsierte EEPROM-Datei erstellt");
+ } else {
+ /* alternativ: leeres EEPROM erstellen und init setzen bei MCU Modus*/
+ for(i = 0; i < EE_SIZE; i++)
+ fwrite("\377", 1, 1, fpw);
+ eeprom_init = 1;
+ LOG_INFO("->Leere EEPROM-Datei erstellt");
+ }
+
+ fclose(fpw);
+ }
+
+ /*Initialsieren der eeprom.bin, wenn gewuenscht*/
+ if(eeprom_init){
+ if(!(fpr = fopen(initfile, "rb"))){ //Datei oeffnen
+ LOG_INFO("->EEP nicht gefunden");
+ return(1);
+ }
+ if(!(fpw = fopen(fn, "rb+"))){ //Datei oeffnen
+ LOG_INFO("->EEPROM-Datei kann nicht beschrieben werden");
+ return(1);
+ }
+
+ /*EEP-Datei in EEPROM-Datei kopieren*/
+ for(i=0; i<EE_SIZE; i++){
+ /*Daten kopieren*/
+ if(!fread(data, 1, 1, fpr))
+ break;
+ if(addrconv){ //EEPROM-Datei im MCU-Modus
+ uint32 naddr;//Konvertierte Adresse
+
+ naddr = conv_eeaddr((uint32)i);
+ if(naddr < 0xfffffffe){
+ fseek(fpw, (int32)naddr, SEEK_SET);
+ }
+ else{
+ continue; //Nichts schreiben Adresse nicht belegt
+ }
+ }
+ fwrite(data, 1, 1, fpw);
+ }
+ fclose(fpr);
+ fclose(fpw);
+ LOG_INFO("->EEPROM-Datei mit Daten init.");
+ }
+ return(0);
+}
+
+/*!
+ * Diese Funktion erstellt aus den beiden im Post erstellten MAP Dateien eine Tabelle
+ * zum umrechnen der PC-Adressen in die des avr-Compilers. Dadurch kann die EEPROM
+ * Datei in einen zum EEPROM des Bot kompatiblen Format gehalten werden.
+ * Wichtige Informationen werden ueber LOG_INFO angezeigt.
+ * ----
+ * Ergebniscodes der Funktion
+ * 0 = Fehlerfrei
+ * 1 = Sim Mapfile nicht vorhanden
+ * 2 = Bot Mapfile nicht vorhanden
+ * 3 = Unterschiedlicher Variablenbestand
+ * 4 = Zuviele Variablen
+ * 5 = EEPROM voll
+ * 6 = Unterschiedliche Variablenanzahl
+ *
+ * @param simfile MAP mit den Adressen der EEPROM-Variablen in der PC exe/elf
+ * @param botfile MAP mit den Adressen der EEPROM-Variablen im MCU elf
+ * @return Statuscode
+ */
+static uint16 create_ctab(char *simfile, char *botfile){
+ FILE *fps, *fpb;
+ char sline[250], bline[250]; //Textzeilen aus Dateien
+ char vname_s[30], vname_b[30]; //Variablennamen
+ size_t addr_s, addr_b; //Adressen der Variablen
+ uint16_t size; //Variablengroesse
+ uint16 vc = 0; //Variablenzaehler
+ size_t first_botaddr = 0xffffffff; //Erste ct-bot EEPROM Adressse
+
+ /*Dateien oeffnen*/
+ if(!(fps=fopen(simfile,"r"))){
+ LOG_INFO("->EEPROM-MAP fuer PC fehlt");
+ return(1);
+ }
+ if(!(fpb=fopen(botfile,"r"))){
+ LOG_INFO("->EEPROM-MAP fuer MCU fehlt");
+ return(2);
+ }
+
+ /*Anzahl Variablen vergleichen*/
+ while(fgets(sline, 249, fps)) vc++;
+ while(fgets(sline, 249, fpb)) vc--;
+ if(vc){
+ fclose(fps);
+ fclose(fpb);
+ LOG_INFO("->Unterschiedliche Variablenanzahl");
+ return(6);
+ }
+ rewind(fps);
+ rewind(fpb);
+
+ /*Tabelle erstellen*/
+ while(fgets(sline, 249, fps)){
+ rewind(fpb);
+ sscanf(&sline[SNAME_POS], "%s", vname_s);
+// printf("vname_s=%s\n", vname_s);
+ addr_s = strtol(&sline[SADDR_POS], NULL, 16);
+// printf("addr_s=0x%lx\n", addr_s);
+ while(fgets(bline, 249, fpb)){
+ /*Variablennamen suchen*/
+ sscanf(&bline[BNAME_POS], "%s", vname_b);
+// printf("vname_b=%s\n", vname_b);
+ addr_b = strtol(&bline[BADDR_POS], NULL, 16);
+// printf("addr_b=0x%lx\n", addr_b);
+ if(addr_b < first_botaddr)//Kleinste ct-bot Adresse bestimmen
+ first_botaddr = addr_b;
+ size = strtol(&bline[BSIZE_POS], NULL, 16);
+// printf("size=0x%x\n", size);
+
+ if(!strcmp(vname_s, vname_b)){
+ /*Daten kopieren*/
+ strcpy(ctab[tsize].varname, vname_b);
+ ctab[tsize].simaddr = addr_s;
+ ctab[tsize].botaddr = addr_b;
+ ctab[tsize++].size = size;
+ //ctab[tsize++].access = 0; // ??? wird nie ausgewertet
+ esize += size;
+ /*Fehlerabbrueche*/
+ if(tsize == MAX_VAR){
+ LOG_INFO("->Mehr als %n Variablen",MAX_VAR);
+ return(4);
+ }
+ if(esize > EE_SIZE){
+ LOG_INFO("->EEPROM voll");
+ return(5);
+ }
+
+ /*Erfolg markieren*/
+ addr_b = -1;
+ break;
+ }
+ }
+ if(addr_b > -1){ //Keine passende Variable gefunden
+ LOG_INFO("->Unterschiedliche Variablen");
+ return(3);
+ }
+ }
+
+ /*Dateien schliessen*/
+ fclose(fps);
+ fclose(fpb);
+
+ /*Tabelle nach Sim-Adressen sortieren*/
+ uint16_t i, j;
+ for(j=tsize-1; j > 0; j--){
+ for(i=0; i < j; i++){
+ if(ctab[i].simaddr > ctab[i+1].simaddr){
+ size_t simaddr, botaddr, size;
+ char vname[30];
+
+ /*Daten umkopieren*/
+ strcpy(vname, ctab[i+1].varname);
+ simaddr = ctab[i+1].simaddr;
+ botaddr = ctab[i+1].botaddr;
+ size = ctab[i+1].size;
+
+ strcpy(ctab[i+1].varname, ctab[i].varname);
+ ctab[i+1].simaddr = ctab[i].simaddr;
+ ctab[i+1].botaddr = ctab[i].botaddr;
+ ctab[i+1].size = ctab[i].size;
+
+ strcpy(ctab[i].varname, vname);
+ ctab[i].simaddr = simaddr;
+ ctab[i].botaddr = botaddr;
+ ctab[i].size = size;
+ }
+ }
+ }
+
+ /*Die EEPROM-Startadressen vom ct-bot und/oder Ct-Sim auf Null normieren*/
+ size_t first_simaddr = ctab[0].simaddr;
+ if(first_simaddr || first_botaddr) {
+ LOG_INFO("->Adressen werden normiert");
+ for(i=0; i<tsize; i++){
+ if(first_simaddr) ctab[i].simaddr -= first_simaddr;
+ if(first_botaddr) ctab[i].botaddr -= first_botaddr;
+// printf("addr_b=0x%x addr_b=0x%x\n", ctab[i].botaddr, ctab[i].simaddr);
+ }
+ }
+
+// for (i=0; i<tsize; i++) {
+// printf("i=%u\n", i);
+// printf("varname=%s\n", ctab[i].varname);
+// printf("simaddr=0x%lx\n", ctab[i].simaddr);
+// printf("botaddr=0x%lx\n", ctab[i].botaddr);
+// printf("size=0x%x\n\n", ctab[i].size);
+// }
+ return(0);
+}
+
+/*!
+ * Diese Funktion initialisiert die eeprom-emulation. Sie sorgt fuer die Erstellung der
+ * eeprom.bin, falls nicht vorhanden und erstellt ueber eine Hilfsfunktion eine Adress-
+ * konvertierungstabelle fuer die EEPROM-Adressen, wenn die benoetigten Daten vorliegen.
+ * Statusinformationen werden ueber DEBUG_INFO angezeigt.
+ * @param init gibt an, ob das EEPROM mit Hilfer einer eep-Datei initialisiert werden soll (0 nein, 1 ja)
+ * @return 0: alles ok, 1: Fehler
+ */
+uint8_t init_eeprom_man(uint8_t init) {
+ uint16 status; //Status von create_ctab
+ uint16 sflag; //Sectionstatus
+ char fn[30] = "";
+
+ LOG_INFO("EEPROM-Manager");
+
+ /*Adresskonvertierungstabelle anlegen*/
+ if((status=create_ctab(EEMAP_PC, EEMAP_MCU))){
+ LOG_INFO("->EEPROM im PC-Modus");
+ strcat(fn, PC_EEPROM_FN);
+ remove(MCU_EEPROM_FN);
+ }
+ else {
+ LOG_INFO("->EEPROM im MCU-Modus");
+ strcat(fn, MCU_EEPROM_FN);
+ remove(PC_EEPROM_FN);
+ addrconv = 1;
+ }
+
+ /*Sections ueberpruefen*/
+ if((&_eeprom_start2__ - &_eeprom_start1__) > 0 && (&resetsEEPROM - &_eeprom_start2__) >0){
+ LOG_INFO("->Sections liegen wohl korrekt");
+ LOG_INFO("->Section Abstand 0x%X", (&_eeprom_start2__ - &_eeprom_start1__));
+ sflag = 0;
+ }
+ else{
+ LOG_INFO("->Sections liegen falsch");
+ sflag = 1;
+ }
+
+ /*eeprom.bin checken*/
+ if(sflag || check_eeprom_file(EEP_PC, init, fn)){
+ LOG_INFO("EEPROM-Emulation fehlerhaft");
+ return 1;
+ }
+ else{
+ LOG_INFO("->EEPROM Groesse: %d Bytes", EE_SIZE);
+ if(addrconv)
+ LOG_INFO("->Belegter EEPROM Speicher: %d Bytes", esize);
+ LOG_INFO("EEPROM-Emulation einsatzbereit");
+ }
+
+ if((ee_file = fopen(fn, "r+b")) == NULL) return 1;
+ if (fread(eeprom, 1, EE_SIZE, ee_file) != EE_SIZE) return 1;
+ return 0;
+}
+
+/*!
+ * Schreibt den kompletten Inhalt des EEPROM-Caches in die Datei zurueck
+ */
+static inline void flush_eeprom_cache(void) {
+ fseek(ee_file, 0, SEEK_SET);
+ fwrite(eeprom, 1, EE_SIZE, ee_file);
+ fflush(ee_file);
+}
+
+/*!
+ * Laedt ein Byte aus dem EEPROM.
+ * @param addr Adresse im EEPROM zwischen 0 und 1023
+ * @return Wert der Speicheraddresse im EEPROM
+ */
+uint8_t eeprom_read_byte(const uint8_t * addr) {
+ uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
+ if (address >= EE_SIZE) return 0xff;
+ return eeprom[address];
+}
+
+/*!
+ * Laedt ein Word aus dem EEPROM.
+ * @param addr Adresse im EEPROM zwischen 0 und 1023
+ * @return Wert der Speicheraddresse im EEPROM
+ */
+uint16_t eeprom_read_word(const uint16_t * addr) {
+ uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
+ if (address >= EE_SIZE-1) return 0xffff;
+ uint8_t * ptr = eeprom + address;
+ return *(uint16_t *)ptr;
+}
+
+/*!
+ * Kopiert einen Block aus dem EEPROM ins RAM
+ * @param pointer_ram Adresse im RAM
+ * @param pointer_eeprom Adresse im EEPROM
+ * @param size Groesse des Blocks in Byte
+ */
+void eeprom_read_block(void *pointer_ram, const void *pointer_eeprom, size_t size) {
+ uint16_t address = conv_eeaddr(EEPROM_ADDR(pointer_eeprom));
+ if (address+size >= EE_SIZE) return;
+ uint8_t * ptr = eeprom + address;
+ memcpy(pointer_ram, ptr, size);
+}
+
+/*!
+ * Speichert ein Byte im EEPROM.
+ * @param addr Adresse im EEPROM zwischen 0 und 1023
+ * @param value Das abzulegende Byte
+ */
+void eeprom_write_byte(uint8_t * addr, uint8_t value) {
+ uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
+ if (address >= EE_SIZE) return;
+ eeprom[address] = value;
+ flush_eeprom_cache();
+}
+
+/*!
+ * Speichert ein Word im EEPROM.
+ * @param addr Adresse im EEPROM zwischen 0 und 1023
+ * @param value Das abzulegende Word
+ */
+void eeprom_write_word(uint16_t * addr, uint16_t value) {
+ uint16_t address = conv_eeaddr(EEPROM_ADDR(addr));
+ if (address >= EE_SIZE-1) return;
+ uint8_t * ptr = eeprom + address;
+ *(uint16_t *)ptr = value;
+ flush_eeprom_cache();
+}
+
+/*!
+ * Kopiert einen Block vom RAM in das EEPROM
+ * @param pointer_ram Adresse im RAM
+ * @param pointer_eeprom Adresse im EEPROM
+ * @param size Groesse des Blocks in Byte
+ */
+void eeprom_write_block(const void *pointer_ram, void *pointer_eeprom, size_t size) {
+ uint16_t address = conv_eeaddr(EEPROM_ADDR(pointer_eeprom));
+ if (address+size >= EE_SIZE) return;
+ uint8_t * ptr = eeprom + address;
+ memcpy(ptr, pointer_ram, size);
+ flush_eeprom_cache();
+}
+
+#endif // PC
Index: E:/eclipse/ct-bot devel/ct-Bot/Changelog.txt
===================================================================
--- E:/eclipse/ct-bot devel/ct-Bot/Changelog.txt (revision 1247)
+++ E:/eclipse/ct-bot devel/ct-Bot/Changelog.txt (working copy)
@@ -1,5 +1,7 @@
CHANGELOG fuer c't-Bot
======================
+2007-09-17 Achim Pankalla [achim.pankalla@xxxxxx]: EEPROM Datei wird nun nach Moduswechsel geloescht. Modus an Dateinamen erkennbar. (#143)
+
2007-09-16 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bugfix fuer Liniensensoren
2007-09-13 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bugfix in log.h (#144)
Index: E:/eclipse/ct-bot devel/ct-Bot/Documentation/eeprom-simulation.html
===================================================================
--- E:/eclipse/ct-bot devel/ct-Bot/Documentation/eeprom-simulation.html (revision 1247)
+++ E:/eclipse/ct-bot devel/ct-Bot/Documentation/eeprom-simulation.html (working copy)
@@ -1,254 +1,455 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <meta http-equiv="CONTENT-TYPE" content="text/html; charset=windows-1252">
- <title></title>
- <meta name="GENERATOR" content="OpenOffice.org 2.2 (Win32)">
- <meta name="AUTHOR" content="Achim Pankalla">
- <meta name="CREATED" content="20060528;19455600">
- <meta name="CHANGEDBY" content="Achim Pankalla">
- <meta name="CHANGED" content="20070617;18142584">
- <style type="text/css">
- <!--
- @page { size: 21cm 29.7cm; margin: 2cm }
- P { margin-bottom: 0.21cm }
- -->
- </style>
-</head>
-
-<body dir="ltr" lang="de-DE">
-
-<p style="margin-bottom: 0cm; font-family: Times New Roman;" align="center"><font size="+1"><b>EEPROM Emulation für
-PC</b></font></p>
-<p style="margin-bottom: 0cm; text-align: center;"><font size="3"><b><small>Version 1 18-Jul-2007</small></b><br>
-Achim Pankalla
-(achim.pankalla@xxxxxx)</font></p>
-<p style="margin-bottom: 0cm; height: 0px;"><br>
-</p>
-
-<p style="margin-bottom: 0cm; font-style: normal; text-align: justify;"></p>
-<div style="text-align: center;"><b>Beschreibung</b><br>
-<div style="text-align: justify;">Die
-EEPROM Emulation für den PC stellt das EEPROM des <i>Atmel
-MEGA32(644) Prozessors</i> 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 <span style="font-style: italic;">#ifdef</span>'s ist also nicht notwendig.<br>
-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.</div>
-</div>
-<p style="margin-bottom: 0cm;" align="left"><br>
-</p>
-
-<p style="margin-bottom: 0cm; text-align: center;"><b>Implementierung</b><br>
-</p>
-<div style="text-align: justify;">Alle Funktionen und Einstellungen der
-EEPROM Emulation findet Sie in den Dateien <i>pc/eeprom-emu_pc.c</i>
-und <i>include/eeprom-emu.h</i>. 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 befindet sich in der
-Konstanten <span style="font-style: italic;">EEPROM_FILENAME</span> in der C-Datei. Standard Pfad ist das Heimatverzeichnis des
-ct-Bots.<font color="#000000"><font face="Courier New, monospace"><font size="2"></font></font></font>
-<font face="Times New Roman, serif">Der Name </font><font face="Times New Roman, serif"><i>eeprom.bin</i></font>
-<font face="Times New Roman, serif">sollte belassen werden.</font><br>
-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 <span style="font-style: italic;">eeprom.bin</span> vorhanden, so wird diese nicht verändert, ausser die ct-Bot.exe wird mit dem Parameter <span style="font-style: italic;">-i</span> gestartet, dann wird auch eine schon vorhandene Datei mit den vorhandenen Zuweisungen überschrieben.<br>
-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. <br>
-Dafür gibt es die beiden Variablen
-<i>_eeprom_start1__</i> und <i>_eeprom_start2_</i><span style="font-style: normal;">_
-in </span><i>1st_init.S</i><span style="font-style: normal;">. Diese
-stehen dort, damit sie auf jeden Fall vor der ersten EEPROM Variable
-definiert werden und damit ihre Sections (.</span><i>s1eeprom</i> <span style="font-style: normal;">+
-.</span><i>s2eeprom</i><span style="font-style: normal;">) auf jeden
-Fall vor der Section .</span><i>eeprom</i> <span style="font-style: normal;">liegen.</span><br>
-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.<br>
-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 <span style="font-style: italic;">eeprom.bin</span> im MCU-Modus benutzen. Sollte keine <span style="font-style: italic;">eeprom.bin</span> existieren, wird sie auch dafür genutzt. Arbeitet man im PC-Modus, kann diese Datei auch in eeprom.bin umbenannt werden.<br>
-Damit die Emulation möglichst effektiv und schnell arbeiten kann, wird nach dem Start die gesamte Datei <span style="font-style: italic;">eeprom.bin</span> im Hauptspeicher gecached und nach jedem Schreibzugriff komplett neu geschrieben.<br>
-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.</div>
-
-<p style="margin-bottom: 0cm;"></p>
-<div style="text-align: center;"><b>Nutzung der EEPROM Emulation</b><br>
-<div style="text-align: justify;">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 Konstante EEPROM_FILENAME in <i>eeprom</i>-<i>emu</i>_<i>pc</i>.<i>c</i>
-festgelegt. <br>
-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 <i>ct-bot.eep</i> Datei im PC-Modus genutzt, ist
-dies natürlich nicht notwendig. <br>
-Alle wichtigen Informationen werden
-beim Start von ct-Bot.exe/elf im Log-Fenster angezeigt, vorrausgesetzt es ist in <span style="font-style: italic;">ct-bot.h</span> aktiviert ist (zusätzlich bitte in <span style="font-style: italic;">eeprom-emu_pc.c</span> die Konstante <span style="font-style: italic;">DEBUG_EEPROM</span>
-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.</div>
-</div>
-<p style="margin-bottom: 0cm;">Generell unterscheidet die Emulation
-zwei Modi:</p>
-<ol>
- <li>
- <p style="margin-bottom: 0cm;">PC-Modus<br>
-In diesen Modus entspricht die
- <span style="font-style: italic;">eeprom.bin</span> 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 <span style="font-style: italic;">ct-bot.eep</span> im Binärformat erstellt wird,
- so kann diese direkt benutzt werden.</p>
- </li>
- <li>
-
- <p style="margin-bottom: 0cm;">MCU-Modus<br>
-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 <span style="font-style: italic;">eeprom.bin</span> auf dem ct-Bot aufgespielen.<br>
-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 <span style="font-style: italic;">eeprom-emu_pc.c</span> ausgeführt werden.</p>
-In den Projekteinstellungen im SVN sind die nötigen Post-Build-Einstellungen für alle Betriebssysteme bereits gemacht.
- <br>
- </li>
-</ol>
-
-<p style="margin-bottom: 0cm; text-align: justify;">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>-i
-</i>starten, dabei spielt es keine Rolle in welchen Modus die
-Emulation arbeitet. Der Pfad der EEP-Datei wird in der Konstante
-<font color="#000000"><font face="Courier New, monospace"><font size="2">EEP_PC
- </font></font></font><font color="#000000"><font face="Times New Roman, serif"><font size="3">und die Pfade für die MAP-Dateien werden in den Konstanten EEMAP_PC und EEMAP_MCU eingetragen.<br>
-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. <br>
-</font></font></font></p>
-<font color="#000000"><font face="Times New Roman, serif"><font size="3">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.</font></font></font>
-<p style="margin-bottom: 0cm;"></p>
-
-<div style="text-align: center;"><b>Grenzen der
-Implementierung</b><br>
-<div style="text-align: justify;">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 <span style="font-style: italic;">eeprom.bin</span> 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 <span style="font-style: italic;">objdump</span> 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 <span style="font-style: italic;">Projekt->clean</span> aufrufen.<br>
-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. </div>
-</div>
-
-<p style="margin-bottom: 0cm;"></p>
-<div style="text-align: center;"><span style="font-weight: bold;">Verschiedenes</span><br>
-<div style="text-align: justify;">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.<br>
-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. <br>
-Möge sich jeder eingeladen fühlen etwas zu verbessern oder erweitern.<br>
-
-</div>
-</div>
-
-<p style="margin-bottom: 0cm;"><b>Funktionen</b><br>
-init_eeprom_man() - Erledigt alle Arbeiten zur Aktivierung der EEPROM-Emulation<br>
-</p>
-<p style="margin-bottom: 0cm;"><b>Nur in eeprom-emu_pc.c sichtbare
-Funktionen</b></p>
-conv_eeaddr() - Wandelt PC Adresse in
-ct-Bot Adresse<br>
-create_ctab() - Erstellt
-Adresskonvertierungstabelle<br>
-check_eeprom_file() - Erstellt leeres
-EEPROM, wenn nötig und initialisiert es, wenn gewünscht<br>
-flush_eeprom_cache() - Schreibt veränderte Daten in eeprom.bin<br>
-
-<p style="margin-bottom: 0cm;"><b>Zugriffsfunktionen für den PC
-(identisch zu denen der avr-libc)</b><br>
-eeprom_read_byte()<br>
-eeprom_write_byte()<br>
-eeprom_read_word()<br>
-eeprom_write_word()<br>
-eeprom_write_block()<br>
-eeprom_read_block()</p>
-
-<p style="margin-bottom: 0cm;"><font size="3"><b>Dateien</b></font><br>
-</p>
-<div style="text-align: center;">
-<div style="text-align: left;">eeprom-emu.h - Headerdatei mit den Deklarationen<br>
-eeprom-emu_pc.c - Implementierung der Funktionen
-für ct-Bot & ct-Sim<br>
-<font size="3">1st_init.S - Sorgt für das korrekte Anlegen der Hilfsvariablen in der Exe</font></div>
-</div>
-<p style="margin-bottom: 0cm;"><br>
-</p>
-<p style="margin-bottom: 0cm;"><br>
-</p>
-<p style="margin-bottom: 0cm;"><br>
-</p>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+
+
+
+
+ <meta http-equiv="CONTENT-TYPE" content="text/html; charset=windows-1252">
+
+
+
+
+
+
+ <title></title>
+ <meta name="GENERATOR" content="OpenOffice.org 2.2 (Win32)">
+
+
+
+
+ <meta name="AUTHOR" content="Achim Pankalla">
+
+
+
+
+ <meta name="CREATED" content="20060528;19455600">
+
+
+
+
+ <meta name="CHANGEDBY" content="Achim Pankalla">
+
+
+
+
+ <meta name="CHANGED" content="20070617;18142584">
+
+
+
+
+ <style type="text/css">
+ <!--
+ @page { size: 21cm 29.7cm; margin: 2cm }
+ P { margin-bottom: 0.21cm }
+ -->
+ </style>
+</head>
+
+
+<body dir="ltr" lang="de-DE">
+
+
+
+<p style="margin-bottom: 0cm; font-family: Times New Roman;" align="center"><font size="+1"><b>EEPROM Emulation für
+PC</b></font></p>
+
+
+<p style="margin-bottom: 0cm; text-align: center;"><font size="3"><b><small>Version 1.1 17-Sep-2007</small></b><br>
+
+
+Achim Pankalla
+(achim.pankalla@xxxxxx)</font></p>
+
+
+<p style="margin-bottom: 0cm; height: 0px;"><br>
+
+
+</p>
+
+
+
+<p style="margin-bottom: 0cm; font-style: normal; text-align: justify;"></p>
+
+
+<div style="text-align: center;"><b>Beschreibung</b><br>
+
+
+<div style="text-align: justify;">Die
+EEPROM Emulation für den PC stellt das EEPROM des <i>Atmel
+MEGA32(644) Prozessors</i> 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 <span style="font-style: italic;">#ifdef</span>'s ist also nicht notwendig.<br>
+
+
+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.</div>
+
+
+</div>
+
+
+<p style="margin-bottom: 0cm;" align="left"><br>
+
+
+</p>
+
+
+
+<p style="margin-bottom: 0cm; text-align: center;"><b>Implementierung</b><br>
+
+
+</p>
+
+
+<div style="text-align: justify;">Alle Funktionen und Einstellungen der
+EEPROM Emulation findet Sie in den Dateien <i>pc/eeprom-emu_pc.c</i>
+und <i>include/eeprom-emu.h</i>. 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_)<span style="font-style: italic;">EEPROM_FN</span> in der C-Datei. Standard Pfad ist das Heimatverzeichnis des
+ct-Bots. <font face="Times New Roman, serif"></font><br>
+
+
+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 <span style="font-style: italic;">eeprom.bin</span> vorhanden, so wird diese nicht verändert, ausser die ct-Bot.exe wird mit dem Parameter <span style="font-style: italic;">-i</span> gestartet, dann wird auch eine schon vorhandene Datei mit den vorhandenen Zuweisungen überschrieben.<br>
+
+
+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. <br>
+
+
+Dafür gibt es die beiden Variablen
+<i>_eeprom_start1__</i> und <i>_eeprom_start2_</i><span style="font-style: normal;">_
+in </span><i>1st_init.S</i><span style="font-style: normal;">. Diese
+stehen dort, damit sie auf jeden Fall vor der ersten EEPROM Variable
+definiert werden und damit ihre Sections (.</span><i>s1eeprom</i> <span style="font-style: normal;">+
+.</span><i>s2eeprom</i><span style="font-style: normal;">) auf jeden
+Fall vor der Section .</span><i>eeprom</i> <span style="font-style: normal;">liegen.</span><br>
+
+
+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.<br>
+
+
+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 <span style="font-style: italic;">eeprom.bin</span> im MCU-Modus benutzen. Sollte keine <span style="font-style: italic;">eeprom.bin</span> existieren, wird sie auch dafür genutzt. Arbeitet man im PC-Modus, kann diese Datei auch in eeprom.bin umbenannt werden.<br>
+
+
+Damit die Emulation möglichst effektiv und schnell arbeiten kann, wird nach dem Start die gesamte Datei <span style="font-style: italic;">eeprom.bin</span> im Hauptspeicher gecached und nach jedem Schreibzugriff komplett neu geschrieben.<br>
+
+
+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.</div>
+
+
+
+<p style="margin-bottom: 0cm;"></p>
+
+
+<div style="text-align: center;"><b>Nutzung der EEPROM Emulation</b><br>
+
+
+<div style="text-align: justify;">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 <i>eeprom</i>-<i>emu</i>_<i>pc</i>.<i>c</i>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.<br>
+
+
+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 <i>ct-bot.eep</i> Datei im PC-Modus genutzt, ist
+dies natürlich nicht notwendig. <br>
+
+
+Alle wichtigen Informationen werden
+beim Start von ct-Bot.exe/elf im Log-Fenster angezeigt, vorrausgesetzt es ist in <span style="font-style: italic;">ct-bot.h</span> aktiviert ist (zusätzlich bitte in <span style="font-style: italic;">eeprom-emu_pc.c</span> die Konstante <span style="font-style: italic;">DEBUG_EEPROM</span>
+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.</div>
+
+
+</div>
+
+
+<p style="margin-bottom: 0cm;">Generell unterscheidet die Emulation
+zwei Modi:</p>
+
+
+<ol>
+
+
+ <li>
+
+
+ <p style="margin-bottom: 0cm;">PC-Modus<br>
+
+
+In diesen Modus entspricht die
+ <span style="font-style: italic;">eeprom.bin</span> 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 <span style="font-style: italic;">ct-bot.eep</span> im Binärformat erstellt wird,
+ so kann diese direkt benutzt werden.</p>
+
+
+ </li>
+
+
+ <li>
+
+
+
+ <p style="margin-bottom: 0cm;">MCU-Modus<br>
+
+
+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 <span style="font-style: italic;">eeprom.bin</span> auf dem ct-Bot aufgespielen.<br>
+
+
+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 <span style="font-style: italic;">eeprom-emu_pc.c</span> ausgeführt werden.</p>
+
+
+In den Projekteinstellungen im SVN sind die nötigen Post-Build-Einstellungen für alle Betriebssysteme bereits gemacht.
+ <br>
+
+
+ </li>
+
+
+</ol>
+
+
+
+<p style="margin-bottom: 0cm; text-align: justify;">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>-i
+</i>starten, dabei spielt es keine Rolle in welchen Modus die
+Emulation arbeitet. Der Pfad der EEP-Datei wird in der Konstante
+<font color="#000000"><font face="Courier New, monospace"><font size="2">EEP_PC
+ </font></font></font><font color="#000000"><font face="Times New Roman, serif"><font size="3">und die Pfade für die MAP-Dateien werden in den Konstanten EEMAP_PC und EEMAP_MCU eingetragen.<br>
+
+
+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. <br>
+
+
+</font></font></font></p>
+
+
+<font color="#000000"><font face="Times New Roman, serif"><font size="3">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.</font></font></font>
+<p style="margin-bottom: 0cm;"></p>
+
+
+
+<div style="text-align: center;"><b>Grenzen der
+Implementierung</b><br>
+
+
+<div style="text-align: justify;">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.
+<span style="color: rgb(0, 0, 0);">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 </span><span style="font-style: italic; color: rgb(0, 0, 0);">eeprom.bin</span><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 0, 0);"> bzw. auf dem Atmel das EEPROM löschen) und für MCU und ct-Sim neue Exe generiert werden</span>.</span>
+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 <span style="font-style: italic;">objdump</span> 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 <span style="font-style: italic;">Projekt->clean</span> aufrufen.<br>
+
+
+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. </div>
+
+
+</div>
+
+
+
+<p style="margin-bottom: 0cm;"></p>
+
+
+<div style="text-align: center;"><span style="font-weight: bold;">Verschiedenes</span><br>
+
+
+<div style="text-align: justify;">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.<br>
+
+
+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. <br>
+
+
+Möge sich jeder eingeladen fühlen etwas zu verbessern oder erweitern.<br>
+
+
+
+</div>
+
+
+</div>
+
+
+
+<p style="margin-bottom: 0cm;"><b>Funktionen</b><br>
+
+
+init_eeprom_man() - Erledigt alle Arbeiten zur Aktivierung der EEPROM-Emulation<br>
+
+
+</p>
+
+
+<p style="margin-bottom: 0cm;"><b>Nur in eeprom-emu_pc.c sichtbare
+Funktionen</b></p>
+
+
+conv_eeaddr() - Wandelt PC Adresse in
+ct-Bot Adresse<br>
+
+
+create_ctab() - Erstellt
+Adresskonvertierungstabelle<br>
+
+
+check_eeprom_file() - Erstellt leeres
+EEPROM, wenn nötig und initialisiert es, wenn gewünscht<br>
+
+
+flush_eeprom_cache() - Schreibt veränderte Daten in eeprom.bin<br>
+
+
+
+<p style="margin-bottom: 0cm;"><b>Zugriffsfunktionen für den PC
+(identisch zu denen der avr-libc)</b><br>
+
+
+eeprom_read_byte()<br>
+
+
+eeprom_write_byte()<br>
+
+
+eeprom_read_word()<br>
+
+
+eeprom_write_word()<br>
+
+
+eeprom_write_block()<br>
+
+
+eeprom_read_block()</p>
+
+
+
+<p style="margin-bottom: 0cm;"><font size="3"><b>Dateien</b></font><br>
+
+
+</p>
+
+
+<div style="text-align: center;">
+<div style="text-align: left;">eeprom-emu.h - Headerdatei mit den Deklarationen<br>
+
+
+eeprom-emu_pc.c - Implementierung der Funktionen
+für ct-Bot & ct-Sim<br>
+
+
+<font size="3">1st_init.S - Sorgt für das korrekte Anlegen der Hilfsvariablen in der Exe</font></div>
+
+
+</div>
+
+
+<p style="margin-bottom: 0cm;"><br>
+
+
+</p>
+
+
+<p style="margin-bottom: 0cm;"><br>
+
+
+</p>
+
+
+<p style="margin-bottom: 0cm;"><br>
+
+
+</p>
+
+
+</body>
+</html>
|
|
|