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>