heise online · c't · iX · Technology Review · Telepolis · mobil · Security · Netze · heise open · heise resale · Autos · c't-TV · Jobs · Kiosk
Zum Inhalt
c't

c't Projekte - c't-Bot und c't-Sim - Mailinglisten

c't-Bot und c't-Sim


[Voriger (Datum)] [Nächster (Datum)] [Voriger (Thread)] [Nächster (Thread)]
[Nach Datum][Nach Thread]

Re: AW: AW: [ct-bot] EEPROM-Emu... -> Bug gefunden !

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&uuml;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&uuml;r den PC stellt das EEPROM des <i>Atmel
-MEGA32(644) Prozessors</i> auch dem ct-Sim zur Verf&uuml;gung.
-Der Zugriff auf dieses EEPROM erfolgt &uuml;ber gleichnamige
-Funktionen, wie sie auch die avr-libc bereitstellt und auch die
-Variablendefinition erfolgt &uuml;ber die gleichen Konstrukte. Eine
-Unterscheidung &uuml;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&auml;her gekommen und Programme mit EEPROM-Zugriffe k&ouml;nnen mit
-der Simulation getestet werden. Mehr noch, Sie k&ouml;nnen auch den
-Inhalt des emulierten EEPROM auf den ct-Bot &uuml;bertragen oder das
-EEPROM vom
-ct-Bot laden und f&uuml;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&auml;re Datei (genau 1 KB bzw. 2 KB gro&szlig;) repr&auml;sentiert&nbsp;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&auml;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 &uuml;berschrieben.<br>
-Damit die
-EEPROM-Funktionen des PC korrekt auf die Datei zugreifen k&ouml;nnen
-darf nur ein Adressraum von 0 bis 1023 (bzw. 2047) entstehen.&nbsp;Die
-Emulation muss also wissen welche Speicheradresse die
-erste Variable im EEPROM hat, um diesen Wert von allen anderen
-abzuziehen. Daf&uuml;r bedarf es bei
-der PC Implementierung (mit PC ist allgemein der Code f&uuml;r den
-ct-Sim gemeint, mag das OS nun Win, Linux oder Mac OS X hei&szlig;en)
-eines Tricks.&nbsp;<br>
-Daf&uuml;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&nbsp; die EEPROM-Emulation auch als Initialisierung f&uuml;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&uuml;r genutzt. Arbeitet man im PC-Modus, kann diese Datei auch in eeprom.bin umbenannt werden.<br>
-Damit die Emulation m&ouml;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 &nbsp;des ct-Bot als emuliertes EEPROM nutzen kann,
-werden Post-Builds ben&ouml;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&uuml;r den realen ct-Bot. 
-Nat&uuml;rlich hat der PC kein EEPROM, dieses wird durch
-eine&nbsp;Datei im Bin&auml;rformat emuliert. Der Dateinamen und der Pfad
-wird &uuml;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 &uuml;ber
-ein DEFINE der Prozessortyp festgelegt wird, entweder ATMega32 oder
-ATMega644. Dieses DEFINE ist beim PC Compiler normalerweise nicht
-gesetzt. Standardm&auml;&szlig;ig wird von einem ATMega32 mit
-1024 Byte EEPROM ausgegangen, Die Emulation kennt aber die Konstante
-f&uuml;r den ATMega644 und erh&ouml;ht den EEPROM Speicher auf 2048
-Bytes. Sollte schon eine 1 KB Datei f&uuml;rs EEPROM bestehen, so muss
-diese gel&ouml;scht werden, damit die Gr&ouml;&szlig;ere angelegt
-wird. Wird direkt die erstellte <i>ct-bot.eep</i> Datei im PC-Modus genutzt, ist
-dies nat&uuml;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&auml;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&auml;&szlig;
-arbeiten kann. Es erfolgt kein Beenden bei
-Problemen, die Funktion des EEPROMs ist dann aber nicht gegeben. Bei
-Auff&auml;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&ouml;tigt keine weiteren Eintr&auml;ge im Post-Build.&nbsp;Wenn eine <span style="font-style: italic;">ct-bot.eep</span> im Bin&auml;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&uuml;rlich, dass der Bot auch mit zuletzt
-	erstelltem Programm bespielt ist. Nat&uuml;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&uuml;r m&uuml;ssen im Post-Build die Befehle aus dem Kommentarkopf aus <span style="font-style: italic;">eeprom-emu_pc.c</span> ausgef&uuml;hrt werden.</p>
-In den Projekteinstellungen im SVN sind die n&ouml;tigen Post-Build-Einstellungen f&uuml;r alle Betriebssysteme bereits gemacht.
-	<br>
-  </li>
-</ol>
-
-<p style="margin-bottom: 0cm; text-align: justify;">M&ouml;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&uuml;r die MAP-Dateien werden in den Konstanten EEMAP_PC und EEMAP_MCU eingetragen.<br>
-Die Variable MAX_VAR legt die Gr&ouml;&szlig;e der Tabelle fest und
-beschr&auml;ngt damit die maximale Anzahl der Variablen. Sollte die
-Fehlermeldung auftreten, dass es zu viele Variablen gibt, muss man
-diesen Wert nur erh&ouml;hen. <br>
-</font></font></font></p>
-<font color="#000000"><font face="Times New Roman, serif"><font size="3">F&uuml;r
-das Debuggen von Zugriffen auf das EEPROM stehen unter anderem die
-DEFINES LOG_STORE und LOG_LOAD zur Verf&uuml;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 &uuml;berpr&uuml;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&uuml;hrt, damit dies kein Problem mehr
-ist. Es gibt aber keine Garantien daf&uuml;r, dass zuk&uuml;nftige Compiler
-Versionen nicht die Reihenfolge der Variablen im Code &auml;ndern.
-Ein Einf&uuml;gen neuer EEPROM Variablen kann auch zu Verschiebungen
-der Adressen f&uuml;hren. Nach solchen &Auml;nderungen (auch ein &auml;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&ouml;schen) und f&uuml;r MCU und ct-Sim neue Exe generiert werden.
-Einmal erstellte Werte sind dann nat&uuml;rlich futsch. Wenn man den
-Einfluss von Codeerg&auml;nzungen kontrollieren will, kann man dies
-vor und nach der &Auml;nderung mit <span style="font-style: italic;">objdump</span> machen (oder falls Sie
-die Befehle f&uuml;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&ouml;nnen dann sehen, ob
-die neuen Variablen nun hinten angeh&auml;ngt wurden (dann brauch das
-EEPROM nicht gel&ouml;scht werden) oder sie dazwischen gelandet sind
-(dann sind die alten Daten unbrauchbar), daf&uuml;r sollten sie aber
-vorher in Eclipse <span style="font-style: italic;">Projekt-&gt;clean</span> aufrufen.<br>
-Der Compiler kann aufgrund der Implementierung
-des EEPROMs auf dem PC nicht kontrollieren, ob mehr als 1024/2048 Bytes
-f&uuml;r die Variablen ben&ouml;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&uuml;r das Testen unter MacOSX und
-f&uuml;r verschiedene Anpassungen, Optimierungen und f&uuml;r den
-Assemblercode in 1st_init.S ohne den wohl st&auml;ndige Probleme
-unvermeidlich gewesen w&auml;ren.<br>
-Dank auch an alle anderen f&uuml;r konstruktive Kritik, die die
-jetzige, ich denke annehmbare, L&ouml;sung erst m&ouml;glich machte und
-meiner Familie f&uuml;r ihre unendliche Geduld. <br>
-M&ouml;ge sich jeder eingeladen f&uuml;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&ouml;tig und initialisiert es, wenn gew&uuml;nscht<br>
-flush_eeprom_cache() - Schreibt ver&auml;nderte Daten in eeprom.bin<br>
-
-<p style="margin-bottom: 0cm;"><b>Zugriffsfunktionen f&uuml;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&uuml;r ct-Bot &amp; ct-Sim<br>
-<font size="3">1st_init.S - Sorgt f&uuml;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&uuml;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&uuml;r den PC stellt das EEPROM des <i>Atmel
+MEGA32(644) Prozessors</i> auch dem ct-Sim zur Verf&uuml;gung.
+Der Zugriff auf dieses EEPROM erfolgt &uuml;ber gleichnamige
+Funktionen, wie sie auch die avr-libc bereitstellt und auch die
+Variablendefinition erfolgt &uuml;ber die gleichen Konstrukte. Eine
+Unterscheidung &uuml;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&auml;her gekommen und Programme mit EEPROM-Zugriffe k&ouml;nnen mit
+der Simulation getestet werden. Mehr noch, Sie k&ouml;nnen auch den
+Inhalt des emulierten EEPROM auf den ct-Bot &uuml;bertragen oder das
+EEPROM vom
+ct-Bot laden und f&uuml;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&auml;re Datei (genau 1 KB bzw. 2 KB gro&szlig;) repr&auml;sentiert&nbsp;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.&nbsp;<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&auml;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 &uuml;berschrieben.<br>
+
+
+Damit die
+EEPROM-Funktionen des PC korrekt auf die Datei zugreifen k&ouml;nnen
+darf nur ein Adressraum von 0 bis 1023 (bzw. 2047) entstehen.&nbsp;Die
+Emulation muss also wissen welche Speicheradresse die
+erste Variable im EEPROM hat, um diesen Wert von allen anderen
+abzuziehen. Daf&uuml;r bedarf es bei
+der PC Implementierung (mit PC ist allgemein der Code f&uuml;r den
+ct-Sim gemeint, mag das OS nun Win, Linux oder Mac OS X hei&szlig;en)
+eines Tricks.&nbsp;<br>
+
+
+Daf&uuml;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&nbsp; die EEPROM-Emulation auch als Initialisierung f&uuml;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&uuml;r genutzt. Arbeitet man im PC-Modus, kann diese Datei auch in eeprom.bin umbenannt werden.<br>
+
+
+Damit die Emulation m&ouml;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 &nbsp;des ct-Bot als emuliertes EEPROM nutzen kann,
+werden Post-Builds ben&ouml;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&uuml;r den realen ct-Bot. 
+Nat&uuml;rlich hat der PC kein EEPROM, dieses wird durch
+eine&nbsp;Datei im Bin&auml;rformat emuliert. Der Dateinamen und der Pfad
+wird &uuml;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&ouml;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 &uuml;ber
+ein DEFINE der Prozessortyp festgelegt wird, entweder ATMega32 oder
+ATMega644. Dieses DEFINE ist beim PC Compiler normalerweise nicht
+gesetzt. Standardm&auml;&szlig;ig wird von einem ATMega32 mit
+1024 Byte EEPROM ausgegangen, Die Emulation kennt aber die Konstante
+f&uuml;r den ATMega644 und erh&ouml;ht den EEPROM Speicher auf 2048
+Bytes. Sollte schon eine 1 KB Datei f&uuml;rs EEPROM bestehen, so muss
+diese gel&ouml;scht werden, damit die Gr&ouml;&szlig;ere angelegt
+wird. Wird direkt die erstellte <i>ct-bot.eep</i> Datei im PC-Modus genutzt, ist
+dies nat&uuml;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&auml;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&auml;&szlig;
+arbeiten kann. Es erfolgt kein Beenden bei
+Problemen, die Funktion des EEPROMs ist dann aber nicht gegeben. Bei
+Auff&auml;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&ouml;tigt keine weiteren Eintr&auml;ge im Post-Build.&nbsp;Wenn eine <span style="font-style: italic;">ct-bot.eep</span> im Bin&auml;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&uuml;rlich, dass der Bot auch mit zuletzt
+	erstelltem Programm bespielt ist. Nat&uuml;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&uuml;r m&uuml;ssen im Post-Build die Befehle aus dem Kommentarkopf aus <span style="font-style: italic;">eeprom-emu_pc.c</span> ausgef&uuml;hrt werden.</p>
+
+
+In den Projekteinstellungen im SVN sind die n&ouml;tigen Post-Build-Einstellungen f&uuml;r alle Betriebssysteme bereits gemacht.
+	<br>
+
+
+  </li>
+
+
+</ol>
+
+
+
+<p style="margin-bottom: 0cm; text-align: justify;">M&ouml;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&uuml;r die MAP-Dateien werden in den Konstanten EEMAP_PC und EEMAP_MCU eingetragen.<br>
+
+
+Die Variable MAX_VAR legt die Gr&ouml;&szlig;e der Tabelle fest und
+beschr&auml;ngt damit die maximale Anzahl der Variablen. Sollte die
+Fehlermeldung auftreten, dass es zu viele Variablen gibt, muss man
+diesen Wert nur erh&ouml;hen. <br>
+
+
+</font></font></font></p>
+
+
+<font color="#000000"><font face="Times New Roman, serif"><font size="3">F&uuml;r
+das Debuggen von Zugriffen auf das EEPROM stehen unter anderem die
+DEFINES LOG_STORE und LOG_LOAD zur Verf&uuml;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 &uuml;berpr&uuml;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&uuml;hrt, damit dies kein Problem mehr
+ist. Es gibt aber keine Garantien daf&uuml;r, dass zuk&uuml;nftige Compiler
+Versionen nicht die Reihenfolge der Variablen im Code &auml;ndern.
+<span style="color: rgb(0, 0, 0);">Ein Einf&uuml;gen neuer EEPROM Variablen kann auch zu Verschiebungen
+der Adressen f&uuml;hren. Nach solchen &Auml;nderungen (auch ein &auml;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&ouml;schen) und f&uuml;r MCU und ct-Sim neue Exe generiert werden</span>.</span>
+Einmal erstellte Werte sind dann nat&uuml;rlich futsch. Wenn man den
+Einfluss von Codeerg&auml;nzungen kontrollieren will, kann man dies
+vor und nach der &Auml;nderung mit <span style="font-style: italic;">objdump</span> machen (oder falls Sie
+die Befehle f&uuml;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&ouml;nnen dann sehen, ob
+die neuen Variablen nun hinten angeh&auml;ngt wurden (dann brauch das
+EEPROM nicht gel&ouml;scht werden) oder sie dazwischen gelandet sind
+(dann sind die alten Daten unbrauchbar), daf&uuml;r sollten sie aber
+vorher in Eclipse <span style="font-style: italic;">Projekt-&gt;clean</span> aufrufen.<br>
+
+
+Der Compiler kann aufgrund der Implementierung
+des EEPROMs auf dem PC nicht kontrollieren, ob mehr als 1024/2048 Bytes
+f&uuml;r die Variablen ben&ouml;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&uuml;r das Testen unter MacOSX und
+f&uuml;r verschiedene Anpassungen, Optimierungen und f&uuml;r den
+Assemblercode in 1st_init.S ohne den wohl st&auml;ndige Probleme
+unvermeidlich gewesen w&auml;ren.<br>
+
+
+Dank auch an alle anderen f&uuml;r konstruktive Kritik, die die
+jetzige, ich denke annehmbare, L&ouml;sung erst m&ouml;glich machte und
+meiner Familie f&uuml;r ihre unendliche Geduld. <br>
+
+
+M&ouml;ge sich jeder eingeladen f&uuml;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&ouml;tig und initialisiert es, wenn gew&uuml;nscht<br>
+
+
+flush_eeprom_cache() - Schreibt ver&auml;nderte Daten in eeprom.bin<br>
+
+
+
+<p style="margin-bottom: 0cm;"><b>Zugriffsfunktionen f&uuml;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&uuml;r ct-Bot &amp; ct-Sim<br>
+
+
+<font size="3">1st_init.S - Sorgt f&uuml;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>


Copyright © 2007 Heise Zeitschriften Verlag Kritik, Anregungen bitte an c't-WWW Datenschutzhinweis   Impressum