## c't-Projekte - Mailinglisten

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

### Re: [ct-bot] EEPROM @ PC

Absender: Achim Pankalla
Datum: Di, 10.04.2007 15:48:39
In-reply-to: <2F019FD4-6C76-47CB-9A35-3BA48E476E50@xxxxxxxxxxxxxxx>
References: <BCF016D5ED5AC34FBB655D109519ABCF083EBE@xxxxxxxxxxxxxxxxxxxx> <45ED3B46.4030400@xxxxxx> <A1E61AA9-0BF2-4A89-B255-27EDD9BDECD2@xxxxxxxxxxxxxxx> <45EEAB88.1080901@xxxxxxxx> <2F019FD4-6C76-47CB-9A35-3BA48E476E50@xxxxxxxxxxxxxxx>

    hallo ct-bot'ler,

`anbei eine überarbeitete version meiner eeprom-simulation für den ct-bot` `unter ct-sim. es hat sich einiges getan, hier nur einige stichpunkte:`

    -auch block_read/write implementiert
    -eep datei wird erzeugt
    -tool für sim-eeprom patchen
    alles weiter findet ihr in der doku. die sollte man auch unbedingt lesen!

`nebenbei wurde noch die routine zum anzeigen der resets` `(TEST_AVAILABLE_COUNTER) entwanzt. ansonsten enthält dieser patch nur` `die eeprom-simulation und die anpassungen des vorhanden eeprom-kodes.` `die kalibrierroutine ist noch in arbeit.`

`an dieser stelle nochmal vielen dank an hr. benz und timo für die` `zahlreichen tipps und danke auch für die schnelle korrektur des` `typen-bug im pc von timo. funktioniert prima! ich hoffe sie findet bald` `eingang ins cvs.`

`da ich im moment nur unter win32 arbeite, wärs schön wenn jemand mit` `linux es mal testen könnte.`

    mit freundlichen grüssen
      achim pankalla

    /* Default linker script, for normal executables */
    OUTPUT_FORMAT(pei-i386)
    SEARCH_DIR("/mingw/mingw32/lib"); SEARCH_DIR("/mingw/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
    ENTRY(_mainCRTStartup)
    SECTIONS
    {
      .text  __image_base__ + __section_alignment__  :
      {
        *(.init)
        *(.text)
        *(SORT(.text$*))
        *(.glue_7t)
        *(.glue_7)
       	___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
    			LONG (-1);
    			*(EXCLUDE_FILE (*crtend.o) .ctors);
    			*(.ctor);
    			*(SORT(.ctors.*));
    			*crtend.o (.ctors);
    			LONG (0);
        	___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
    			LONG (-1);
    			*(EXCLUDE_FILE (*crtend.o) .dtors);
    			*(.dtor);
    			*(SORT(.dtors.*));
    			*crtend.o (.dtors);
    			LONG (0);
         *(.fini)
        /* ??? Why is .gcc_exc here?  */
         *(.gcc_exc)
        *(.gcc_except_table)
      }
      /* The Cygwin32 library uses a section to avoid copying certain data
         on fork.  This used to be named ".data".  The linker used
         to include this between __data_start__ and __data_end__, but that
         breaks building the cygwin32 dll.  Instead, we name the section
         ".data_cygwin_nocopy" and explictly include it after __data_end__. */
      .data BLOCK(__section_alignment__) :
      {
        __data_start__ = . ;
        *(.data)
        *(.data2)
        *(SORT(.data$*))
        __data_end__ = . ;
        *(.data_cygwin_nocopy)
      }
      .eeprom BLOCK(__section_alignment__) :
      {
        __eeprom_start__ = . ;
        *(.eeprom)
        *(.eeprom_cygwin_nocopy)
      } =0xff
      .rdata BLOCK(__section_alignment__) :
      {
        *(.rdata)
        *(SORT(.rdata$*))
        *(.eh_frame)
        ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
        __RUNTIME_PSEUDO_RELOC_LIST__ = .;
        *(.rdata_runtime_pseudo_reloc)
        ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
        __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
      }
      .pdata BLOCK(__section_alignment__) :
      {
        *(.pdata)
      }
      .bss BLOCK(__section_alignment__) :
      {
        __bss_start__ = . ;
        *(.bss)
        *(COMMON)
        __bss_end__ = . ;
      }
      .edata BLOCK(__section_alignment__) :
      {
        *(.edata)
      }
      /DISCARD/ :
      {
        *(.debug$S)
        *(.debug$T)
        *(.debug$F)
        *(.drectve)
      }
      .idata BLOCK(__section_alignment__) :
      {
        /* This cannot currently be handled with grouped sections.
    	See pe.em:sort_sections.  */
        SORT(*)(.idata$2)
        SORT(*)(.idata$3)
        /* These zeroes mark the end of the import list.  */
        LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
        SORT(*)(.idata$4)
        SORT(*)(.idata$5)
        SORT(*)(.idata$6)
        SORT(*)(.idata$7)
      }
      .CRT BLOCK(__section_alignment__) :
      {
        ___crt_xc_start__ = . ;
        *(SORT(.CRT$XC*))  /* C initialization */
        ___crt_xc_end__ = . ;
        ___crt_xi_start__ = . ;
        *(SORT(.CRT$XI*))  /* C++ initialization */
        ___crt_xi_end__ = . ;
        ___crt_xl_start__ = . ;
        *(SORT(.CRT$XL*))  /* TLS callbacks */
        /* ___crt_xl_end__ is defined in the TLS Directory support code */
        ___crt_xp_start__ = . ;
        *(SORT(.CRT$XP*))  /* Pre-termination */
        ___crt_xp_end__ = . ;
        ___crt_xt_start__ = . ;
        *(SORT(.CRT$XT*))  /* Termination */
        ___crt_xt_end__ = . ;
      }
      .tls BLOCK(__section_alignment__) :
      {
        ___tls_start__ = . ;
        *(.tls)
        *(.tls$)
        *(SORT(.tls$*))
        ___tls_end__ = . ;
      }
      .endjunk BLOCK(__section_alignment__) :
      {
        /* end is deprecated, don't use it */
        PROVIDE (end = .);
        PROVIDE ( _end = .);
         __end__ = .;
      }
      .rsrc BLOCK(__section_alignment__) :
      {
        *(.rsrc)
        *(SORT(.rsrc$*))
      }
      .reloc BLOCK(__section_alignment__) :
      {
        *(.reloc)
      }
      .stab BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.stab)
      }
      .stabstr BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.stabstr)
      }
      /* DWARF debug sections.
         Symbols in the DWARF debugging sections are relative to the beginning
         of the section.  Unlike other targets that fake this by putting the
         section VMA at 0, the PE format will not allow it.  */
      /* DWARF 1.1 and DWARF 2.  */
      .debug_aranges BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_aranges)
      }
      .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_pubnames)
      }
      /* DWARF 2.  */
      .debug_info BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_info) *(.gnu.linkonce.wi.*)
      }
      .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_abbrev)
      }
      .debug_line BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_line)
      }
      .debug_frame BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_frame)
      }
      .debug_str BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_str)
      }
      .debug_loc BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_loc)
      }
      .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_macinfo)
      }
      /* SGI/MIPS DWARF 2 extensions.  */
      .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_weaknames)
      }
      .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_funcnames)
      }
      .debug_typenames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_typenames)
      }
      .debug_varnames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_varnames)
      }
      /* DWARF 3.  */
      .debug_ranges BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_ranges)
      }
    }

    /*
     * SimEEtool for 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 	simeetool.c
     * @brief 	Programm zur Unterstuetzung des Simulierten EEPROM des ct-bot
     * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
     * @date 	02.04.07
     */

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>

    char avrmap[100]=""; //Datei mit der EEPROM-MAP des realen ct-bot
    char  pcmap[100]=""; //Datei mit der EEPROM-MAP des simulierten ct-bot
    char avreep[100]=""; //Datei mit den Initialisierungswerten des realen Bot vom avr-gcc
    char  pceep[100]=""; //Datei mit den Initialisierungswerten des sim Bot vom gcc
    char avrbin[100]=""; //Datei mit dem Abzug des EEPROM des realen ct-bot im binary Format
    char  pcbin[100]=""; //Datei die das simulierte EEPROM fuer den ct-sim darstellt

    /*!
     * Liest die cfg-Datei ein und legt die Pfade der benötigten Datei ab.
     */
    void read_cfg(){
    	FILE *fpr;

    	if(!(fpr = fopen("simeetool.cfg", "r")))
    		return;
    	fgets(avrmap, 99, fpr); avrmap[strlen(avrmap)-1] = '\0';
    	fgets( pcmap, 99, fpr);  pcmap[strlen( pcmap)-1] = '\0';
    	fgets(avreep, 99, fpr); avreep[strlen(avreep)-1] = '\0';
    	fgets( pceep, 99, fpr);  pceep[strlen( pceep)-1] = '\0';
    	fgets(avrbin, 99, fpr); avrbin[strlen(avrbin)-1] = '\0';
    	fgets( pcbin, 99, fpr);  pcbin[strlen( pcbin)-1] = '\0';
    	fclose(fpr);
    }

    /*!
     * Diese Funktion extrahiert den Inhalt der übergebenen IHex Zeile und legt sie in den
     * Parametern ab.
     * @param  line Zeile mit IHex Daten
     * @param  addr Adresse
     * @param  data Daten der IHex Zeile
     * @param  size Anzahl der Daten
     */
    void get_ihex_data(char *line, int *addr, int *data, int *size){
    	char ssize[] = "  ";
    	char saddr[] = "    ";
    	char sdata[] = "  ";
    	int i=0;

    	strncpy(ssize, &line[1], 2);  //Kopfdaten extrahieren
    	strncpy(saddr, &line[3], 4);
    	sscanf(ssize, "%x", size);
    	sscanf(saddr, "%x", addr);

    	for(i=0; i<*size; i++){
    		strncpy(sdata, &line[9+i*2], 2);
    		sscanf(sdata, "%x", &data[i]);
    	}

    	return;
    }

    /*!
     * Die Funktion setzt die neuen Daten in die IHex Zeile und berechnet die Prüfziffer neu.
     * @param  addr Adresse
     * @param  date Zeiger auf das Datenarray
     * @param  size Groesse des Datenarray
     * @param  line Zeile, in der die Daten eingetragen werden muessen
     */
    void set_ihex_data(int addr, int *data, int size, char *line){
    	char ssize[3]="  ";
    	char saddr[5];
    	char sdata[3];
    	int i=0, chksum=0, tmp;

    	sprintf(ssize, "%2.2X", size);  //Kopfdaten erstellen (eigentlich hier nicht notwendig, aber wenn mans mal anderes nutzt)
    	sprintf(saddr, "%4.4X", addr);
    	sprintf(line, ":%s%s00", ssize, saddr);

    	for(i=0; i<size; i++){ //Daten schreiben
    		sprintf(sdata, "%2.2X", data[i]);
    		strcat(line, sdata);
    	}

    	for(i=0; i<(size*2)+4;i+=2){ //Neue Checksumme berechnen
    		strncpy(ssize, &line[i+1], 2); //Byte holen
    		sscanf(ssize, "%x", &tmp); //wandeln
    		chksum += tmp;
    	}
    	chksum %= 256; //Modulo 256
    	chksum =(~chksum & 0x00ff)+1; //2er Komplement
    	sprintf(ssize, "%2.2X", chksum); //Checksumme in Zeile aendern
    	strncpy(&line[size*2+9], ssize, 2);

    	return;
    }

    /*!
     * Diese Funktion liest aus einer IntelHEX Datei den Inhalt der übergebenen Adresse
     * aus.
     * @param  addr Adresse
     * @param  eep  Legt epp datei fest 0->pc 1->mcu
     * @return Gelesener Wert (0=OK, -1=Dateifehler, -2=Adressfehler
     */
    int read_ihex(int addr, int eep){
    	FILE *fpr;
    	char line[134]; //Eingelesene Zeile
    	int ihexaddr, ihexdata[16], ihexsize; //Ausgelesene Daten

    	if(!(fpr = fopen((eep?avreep:pceep), "r"))){  //Datei oeffnen
    		return(-1);
    	}

    	while(fgets(line, 130, fpr)){
    		get_ihex_data(line, &ihexaddr, ihexdata, &ihexsize);
    		if(addr >= ihexaddr && addr < (ihexaddr + ihexsize)){
    			fclose(fpr);
    			return(ihexdata[ihexsize-((ihexaddr+ihexsize)-addr)]);
    		}
    	}
    	fclose(fpr);
    	return(-2);
    }

    /*!
     * Diese Funktion schreibt in eine IntelHEX Datei den Inhalt von value an die angegebene
     * Adresse.
     * @param  addr Adresse
     * @param  eep  Legt epp datei fest 0->pc 1->mcu
     * @return Status, ob Operation erfolgreich.
     */
    int write_ihex(int addr, int value, int eep){
    	FILE *fpr;
    	long fp; //Lesezeigerposition
    	char line[134]; //Eingelesene Zeile
    	int ihexaddr, ihexdata[16], ihexsize; //Ausgelesene Daten

    	if(!(fpr = fopen((eep?avreep:pceep), "r+"))){  //Datei oeffnen
    		return(-1);
    	}

    	fp = ftell(fpr);
    	while(fgets(line, 130, fpr)){
    		get_ihex_data(line, &ihexaddr, ihexdata, &ihexsize);
    		if(addr >= ihexaddr && addr < (ihexaddr + ihexsize)){
    			ihexdata[ihexsize-((ihexaddr+ihexsize)-addr)] = value;
    			fseek(fpr, fp, SEEK_SET);
    			set_ihex_data(ihexaddr, ihexdata, ihexsize, line);
    			fprintf(fpr, "%s", line);
    			fclose(fpr);
    			return(0);
    		}
    		fp = ftell(fpr); //Alte Position sichern
    	}
    	fclose(fpr);
    	return(-1);
    }

    /*!
     * Liest einen Wert aus einer Binaerdatei von der angegebenen Adresse.
     * @param address Adresse
     * @param bin  Legt bin Datei fest 0->pc 1->mcu
     * @return Fehler(-1) oder OK(0)
     */
    int read_binary(int address, int bin) {
    	int fh = 0; 	//Dateizeiger
    	int dataline[1] = {0};	//String fuer Datenausgabe

    	if((fh = open((bin?avrbin:pcbin), O_BINARY|O_RDONLY)) == -1) //ansonsten Datei oeffnen
    		return(0);

    	//Daten einlesen
    	lseek(fh, address, SEEK_SET); //Lesezeiger setzen
    	read(fh, dataline, 1);	//Daten lesen

    	close(fh);
    	return(dataline[0]);
    }

    /*!
     * Schreibt einen Wert in eine Binaerdatei an die richtige Adresse.
     * @param address Adresse
     * @param data Byte welches abgelegt werden soll.
     * @param bin  Legt bin Datei fest 0->pc 1->mcu
     * @return Fehler(-1) oder OK(0)
     */
    int write_binary(int address, int data, int bin) {
    	int fh = 0; 	//Dateizeiger

    	if((fh = open((bin?avrbin:pcbin), O_BINARY|O_WRONLY)) == -1) //Datei oeffnen
    		return(-1);

    	//Daten eintragen
    	lseek(fh, address, SEEK_SET); //Schreibzeiger setzen
    	data=data%256;
    	write(fh, &data, 1);	//Daten schreiben

    	close(fh);
    	return(0);
    }

    /*!
     * Bestimmte die Adresse einer Variable mit Hilfe der map-Dateien. Im Fall der mcu-eeprom.map
     * kann auch noch die Groesse der Variable in Byte bestimmt werden.
     * @param var  Name der Variablen
     * @param map  Legt map datei fest 0->pc 1->mcu
     * @param size Liefert bei map->1 auch die Groesse der Variable in Bytes
     */
    int get_addr(char *var, int map, int *size){
    	FILE *fpr;
    	char line[200];

    	*size=-1; //Vorbelegung
    	if(!(fpr = fopen((map?avrmap:pcmap), "r"))){ //map-Datei oeffnen
    		return(-1);
    	}

    	do { //Unwichtiges ueberspringen
    		fgets(line, 198, fpr);
    	}while(strncmp(line, (map?"SYM":"AUX"), 3));

    	while(fgets(line, 198, fpr)) //Adresse bestimmen
    		if(!strncmp(var, &line[(map?34:59)], strlen(var))){
    			char hex[11] = "0x00000000";
    			int addr = 0;

    			strncpy(&hex[(map?6:0)], &line[(map?4:47)], (map?4:10));
    			sscanf(hex, "%x", &addr);
    			if(map){ //Grosse auch auslesen
    				strncpy(&hex[2], &line[25], 8);
    				sscanf(hex, "%x", size);
    			}
    			fclose(fpr);
    			return(addr);
    		}

    	fclose(fpr); //Variable nicht gefunden
    	return(-1);
    }

    /*!
     * Schreibt die Initialisierung einer Variable aus der eep Datei in das simulierte
     * EEPROM.
     */
    int set_command(char *var, char *csize){
    	int size;
    	int addr;
    	int value;
    	int i=0;

    	addr = get_addr(var, 0, &size);	//addresse bestimmen
    	if(addr < 0){ //Fehler, Variable unbek.
    		printf("Variable unbek. oder falscher MAP Dateiname\n");
    		return(0);
    	}

    	if(!strlen(csize)){ //Groesse vorhanden?
    		get_addr(var, 1, &size);        //groesse bestimmen
    		if(size < 0){
    			printf("Groesse der Variable unbek.. Bitte als Parameter angeben!\n");
    			return(0);
    		}
    	}
    	else
    		size=atoi(csize);

    	do { //Daten kopieren
    		value = read_ihex(addr+i, 0); //daten aus eep datei holen
    		if(value == -1){
    			printf("Kann EEP Datei des PC nicht finden!\n");
    			return(0);
    		}
    		if(value == -2){
    			printf("Adresse nicht vorhanden!\n");
    			return(0);
    		}

    		value = write_binary(addr+i, value, 0); //daten in bin datei schreiben
    		if(value < 0){
    			printf("Kann BIN Datei des PC nicht finden!\n");
    			return(0);
    		}
    	}
    	while(++i < size);

    	printf("Variable %s an Adresse 0x%4.4x %d Byte%c in Sim-EEPROM eingepatched\n", var, addr, size, (size>1?'s':' '));
    	return(0);
    }

    /*!
     * Schreibt die Werte einer Variable aus den simulierte EEPROM in die Initialiserungsdatei
     * des EEPROM vom Compiler (EEP-Datei).
     */
    int get_command(char *var, char *csize){
    	int size;
    	int addr;
    	int value;
    	int i=0;

    	addr = get_addr(var, 0, &size);	//addresse bestimmen
    	if(addr < 0){ //Fehler, Variable unbek.
    		printf("Variable unbek. oder falscher MAP Dateiname\n");
    		return(0);
    	}

    	if(!strlen(csize)){ //Groesse vorhanden?
    		get_addr(var, 1, &size);        //groesse bestimmen
    		if(size < 0){
    			printf("Groesse der Variable unbek.. Bitte als Parameter angeben!\n");
    			return(0);
    		}
    	}
    	else
    		size=atoi(csize);

    	do { //Daten kopieren
    		value = read_binary(addr+i, 0); //daten aus eep datei holen
    		if(value == -1){
    			printf("Kann BIN Datei des PC nicht finden!\n");
    			return(0);
    		}
    		if(value == -2){
    			printf("Adresse nicht vorhanden!\n");
    			return(0);
    		}

    		value = write_ihex(addr+i, value, 0); //daten in bin datei schreiben
    		if(value < 0){
    			printf("Kann EEP Datei des PC nicht finden!\n");
    			return(0);
    		}
    	}
    	while(++i < size);

    	printf("Variable %s an Adresse 0x%4.4x %d Byte%c in EEP Datei eingepatched\n", var, addr, size, (size>1?'s':' '));
    	return(0);
    }

    /*!
     * Schreibt die Werte einer Variable aus den simulierte EEPROM in die Initialiserungsdatei
     * des EEPROM vom Compiler (EEP-Datei).
     */
    int flash_command(char *var, char *csize){
    	int addr=0;
    	int value;

    	while((value=read_ihex(addr, 0))>=0){ //Daten kopieren
    		value = write_binary(addr++, value, 0); //daten in bin datei schreiben
    		if(value < 0){
    			printf("Kann EEP Datei des PC nicht finden!\n");
    			return(0);
    		}
    	}

    	printf("%d Bytes in Sim-EEPROM eingepatched\n", addr);
    	return(0);
    }

    /*!
     * Hauptprogramm des simeetool, kuemmert sich um seine Steuerung.
     */
    int main (int argc, char *argv[]){

    	read_cfg(); //Konfiguration einlesen
    	switch(argc) {
    		case 1:
    			printf("simeetool <command> <arg1...>\n");
    			printf("%-8s %-12s %-10s %-30s\n", "command", "arg1", "arg2", "Funktion");
    			printf("%-8s %-12s %-10s %-30s\n", "set", "<variable>", "[size]", "Uebertraegt Werte von PC-EEP in Sim EEPROM");
    			printf("%-8s %-12s %-10s %-30s\n", "get", "<variable>", "[size]", "Uebertraegt Werte vom Sim EEPROM in PC-EEP");
    			printf("%-8s %-12s %-10s %-30s\n", "flash", "", "", "Uebertr. alle Werte vom PC-EEP ins Sim EEPROM ");
    			break;
    		case 2:
    			if(!strcmp(argv[1], "flash")){
    				printf("flash-comand\n");
    				flash_command(argv[2], "");
    			}
    			break;
    		case 3:
    			if(!strcmp(argv[1], "set")){
    				printf("set-comand\n");
    				set_command(argv[2], "");
    			} else if(!strcmp(argv[1], "get")){
    				printf("get-comand\n");
    				get_command(argv[2], "");
    			} else{
    				printf("unknown command\n");
    			}
    			break;
    		case 4:
    			if(!strcmp(argv[1], "set")){
    				printf("set-comand\n");
    				set_command(argv[2], argv[3]);
    			} else if(!strcmp(argv[1], "get")){
    				printf("get-comand\n");
    				get_command(argv[2], argv[3]);
    			} else{
    				printf("unknown command\n");
    			}
    			break;
    	}
    	return(0);
    }

    ### Eclipse Workspace Patch 1.0
    #P ct-Bot
    Index: include/gui.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/gui.h,v
    retrieving revision 1.1
    diff -u -r1.1 gui.h
    --- include/gui.h	22 Feb 2007 18:02:10 -0000	1.1
    +++ include/gui.h	10 Apr 2007 13:56:45 -0000
    @@ -57,6 +57,7 @@

     #ifdef RESET_INFO_DISPLAY_AVAILABLE
     	extern uint8 reset_flag;	 /*<! Nimmt den Status von MCU(C)SR bevor dieses Register auf 0x00 gesetzt wird */
    +	extern uint8 reset;
     	/*!
     	 * @brief	Zeigt Informationen ueber den Reset an
     	 */
    Index: include/global.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/global.h,v
    retrieving revision 1.6
    diff -u -r1.6 global.h
    --- include/global.h	8 Jun 2006 16:36:38 -0000	1.6
    +++ include/global.h	10 Apr 2007 13:56:45 -0000
    @@ -64,4 +64,6 @@
     //	#define PI					3.14159					/*!< Kreiszahl Pi fuer trigonometrische Berechnungen */
     	#define binary(var,bit) ((var >> bit)&1)
     	//#define NULL 0
    +	#define EEPROM  __attribute__ ((section (".eeprom"))) //Attribute fuer eeprom Variablen
    +
     #endif
    Index: Changelog.txt
    ===================================================================
    RCS file: /ctbot/ct-Bot/Changelog.txt,v
    retrieving revision 1.142
    diff -u -r1.142 Changelog.txt
    --- Changelog.txt	27 Mar 2007 16:26:27 -0000	1.142
    +++ Changelog.txt	10 Apr 2007 13:56:44 -0000
    @@ -1,5 +1,9 @@
     CHANGELOG fuer c't-Bot
     ======================
    +2007-04-10 Achim Pankalla [achim.pankalla@xxxxxx]: EEPROM Simulation für für ct-bot unter ct-sim.
    +
    +2007-04-10 Achim Pankalla [achim.pankalla@xxxxxx]: Fehler bei aktivierten Resetcounter unter PC korregiert
    +
     2007-03-27 Benjamin Benz [bbe@xxxxxxxx]: Makefile Ã¼berarbeitet

     2007-03-05 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bugfix fuer Remote-Display (falsche Cursorposition, falls nicht vor jedem display_printf() ein display_cursor() efolgte)
    Index: ct-Bot.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/ct-Bot.h,v
    retrieving revision 1.38
    diff -u -r1.38 ct-Bot.h
    --- ct-Bot.h	22 Feb 2007 18:02:10 -0000	1.38
    +++ ct-Bot.h	10 Apr 2007 13:56:44 -0000
    @@ -121,6 +121,7 @@
     		#undef TWI_AVAILABLE
     		#undef SPEED_CONTROL_AVAILABLE // Deaktiviere die Motorregelung
     		#undef MMC_AVAILABLE
    +		#undef TEST_AVAILABLE_COUNTER  //Keine Resetcounter im sim
     	#endif

     	#define COMMAND_AVAILABLE		/*!< High-Level Communication */
    Index: ct-Bot.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/ct-Bot.c,v
    retrieving revision 1.43
    diff -u -r1.43 ct-Bot.c
    --- ct-Bot.c	22 Feb 2007 18:02:10 -0000	1.43
    +++ ct-Bot.c	10 Apr 2007 13:56:44 -0000
    @@ -32,12 +32,14 @@
     //	#include <avr/signal.h>
     	#include <avr/wdt.h>
     	#include "bot-2-pc.h"
    +	#include <avr/eeprom.h>
     #endif

     #ifdef PC
     	#include "bot-2-sim.h"
     	#include "tcp.h"
     	#include "tcp-server.h"
    +	#include "eeprom-emu.h"
     	#include <pthread.h>
     	#include <unistd.h>
     	#include <stdlib.h>
    @@ -64,6 +66,7 @@
     #include "timer.h"
     #include "sensor.h"
     #include "log.h"
    +#include "eeprom_map.h"

     #include "motor.h"
     #include "sensor-low.h"
    @@ -81,7 +84,6 @@
     #include "mmc-vm.h"
     #include "gui.h"
     #include "ui/available_screens.h"
    -
     /*!
      * Der Mikrocontroller und der PC-Simulator brauchen ein paar Einstellungen,
      * bevor wir loslegen koennen.
    @@ -404,10 +406,10 @@
     //TODO: what's that?!?
     #ifdef TEST_AVAILABLE_COUNTER
     //	display_screen=2;
    - 	resets=eeprom_read_byte(&resetsEEPROM)+1;
    -    eeprom_write_byte(&resetsEEPROM,resets);
    + 	reset=eeprom_read_byte(&resets)+1;
    +    eeprom_write_byte(&resets,reset);
         /* Lege den Grund fuer jeden Reset im EEPROM ab */
    -    eeprom_write_byte(&resetInfoEEPROM+resets,reset_flag);
    +    eeprom_write_byte((uint8 *)((uint8)&resetinfo+(uint8)(reset%10)),reset_flag);
     #endif

     /* Hauptschleife des Bots */
    Index: bot-logic/behaviour_turn.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/bot-logic/behaviour_turn.c,v
    retrieving revision 1.2
    diff -u -r1.2 behaviour_turn.c
    --- bot-logic/behaviour_turn.c	22 Feb 2007 01:41:16 -0000	1.2
    +++ bot-logic/behaviour_turn.c	10 Apr 2007 13:56:45 -0000
    @@ -31,10 +31,17 @@
     #ifdef MCU
     	#include <avr/eeprom.h>
     #endif
    +#ifdef PC
    +	#include "eeprom-emu.h"
    +#endif
     #include <stdlib.h>
     #include <math.h>
     #include "log.h"

    +extern uint8 EEPROM err15;		/*!< Fehler bei Drehungen unter 15 Grad */
    +extern uint8 EEPROM err45;		/*!< Fehler bei Drehungen zwischen 15 und 45 Grad */
    +extern uint8 EEPROM err_big;	/*!< Fehler bei groesseren Drehungen */
    +
     /* Parameter fuer das bot_turn_behaviour() */
     #ifndef MEASURE_MOUSE_AVAILABLE
     int16 turn_targetR;				/*!< Zu drehender Winkel bzw. angepeilter Stand des Radencoders sensEncR */
    @@ -42,15 +49,6 @@
     #else
     int8 angle_correct=0;			/*!< Drehabschnitt 0=0-15Grad, 1=16-45 Grad, 2= >45 Grad */
     int16 to_turn;					/*!< Wieviel Grad sind noch zu drehen? */
    -	#ifdef MCU
    -		uint8 __attribute__ ((section (".eeprom"))) err15=1;					/*!< Fehler bei Drehungen unter 15 Grad */
    -		uint8 __attribute__ ((section (".eeprom"))) err45=2;					/*!< Fehler bei Drehungen zwischen 15 und 45 Grad */
    -		uint8 __attribute__ ((section (".eeprom"))) err_big=4;				/*!< Fehler bei groesseren Drehungen */
    -	#else
    -		uint8 err15=0;
    -		uint8 err45=0;
    -		uint8 err_big=0;
    -	#endif
     #endif
     int8 turn_direction;			/*!< Richtung der Drehung */

    @@ -150,48 +148,30 @@
     				speedWishRight=BOT_SPEED_STOP;
     				break;
      			}
    -			#ifdef MCU
    -				e15=eeprom_read_byte(&err15);
    -				e45=eeprom_read_byte(&err45);
    -				ebig=eeprom_read_byte(&err_big);
    -			#else
    -				e15=err15;
    -				e45=err45;
    -				ebig=err_big;
    -			#endif
    +			e15=eeprom_read_byte(&err15);
    +			e45=eeprom_read_byte(&err45);
    +			ebig=eeprom_read_byte(&err_big);

     			// Neue Abweichung mit alter vergleichen und ggfs neu bestimmen
     			switch(angle_correct) {
     				case 0:
     					if (abs(to_turn+e15) > 1){
     						e15 = (uint8)(-to_turn + e15) / 2;
    -						#ifdef MCU
    -							eeprom_write_byte(&err15,e15);
    -						#else
    -							err15=e15;
    -						#endif
    +						eeprom_write_byte(&err15,e15);
     					}
     					break;

     				case 1:
     					if (abs(to_turn+e45) > 1){
     						e45 = (uint8)(-to_turn + e45) / 2;
    -						#ifdef MCU
    -							eeprom_write_byte(&err45,e45);
    -						#else
    -							err45=e45;
    -						#endif
    +		 				eeprom_write_byte(&err45,e45);
     					}
     					break;

     				case 2:
     					if (abs(to_turn+ebig) > 1){
     						ebig = (uint8)(-to_turn + ebig) / 2;
    -						#ifdef MCU
    -							eeprom_write_byte(&err_big,ebig);
    -						#else
    -							err_big=ebig;
    -						#endif
    +						eeprom_write_byte(&err_big,ebig);
     					}
     					break;
     			}
    @@ -212,34 +192,21 @@
      	if(degrees < 0) turn_direction = -1;
      	else turn_direction = 1;
     	to_turn=abs(degrees);
    -	#ifdef MCU
    -		/* Fehlerwerte initialisieren, falls noch nicht geschehen */
    -		if (eeprom_read_byte(&err15) == 255) eeprom_write_byte(&err15,1);
    -		if (eeprom_read_byte(&err45) == 255) eeprom_write_byte(&err45,2);
    -		if (eeprom_read_byte(&err_big) == 255) eeprom_write_byte(&err_big,4);
    +	/* Fehlerwerte initialisieren, falls noch nicht geschehen */
    +	if (eeprom_read_byte(&err15) == 255) eeprom_write_byte(&err15,1);
    +	if (eeprom_read_byte(&err45) == 255) eeprom_write_byte(&err45,2);
    +	if (eeprom_read_byte(&err_big) == 255) eeprom_write_byte(&err_big,4);

    -		if (to_turn>45) {
    -			to_turn-=eeprom_read_byte(&err_big);
    -			angle_correct=2;
    -		} else if (to_turn<=45 && to_turn>15) {
    -			to_turn-=eeprom_read_byte(&err45);
    -			angle_correct=1;
    -		} else {
    -			to_turn-=eeprom_read_byte(&err15);
    -			angle_correct=0;
    -		}
    -	#else
    -		if (to_turn>45) {
    -			to_turn-=err_big;
    -			angle_correct=2;
    -		} else if (to_turn<=45 && to_turn>15) {
    -			to_turn-=err45;
    -			angle_correct=1;
    -		} else {
    -			to_turn-=err15;
    -			angle_correct=0;
    -		}
    -	#endif
    +	if (to_turn>45) {
    +		to_turn-=eeprom_read_byte(&err_big);
    +		angle_correct=2;
    +	} else if (to_turn<=45 && to_turn>15) {
    +		to_turn-=eeprom_read_byte(&err45);
    +		angle_correct=1;
    +	} else {
    +		to_turn-=eeprom_read_byte(&err15);
    +		angle_correct=0;
    +	}
      	switch_to_behaviour(caller, bot_turn_behaviour,OVERRIDE);
      }
     #else
    Index: ui/misc.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/ui/misc.c,v
    retrieving revision 1.1
    diff -u -r1.1 misc.c
    --- ui/misc.c	22 Feb 2007 18:02:10 -0000	1.1
    +++ ui/misc.c	10 Apr 2007 13:56:45 -0000
    @@ -65,6 +65,7 @@

     	#ifdef RESET_INFO_DISPLAY_AVAILABLE
     		uint8 reset_flag;
    +		uint8 reset;
     		/*!
     		 * @brief Zeigt Informationen ueber Resets an
     		 */
    Index: include/eeprom_map.h
    ===================================================================
    RCS file: include/eeprom_map.h
    diff -N include/eeprom_map.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/eeprom_map.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,54 @@
    +/*
    + * 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_map.h
    + * @brief 	Speicherbelgegung des EEPROM Bereiches vom ct-bot Prozessor
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	01.03.07
    +*/
    +#ifndef eeprom_map_H_
    +#define eeprom_map_H_
    +
    +#ifdef PC
    +	#define ALIGNED  __attribute__ ((aligned(1))) //Keine Luecken zwischen Daten beim PC
    +#else
    +	#define ALIGNED
    +#endif
    +
    +/******************************************************************************
    +* EEPROM Memory map zur Uebersicht welche Variablen es bereits im EEPROM liegen
    +* und zur Übersicht, wie der Speicher aufgeteilt ist.
    +* Achtung!
    +* Eine Aenderung der Reihenfolge der Variablen hat einfluss auf die Nutzung des
    +* EEPROMs. Alte EEPROM Inhalte, wie zum Beispiel Kalibrierdaten sind dann nicht
    +* mehr nutzbar und muessen neu angelegt werden.
    +* Bitte immer auch das ALIGNED verwenden, damit beim PC die Variablen lueckenlos
    +* hintereinander stehen.
    +******************************************************************************/
    +//Speicher für die Kalibriertabellen der IR-Distanzsensoren
    +uint16 EEPROM ALIGNED sct_left[30];		/*!< Tabelle fuer linken Sensor */
    +uint16 EEPROM ALIGNED sct_right[30];	/*!< Tabelle fuer rechten Sensor */
    +//Variablen für TEST_AVAILABLE_COUNTERS. Resetkontrollroutine
    +uint8  EEPROM ALIGNED resets=0;			/*!< Anzahl der Resets seid Rücksetzen des Zählers */
    +uint8  EEPROM ALIGNED resetinfo[10];	/*!< Registerflags der letzten 10 Resets */
    +//bot_turn_behaviour Daten
    +uint8  EEPROM ALIGNED err15=1;			/*!< Fehler bei Drehungen unter 15 Grad */
    +uint8  EEPROM ALIGNED err45=2;			/*!< Fehler bei Drehungen zwischen 15 und 45 Grad */
    +uint8  EEPROM ALIGNED err_big=4;		/*!< Fehler bei groesseren Drehungen */
    +#endif
    Index: include/eeprom-emu.h
    ===================================================================
    RCS file: include/eeprom-emu.h
    diff -N include/eeprom-emu.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/eeprom-emu.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,55 @@
    +/*
    + * 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.h
    + * @brief 	Low-Level Routinen fuer den Zugriff auf das EEPROM des c't-Bots
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	01.03.07
    +*/
    +#ifndef eeprom_emu_H_
    +#define eeprom_emu_H_
    +
    +#ifdef PC
    +#include <stddef.h>
    +/*!
    + * Speichern Daten im EEPROM.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @param data Variable mit den abzulegenen Daten.
    + */
    +extern void eeprom_write_byte(uint8  *adr, uint8 value);
    +extern void eeprom_write_word(uint16 *adr, uint16 value);
    +
    +/*!
    + * Laden Daten aus dem EEPROM.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @return Wert der Speicheraddresse im EEPROM
    + */
    +extern uint8  eeprom_read_byte(uint8  *adr);
    +extern uint16 eeprom_read_word(uint16 *adr);
    +
    +/*!
    + * Kopiert ein Block aus den EEPROM oder in das EEPROM
    + * @param address Adresse im Speicher.
    + * @param address Adresse im EEPROM.
    + */
    +extern void eeprom_read_block(void *pointer_ram, const void *pointer_eeprom, size_t size);
    +extern void eeprom_write_block(const void *pointer_ram, void *pointer_eeprom, size_t size);
    +
    +#endif
    +#endif
    Index: Documentation/eeprom-simulation.html
    ===================================================================
    RCS file: Documentation/eeprom-simulation.html
    diff -N Documentation/eeprom-simulation.html
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ Documentation/eeprom-simulation.html	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,239 @@
    +<!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.1  (Win32)">
    +	<META NAME="AUTHOR" CONTENT="Achim Pankalla">
    +	<META NAME="CREATED" CONTENT="20060528;19455600">
    +	<META NAME="CHANGEDBY" CONTENT="Achim Pankalla">
    +	<META NAME="CHANGED" CONTENT="20070409;18433614">
    +	<STYLE>
    +	<!--
    +		@page { size: 21cm 29.7cm; margin: 2cm }
    +		P { margin-bottom: 0.21cm }
    +	-->
    +	</STYLE>
    +</HEAD>
    +<BODY LANG="de-DE" DIR="LTR">
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><B>EEPROM Simulation f&uuml;r
    +PC</B></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3><B>Author: </B></FONT>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>Achim Pankalla
    +(achim.pankalla@xxxxxx)</FONT></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Beschreibung:</B></P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm; font-style: normal">Die
    +EEPROM Simulation f&uuml;r den PC stellt das EEPROM des <I>Atmel
    +MEGA32 Prozessor</I> auch dem Simulierten ct-bot zur Verf&uuml;gung.
    +Der Zugriff auf dieses EEPROM erfolgt &uuml;ber gleichnamige
    +Funktionen, wie sie auch der avr-gcc besitzt und auch die
    +Variablendefinition erfolgt &uuml;ber die gleichen Konstrukte. Eine
    +Unterscheidung &uuml;ber #ifdef's ist also nicht notwendig.<BR>Durch
    +diese EEPROM-Simulation, ist der Simulator dem realen Bot ein schritt
    +n&auml;her gekommen und Programme mit EEPROM-Zugriffe k&ouml;nnen mit
    +der Simulation getestet werden.</P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Implementierung:</B></P>
    +<P STYLE="margin-bottom: 0cm">Alle Funktionen und Einstellungen der
    +EEPROM Simulation 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 1K gross) repr&auml;sentiert (und kann so
    +mit einen HexEditor bearbeitet werden), deren Pfad in der C-Datei
    +festgelegt wird. Standard Pfad ist das Heimatverzeichnis des Ct-Sim.
    +Nat&uuml;rlich k&ouml;nnen Sie das jederzeit &auml;ndern, dies geht
    +&uuml;ber die Konstante <FONT COLOR="#000000"><FONT SIZE=2><FONT FACE="Courier New, monospace">EEPROM_FILENAME.
    +</FONT></FONT><FONT FACE="Times New Roman, serif">B</FONT></FONT><FONT FACE="Times New Roman, serif">itte
    +beachten Sie aber das Verdoppeln des Backslash im Verzeichnispfad.
    +Der Name <I>eeprom.bin</I> sollte dabei belassen werden.</FONT><BR>Die
    +Datei wird automatisch neu angelegt, wenn sie noch nicht existiert.
    +Dann besteht der Inhalt nur aus 0xFF, wie es auch beim
    +unintialisierten EEPROM des Atmel der Fall ist.<BR>Damit die
    +EEPROM-Funktionen des PC korrekt auf die Datei zugreifen k&ouml;nnen
    +und nur ein Adressraum von 0 bis 1023 entsteht, wie es auch beim
    +avr-gcc verwalteten ist, gibt es die externe Variable
    +&bdquo;_eeprom_start__&ldquo;. Diese enth&auml;lt die Startadresse
    +der ersten Variable im Segment .eeprom und dieser Wert wird dann von
    +der &uuml;bergebenen Adresse subtrahiert. Damit es diese Variable
    +gibt, m&uuml;ssen Sie das Linkerscript &bdquo;linker_script.lk&ldquo;
    +an den Linker &uuml;bergeben. Dies machen Sie mit den Parameter <I>-T</I>
    +der Linkers. Tragen sie in Eclipse dies unter
    +Project-&gt;Properties-&gt;C/C++ Build-&gt;Linker-&gt;Miscellaneous-&gt;Linker
    +flags &bdquo;-T linker_script.lk&ldquo; ein. Die Datei muss dann
    +nat&uuml;rlich im Debug-W32/Linux Verzeichnis vorhanden sein.<BR>Wie
    +auch beim MCU Projekt wird nun auch beim Erstellen eines ct-sim bot
    +die Datei ct-bot.eep erstellt, die die Initialisierungswerte der
    +EEPROM Variablen enth&auml;lt. Daf&uuml;r muss unter
    +Project-&gt;Properties-&gt;C/C++ Build-&gt;Build Steps-&gt;Post Build
    +steps der Befehl eingetragen <I>objcopy -j .eeprom
    +--change-section-lma .eeprom=0 -O ihex ct-Bot.exe ct-Bot.eep</I>
    +sein. Dies m&uuml;ssen Sie nat&uuml;rlich nur in der Konfiguration
    +DEBUG-W32/Linux machen.</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B><FONT SIZE=4 STYLE="font-size: 15pt"><FONT COLOR="#ff0000">Achtung!!</FONT></FONT></B><BR>Beachten
    +Sie die Zeigerarithmetik von C. Alle eeprom-Funktionen erwarten, wie
    +beim avr-Compiler Pointer auf uint8 oder uint16 als Adressparameter.
    +Damit auch alles sicher klappt sollten bei berechneten Adressen wie
    +folgt vorgegangen werden.<BR>z.B. eeprom_read_word((uint16 *)
    +(SCT_LEFT + i*2))</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>eeprom_map.h</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal; font-weight: medium">
    +Zum Gesamtkonzept des Simulierten EEPROM geh&ouml;rt auch noch die
    +Datei eeprom_map.h. Diese Datei erf&uuml;llt dabei zwei Funktionen.
    +Erstens soll sie daf&uuml;r sorgen, das die Programmierer einen
    +&Uuml;berblick dar&uuml;ber erhalten, in wie weit das EEPROM schon
    +benutzt ist (ein bisschen Ordnung hat noch nie geschadet und es gibt
    +ja nur 1K) und zweitens legt der Compiler die Variablen so auf einmal
    +an und es ist daf&uuml;r gesorgt, das es keine Verschiebungen in der
    +Reihenfolge gibt, wenn man neue Variablen hinten anh&auml;ngt oder
    +einige EEPROM-Variablen nicht definiert werden, weil Funktionen des
    +Bot nicht aktiviert sind. (IFDEFs sollten nicht benutzt werden!) Dies
    +ist sofern interessant, das damit die schon vorhandene <I>eeprom.bin</I>
    +weiter genutzt werden kann und schon m&uuml;hsam erstellte werte
    +nicht platt gemacht werden m&uuml;ssen. Eine Garantie ist dies aber
    +nicht, siehe auch Abschnitt <I>Probleme der Implementierung</I>.</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Probleme der
    +Implementierung</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal; font-weight: medium">
    +Leider arbeiten der gcc und er avr-gcc nicht identisch, so da&szlig;
    +die Reihenfolge der Variablen in den eep Dateien von PC und MCU
    +variiert. Auch mein urspr&uuml;ngliches Ziel, einen bin&auml;ren
    +Abzug des EEPROM des Bot direkt in dem Ct-Sim nutzen zu k&ouml;nnen,
    +ist nicht m&ouml;glich. Auch der sch&ouml;ne Gedanke der eeprom_map.h
    +wird dadurch nur teilweise umgesetzt. Es gibt keine Garantien daf&uuml;r,
    +das zuk&uuml;nftige Compiler Versionen nicht auch die Reihenfolge der
    +Variablen im Code &auml;ndern, wenn man sie nur hinten anf&uuml;gt.
    +Auf der sicheren Seite sind Sie nur, wenn das EEPROM initialisiert
    +wird (sprich Sie Ihre alte eeprom.bin l&ouml;schen).<BR>Die
    +Implementierung des EEPROM auf den PC kontrolliert noch nicht, ob
    +nicht 1K an Daten &uuml;berschritten wird. Die Funktionen f&uuml;r
    +den Zugriff aber schon, dh im Moment muss der Programmierer selbst
    +darauf achten, das seine Daten nicht mehr als ein Kilobyte werden.
    +(Sp&auml;testens der avg-gcc wird dann aber meckern).
    +</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Funktionen:</B></P>
    +<P STYLE="margin-bottom: 0cm"><B>Nur in eeprom-emu_pc.c sichtbare
    +Funktionen</B></P>
    +<P STYLE="margin-bottom: 0cm">store_parameter() - Speichern von
    +Informationen im simulierten EEPROM</P>
    +<P STYLE="margin-bottom: 0cm">load_parameter() - Laden von
    +Informationen aus dem simulierten EEPROM</P>
    +<P STYLE="margin-bottom: 0cm"><B>Zugriffsfunktionen f&uuml;r den PC
    +(Identisch zu denen von WinAVR)</B></P>
    +<P STYLE="margin-bottom: 0cm">eeprom_read_byte()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_write_byte()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_read_word()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_write_word()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_write_block()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_read_block()</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3><B>Dateien:</B></FONT></P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>eeprom-emu.h Include
    +Dateinamen mit Funktionsparameter</FONT></P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>eeprom-emu_pc.c Funktionen
    +fuer den ct-Sim</FONT></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Tool: simeetool</B></P>
    +<P STYLE="margin-bottom: 0cm">Damit die Arbeit mit dem Simulierten
    +EEPROM auch noch etwas komfortabler wird, gibt es auch noch das Tool
    +&bdquo;simeetool&ldquo;.</P>
    +<P STYLE="margin-bottom: 0cm"><BR><B>Beschreibung:</B></P>
    +<P STYLE="margin-bottom: 0cm">Mit dem <I>Simeetool</I> kann man
    +komfortable das Simulierte EEPROM (sim-eeprom) ver&auml;ndern und die
    +Initialisierungen der eep-Datei &uuml;bertragen. Durch die Nutzung
    +einer kleinen Konfigdatei und die Erweiterung des Post-Build in
    +eclipse ist es m&ouml;glich f&uuml;r einzelne Variablen den
    +Initialisierungswert aus der entstandenen EEP Datei in das sim-eeprom
    +zu &uuml;bernehmen. Dazu reicht ein Aufruf von simeetool. Auch die
    +gesamte &Uuml;bernahme aller Initwerte ist mit einem Befehl zu
    +realisieren.</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Optionen:</B><BR>set &lt;variable&gt;
    +[size] &Uuml;bertr&auml;gt Werte von PC-EEP in Sim EEPROM</P>
    +<P STYLE="margin-bottom: 0cm">get &lt;variable&gt; [size] &Uuml;bertr&auml;gt
    +Werte vom Sim EEPROM in PC-EEP</P>
    +<P STYLE="margin-bottom: 0cm">flash &Uuml;bertr&auml;gt alle Werte
    +vom PC-EEP ins Sim EEPROM
    +</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Installation:</B></P>
    +<P STYLE="margin-bottom: 0cm">Legen Sie in Eclipse ein neues Projekt
    +mit dem Namen simeetool an und &uuml;bernehmen Sie den Quellkode und
    +&uuml;bersetzen ihn (Oder machen Sie es auf Kommandoebene).<BR>Die
    +Konfigurationdate mit den Namen <I>simeetool.cfg</I> kommt in das
    +gleiche Verzeichnis wie die ausf&uuml;hrbare Datei. Im Anhang finden
    +sie ein Beispiel f&uuml;r <I>copy and paste</I>. ;-) Dies m&uuml;ssen
    +Sie nur noch f&uuml;r sich anpassen.<BR>Damit die ben&ouml;tigten MAP
    +Dateien erzeugt werden m&uuml;ssen Sie unter
    +<I>Project-&gt;Properties-&gt;C/C++ Build-&gt;Build Steps-&gt;Post
    +Build steps </I>folgende Befehle <B><FONT COLOR="#ff0000">zus&auml;tzlich</FONT></B>
    +eintragen. Trennen Sie diese von den vorhandenen mit ;. Diese Datei
    +braucht das Tool f&uuml;r die Adressbestimmung.<BR>WIN32/Linux:
    +objcopy -j .eeprom ct-bot.exe ct-bot.map;objdump -t ct-bot.map &gt;
    +pc-eeprom.map;rm ct-bot.map</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">MCU: avr-objcopy -j
    +.eeprom ct-bot.elf ct-bot.map;avr-objdump -t ct-bot.map &gt;
    +mcu-eeprom.map;rm ct-bot.map</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Konfigurationsdatei:</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">e:/eclipse/ct-bot/ct-bot/debug-mcu-w32/mcu-eeprom.map<BR>e:/eclipse/ct-bot/ct-Bot/Debug-W32/pc-eeprom.map<BR>e:/eclipse/ct-bot/ct-Bot/Debug-MCU-W32/ct-bot.eep<BR>e:/eclipse/ct-bot/ct-Bot/Debug-W32/ct-Bot.eep<BR>e:/eclipse/ct-bot/debug-w32/mcu-eeprom.bin<BR><A HREF="../../../../temp/eeprom.bin">e:/tmp/eeprom.bin<BR></A>####################</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Die ersten sechs
    +Zeilen dieser Datei muessen in der angegebenen</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Reihenfolge die
    +folgenden Daten enthalten:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">1. Zeile:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Absoluter Pfad und
    +Dateiname der MAP Datei fuer das EEPROM des realen ct-bot.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">(mcu-eeprom.map)<BR>2.
    +Zeile:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Absoluter Pfad und
    +Dateiname der MAP Datei fuer das EEPROM des simulierten</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">ct-bot.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">(pc-eeprom.map)<BR>3.
    +Zeile:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Absoluter Pfad und
    +Dateiname der eep Datei des realen ct-bot. (ct-bot.eep)<BR>4. Zeile:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Absoluter Pfad und
    +Dateiname der eep Datei des simulierten ct-bot.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">(ct-bot.eep)<BR>5.
    +Zeile:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Absoluter Pfad und
    +Dateiname der Datei mit einen Abzug des EEPROM des</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">realen ct-bot im
    +Binaer Format. (zB. mcu-eeprom.bin)<BR>6. Zeile:</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Absoluter Pfad und
    +Dateiname der Datei mit dem simulierten EEPROM des</P>
    +<P STYLE="margin-bottom: 0cm"><SPAN STYLE="font-style: normal">des
    +ct-bot fuer den ct-Sim im Binaer Format. (eeprom.bin)<BR></SPAN><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">ACHTUNG!!!</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Als Trenner der
    +Pfade den Slash, wie auch bei *nix benutzen!</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Wie geht&rsquo;s
    +weiter...:</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Das Tool wird
    +sicher noch m&auml;chtiger. Ideen wird&rsquo;s noch eine Menge geben
    +w&auml;hrend man es benutzt. Jeder ist eingeladen dieses Tool zu
    +erg&auml;nzen und weiterzuentwicklen. Bitte la&szlig;t dann auch alle
    +daran teilhaben.</P>
    +</BODY>
    +</HTML>
    Index: pc/eeprom-emu_pc.c
    ===================================================================
    RCS file: pc/eeprom-emu_pc.c
    diff -N pc/eeprom-emu_pc.c
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ pc/eeprom-emu_pc.c	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,179 @@
    +/*
    + * 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 	21.03.07
    +*/
    +
    +#include "ct-Bot.h"
    +
    +#ifdef PC
    +
    +#include <errno.h>
    +#include <io.h>
    +#include <sys/stat.h>
    +#include <fcntl.h>
    +#include <stdio.h>
    +
    +//#include "log.h"
    +
    +extern long _eeprom_start__;
    +
    +#define EEPROM_FILENAME	".\\eeprom.bin" 	/*<! Name und Pfad der EEPROM Datei. Verzeichnis muss existieren. Backslash doppeln!*/
    +
    +/*!
    + * Traegt die uebergebenen Daten in das simulierte EEPROM ein. Dieses simulierte EEPROM
    + * besteht aus einer Datei. Ist sie nicht vorhanden, so wird eine leereangelegt. Sie ist im
    + * Binaer Format und kann direkt mit zB. PonyProg in den realen Bot eingespielt werden.
    + * Es koennen Bytes (uint8 size = 1) und Integer (uint16 size = 2) uebergeben werden.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @param data Daten die abgelegt werden sollen.
    + * @param size Groesse der Daten in Byte.
    + */
    +static void store_parameter(uint16 address, uint16 data, uint8 size) {
    +	int16 fh = 0; 	//Dateizeiger
    +	uint16 i = 0; //Laufvariable
    +	uint8 dataline[2];	//Speicher fuer Datenausgabe
    +
    +	if(address > (size == 1 ? 1023 : 1022)) //Adresse checken
    +		return;
    +
    +	if(access(EEPROM_FILENAME, R_OK) == -1){ //Testen, ob Datei vorhanden ist.
    +		if((fh = open(EEPROM_FILENAME, O_BINARY|O_CREAT|O_RDWR, S_IWRITE|S_IREAD)) == -1) //wenn nicht, dann erstellen
    +			return;
    +		for(i = 0; i < 1024; i++) //Leere EEPROM Datei erstellen
    +			write(fh, "\377", 1);
    +		close(fh);
    +	}
    +	if((fh = open(EEPROM_FILENAME, O_BINARY|O_WRONLY)) == -1) //ansonsten Datei oeffnen
    +		return;
    +
    +	//Daten eintragen
    +	lseek(fh, address, SEEK_SET); //Schreibzeiger setzen
    +	dataline[0] = data%256;
    +	dataline[1] = data/256;
    +	write(fh, dataline, size);	//Daten schreiben);
    +
    +	close(fh);
    +	return;
    +}
    +
    +/*!
    + * Liest die gewuenschten Daten aus eine simulierten EEPROM. Dieses simulierte EEPROM
    + * besteht aus der Datei eeprom.bin. Ist die Datei nicht vorhanden, so wird eine leere angelegt.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @param size Groesse der Daten in Byte.
    + * @return Aus dem EEPROM gelesener Wert.
    + */
    +static uint16 load_parameter(uint16 address, uint8 size) {
    +	int16 fh = 0; 	//Dateizeiger
    +	uint16 i = 0; //Laufvariable
    +	uint8 dataline[2] = {0,0};	//String fuer Datenausgabe
    +
    +	if(address > (size == 1 ? 1023 : 1022)) //Adresse checken
    +		return(0);
    +
    +	if(access(EEPROM_FILENAME, R_OK) == -1){ //Testen, ob Datei vorhanden ist.
    +		if((fh = open(EEPROM_FILENAME, O_BINARY|O_CREAT|O_RDWR, S_IWRITE|S_IREAD)) == -1) //wenn nicht, dann erstellen
    +			return(0);
    +		for(i = 0; i < 1024; i++) //Leere EEPROM Datei erstellen
    +			write(fh, "\377", 1);
    +		close(fh);
    +	}
    +	if((fh = open(EEPROM_FILENAME, O_BINARY|O_RDONLY)) == -1) //ansonsten Datei oeffnen
    +		return(0);
    +
    +	//Daten eintragen
    +	lseek(fh, address, SEEK_SET); //Lesezeiger setzen
    +	read(fh, dataline, size);	//Daten schreiben);
    +	close(fh);
    +	return((uint16)dataline[0] + (uint16)dataline[1]*256);
    +}
    +
    +/*!
    + * Liest ein Byte aus den simulierten EEPROM
    + * @param address Adresse im EEPROM
    + * @return Aus dem EEPROM gelesener Wert.
    + */
    +uint8 eeprom_read_byte(uint8 *adr) {
    +	return((uint8)load_parameter((uint16)((uint32)adr - (uint32)&_eeprom_start__), 1));
    +}
    +
    +/*!
    + * Liest ein Word aus den simulierten EEPROM
    + * @param address Adresse im EEPROM
    + * @return Aus dem EEPROM gelesener Wert.
    + */
    +uint16 eeprom_read_word(uint16 *adr) {
    +	return(load_parameter((uint16)((uint32)adr - (uint32)&_eeprom_start__), 2));
    +}
    +
    +/*!
    + * Schreibt ein Byte in das simulierte EEPROM
    + * @param address Adresse im EEPROM
    + * @param Zu schreibender Wert.
    + */
    +void eeprom_write_byte(uint8 *adr, uint8 value) {
    +	store_parameter((uint16)((uint32)adr - (uint32)&_eeprom_start__), (uint16)value, 1);
    +}
    +
    +/*!
    + * Schreibt ein Word in das simulierte EEPROM
    + * @param address Adresse im EEPROM
    + * @param Zu schreibender Wert.
    + */
    +void eeprom_write_word(uint16 *adr, uint16 value) {
    +	store_parameter((uint16)((uint32)adr - (uint32)&_eeprom_start__), value, 2);
    +}
    +
    +/*!
    + * Liest ein Speicherblock aus dem simulierte EEPROM
    + * @param pointer_ram Adresse im Hauptspeicher
    + * @param pointer_eeprom Adresse im EEPROM
    + * @param Groeße des Block.
    + */
    +void eeprom_read_block (void *pointer_ram, const void *pointer_eeprom, size_t size) {
    +	uint32 i;
    +	uint8 *ram;
    +
    +	ram = (uint8 *)pointer_ram;
    +	for(i=0; i< size; i++){
    +		ram[i]=(uint16)load_parameter((uint16)((uint32)pointer_eeprom - (uint32)&_eeprom_start__ + i), 1);
    +	}
    +}
    +
    +/*!
    + * Schreibt ein Speicherblock in das simulierte EEPROM
    + * @param pointer_ram Adresse im Hauptspeicher
    + * @param pointer_eeprom Adresse im EEPROM
    + * @param Groeße des Block.
    + */
    +void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom, size_t size) {
    +	uint32 i;
    +	uint8 *ram;
    +
    +	ram = (uint8 *)pointer_ram;
    +	for(i=0; i< size; i++){
    +		store_parameter((uint16)((uint32)pointer_eeprom - (uint32)&_eeprom_start__ + i), (uint16)ram[i] ,1);
    +	}
    +}
    +
    +#endif

- Antworten:
  - Re: [ct-bot] EEPROM @ PC
    - From: Timo Sandmann

- Referenzen:
  - [ct-bot] Kaibrierung
    - From: Carsten Giesen
  - [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Achim Pankalla
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Timo Sandmann
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Benjamin Benz
  - [ct-bot] EEPROM @ PC
    - From: Timo Sandmann

- Voriger (Datum): Re[2]: [ct-bot] Fragen zum Framework (Display), Thorsten Thiele
- Nächster (Datum): Re: [ct-bot] EEPROM @ PC, Timo Sandmann
- Voriger (Thread): [ct-bot] EEPROM @ PC, Timo Sandmann
- Nächster (Thread): Re: [ct-bot] EEPROM @ PC, Timo Sandmann
- Indizes:
  - Datum
  - Thread