-         

Ergebnis 1 bis 6 von 6

Thema: 1KB EEPROM im Prozessor

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414

    1KB EEPROM im Prozessor

    Anzeige

    Hallo,
    der ATmega32 besitzt ja intern 1KB eeprom. Die winavr hat dafür auch Funktionen um diesen Bereich anzusprechen und z.B. Vars ins eeprom auszulagern bzw. dort dynamisch Daten zur Laufzeit anzulegen.
    http://www.nongnu.org/avr-libc/user-...r__eeprom.html
    Es gibt aber normalerweise auch die Möglichkeit, ein vorcompiliertes EEP file mit dem GCC zu erstellen und hoch zu laden. Das ist das gleiche HEX Format wie der Programmoutput und schaut z.B. so aus:
    Code:
    :10000000004010502E2C6F4F302A304F6F2C2E2076
    :1000100000060906000000000000000A1F0E040090
    :100020000000000A1F0E04000000000A1F0E04005A
    :100030000000000A1F0E04000000000A1F0E04004A
    :1000400000040404040404000000000A1F0E04005D
    :0100500000AF
    :00000001FF
    Das kann man mit einem ISP-Programmer und AVR-Studio auch ganz einfach direkt in die CPU laden.

    Nu meine Frage.
    Hat es jemand geschafft diese EEPROM Daten über den Robotloader in die CPU zu laden?

    Ich vermute das es mit dem Robotloader nicht gehen wird aber hat denn jemand mal eine Art "EEPROMloaderprogramm" geschrieben, ähnlich wie der Originalbootloader der das EEPROM mit hochladbaren HEX Daten beschreibt? Mit einem Terminal z.B. kann man ja auch Daten/Files an den RP6 senden.

    Ich möchte es mir eigentlich ersparen, die Prozessoren mit ISP zu bearbeiten und so ein Programm würde 1kb Speicher für selten bis garnicht veränderte Konstanten/Variablen bieten, wo bisher RAM oder besser... ProgrammFLASH per PSTR() genutzt wird. Über Deklarationen wie:
    Code:
     const char var[] EEMEM = "0123456789ABCDEF";
    geht es aber auch und wie ich finde... besser!
    Nur müsste man die Daten aus dem .eep halt irgendwie einfach ins eeprom bekommen.
    Hat da jemand schon mal was gebaut?
    Gruß
    Sind Sie auch ambivalent?

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hi RolfD,

    ich denke nicht, dass der RP6-Bootloader das Hochladen von .eep Files unterstützt. SlyD kann das aber sicher beantworten.

    Ich brauche aber meist nur das Schreiben selten veränderter Daten/Konstanten ins EEPROM zur Laufzeit z.B. am Programmanfang, so dass ich die Funktion des Hochladens einer .eep Datei noch nicht vermißt habe.

    Anstelle von Deklarationen wie const char var[] EEMEM = "xy" würde mir auch char EEMEM var[] reichen, wobei ich var dann einmal am Programmanfang fülle. Nachteil ist sicher, dass ich die EEPROM-Konstanten im Flash mitführen muss.
    Bei einem größeren Programm mit mehreren konstanten EEPROM Werten habe ich es dann so gemacht, dass ich die Werte mit einem "Hilfsprogramm" zunächst ins EEPROM geschrieben habe. Das Hauptprogramm hat dann nur noch per Quersumme geprüft, ob die Daten im EEPROM vorhanden sind.

    Aber: Natürlich wäre eine .eep Upload-Funktion per RobotLoader/Bootloader eine feine Sache ...
    Gruß
    Dirk

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hallo,

    Zitat Zitat von Dirk Beitrag anzeigen
    ich denke nicht, dass der RP6-Bootloader das Hochladen von .eep Files unterstützt. SlyD kann das aber sicher beantworten.

    Wäre möglich gewesen und ist sogar im Protokoll vorgesehen, wurde aber nicht mehr eingebaut.
    Beim M256 würds evtl. auch Probleme damit geben, da die ersten 32 Bytes im EEPROM für diverse Einstellungen reserviert sind (der Bootloader überschreibt den Bereich mit Standardwerten wenn die Daten verändert wurden).
    Einstellungen speichern ist Hauptzweck von den internen EEPROMs - also Daten die sich ab und zu mal zur Laufzeit ändern können und ggf. auch unabhängig vom Hauptprogramm erhalten bleiben sollen.
    Gut - man kann da auch konstante Daten drin ablegen, aber das kann man ja wie Dirk schon gesagt hat einfach mit einem kleinen Hilfsprogramm machen.

    Das EEPROM ist AFAIR auch etwas langsamer als das Flash ROM beim Lesen... also für Daten die häufig genutzt werden und sich nie ändern ist das Flash ROM besser.


    MfG,
    SlyD

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Hab mir da mal was zusammen gesucht... vielleicht hilfts ja dem einen oder anderen.

    Im Prinzip stammt der entrümpelte ihex Loader aus der Anleitung für ein Bootloader auf http://www.mikrocontroller.net/artic...ache_Anleitung
    Sinngemäß soll das ihexfile per eeprom_update_block() auf die eepromzellen geschrieben werden.

    Ich hab irgendwo gelesen, das die ersten Bytes (1? 2?) des EEPROM vom nativen Bootloader des RP6/M32 zum steuern von LEDs verwendet werden.
    Irgendwie sollte man verhindern können, das genau diese Adressen von einem epp file überschrieben werden bzw. müsste dafür eine Art "Align" der eeprom-Daten erfolgen. Ich hab aber noch nicht rausgefunden wie das genau geht. Man könnte den Loader vielleicht so umbauen das er die ersten 2 byte im ihex nicht schreibt und eine erste int (nicht zu schreibende) Dummyvariable fürs Alignment vor allen anderen in den Code setzen. Allerdings ist das übelstes Gefrickel, vielleicht hat jemand noch eine andere Idee.* Ich dachte an sowas wie den Section-Eintrag für den Linker bezüglich .eeprom hoch zu drehen oder so.

    *das geht nicht, da der Linker die Variablen nach eigener Vorstellung und nicht chronologisch anordnet.

    Aufgerufen wird das mit:
    Code:
    UART_Mode(UART_ASCII);
    puts_P(PSTR("laedt epp..."));    
    if (import_epp()) puts_P(PSTR("...fertig")); else puts_P(PSTR("...FEHLER"));
    Also zumindest für den Fall das ihr meine UART Lib verwendet
    Die Einstellungen für die UART LIB sind:

    #define WENEEDASCII 1
    #define WENEEDTXXONOFF 1
    #define WENEEDRXXONOFF 1
    #define WENEED7BIT 1
    #define WENEEDCRLF 1

    Man kann dann im Realterm dank xon/xoff über "Send File" das epp File in einem Rutsch hoch laden.
    Mit der alten Lib hab ich es nicht probiert aber wenn man sicher stellen kann das keine Zeichen flöten gehen, gehts auch damit. Wenn...
    Man muss dann nur die getchar() durch readChar mit dieser komischen while not null ersetzen und im Original ist übrigends auch eine xon/xoff Steuerung enthalten.
    Mit der neuen Lib kann man die Zeilen sogar über copy&paste per Robotloaderterminal einfügen... mit der alten weis ich nicht, ich glaube da müsste man noch ein paar \r und \f aus dem Datenstrom fischen. Der Parser kann keine extended Adresses aber er ist nun problemlos nachrüstbar.

    Code:
    #include <avr/eeprom.h>
    
    uint16_t hex2num (const uint8_t * ascii, uint8_t num)
    {
        uint8_t  i;
        uint16_t val = 0;
        for (i=0; i<num; i++)
        {
            uint8_t c = ascii[i];
            if (c >= '0' && c <= '9')            c -= '0';
            else if (c >= 'A' && c <= 'F')       c -= 'A' - 10;
            else if (c >= 'a' && c <= 'f')       c -= 'a' - 10;
            val = 16 * val + c;
        }
        return val;
    }
    
    /* Zustände des Hex-File-Parsers */
    #define PARSER_STATE_START      0
    #define PARSER_STATE_SIZE       1
    #define PARSER_STATE_ADDRESS    2
    #define PARSER_STATE_TYPE       3
    #define PARSER_STATE_DATA       4
    #define PARSER_STATE_CHECKSUM   5
    #define PARSER_STATE_ERROR      6
    #define PARSER_STATE_EXT_SEGMENTADRESS 7
    #define PARSER_STATE_SEGMENTADRESS 8
    #define PARSER_STATE_EXT_LINEARADRESS 9
    #define PARSER_STATE_LINEARADRESS 10
    #define START_SIGN              ':' /* Hex-Datei Zeilenstartzeichen */
    #define IHEXSIZE 255                /* maxbytes per Line, kann kleiner als 255 sein, beim GCC reichen üblicher weise 16 bytes */
    
    /* Zustände des Bootloader-Programms */
    
    uint8_t import_epp ( void ){
        /* Empfangenes Zeichen */
        uint16_t c = 0,
        /* Intel-HEX Zieladresse */
        hex_addr = 0,
        /* Intel-HEX Checksumme zum Überprüfen des Daten */
        hex_check = 0;
        /* Empfangszustandssteuerung */
        uint8_t parser_state = PARSER_STATE_START,
        /* Datenpuffer für die Hexdaten*/
        flash_data[IHEXSIZE],
        /* Positions zum Schreiben in der Datenpuffer */
        flash_cnt = 0,
        /* Position zum Schreiben in den HEX-Puffer */
        hex_cnt = 0,
        /* Puffer für die Umwandlung der ASCII in Binärdaten */
        hex_buffer[5],
        /* Intel-HEX Datenlänge */
        hex_size = 0,
        /* Intel-HEX Recordtype */
        hex_type = 0,
        /* empfangene HEX-Checksumme */
        hex_checksum=0;
    
        while (true) {
            c = getchar();
            switch(parser_state) {
                /* Warte auf Zeilen-Startzeichen */
                case PARSER_STATE_START:
                if((uint8_t)c == START_SIGN) {
                    parser_state = PARSER_STATE_SIZE;
                    hex_cnt = 0;
                    hex_check = 0;
                    flash_cnt = 0;
                }
                break;
                /* Parse Datengröße und prüfen auf Bufferüberlauf */
                case PARSER_STATE_SIZE:
                hex_buffer[hex_cnt++] = (uint8_t)c;
                if(hex_cnt == 2) {
                    parser_state = PARSER_STATE_ADDRESS;
                    hex_cnt = 0;
                    hex_size = (uint8_t)hex2num(hex_buffer, 2);
                    hex_check += hex_size;
                }
                break;
                /* Parse Zieladresse */
                case PARSER_STATE_ADDRESS:
                    hex_buffer[hex_cnt++] = (uint8_t)c;
                    if(hex_cnt == 4) {
                        parser_state = PARSER_STATE_TYPE;
                        hex_cnt = 0;
                        hex_addr = hex2num(hex_buffer, 4);
                        hex_check += (uint8_t) hex_addr;
                        hex_check += (uint8_t) (hex_addr >> 8);
                    }
                break;
                /* Parse Zeilentyp */
                case PARSER_STATE_TYPE:
                    hex_buffer[hex_cnt++] = (uint8_t)c;
                    if(hex_cnt == 2) {
                        hex_cnt = 0;
                        hex_type = (uint8_t)hex2num(hex_buffer, 2);
                        hex_check += hex_type;
                        switch(hex_type) {
                            case 0: parser_state = PARSER_STATE_DATA; break;
                            case 1: parser_state = PARSER_STATE_CHECKSUM; break;
                            case 2: parser_state = PARSER_STATE_EXT_SEGMENTADRESS; break;
                            case 3: parser_state = PARSER_STATE_SEGMENTADRESS; break;
                            case 4: parser_state = PARSER_STATE_EXT_LINEARADRESS; break;
                            case 5: parser_state = PARSER_STATE_LINEARADRESS; break;
                            default: parser_state = PARSER_STATE_ERROR; break; //reading bullshit
                        }
                    }
                break;
                
                case PARSER_STATE_EXT_SEGMENTADRESS:
                // Tag für RP6 überlesen
                    parser_state = PARSER_STATE_START;
                break;
    
                case PARSER_STATE_SEGMENTADRESS:
                // Tag für RP6 überlesen            
                    parser_state = PARSER_STATE_START;            
                break;
                
                case PARSER_STATE_EXT_LINEARADRESS:
                // Tag für RP6 überlesen            
                    parser_state = PARSER_STATE_START;
                break;
                
                case PARSER_STATE_LINEARADRESS:
                // Tag für RP6 überlesen            
                    parser_state = PARSER_STATE_START;
                break;            
    
                /* Parse Flash-Daten */
                case PARSER_STATE_DATA:
                    hex_buffer[hex_cnt++] = (uint8_t)c;
                    if(hex_cnt == 2) {
                        hex_cnt = 0;
                        flash_data[flash_cnt] = (uint8_t)hex2num(hex_buffer, 2);
                        hex_check += flash_data[flash_cnt++];
                        if (hex_size==flash_cnt) parser_state = PARSER_STATE_CHECKSUM;
                    }
                break;
                /* Parse Checksumme */
                case PARSER_STATE_CHECKSUM:
                    hex_buffer[hex_cnt++] = (uint8_t)c;
                    if(hex_cnt == 2) {
                        hex_checksum = (uint8_t)hex2num(hex_buffer, 2);
                        hex_check += hex_checksum;
                        hex_check &= 0x00FF;
                        /* Überprüfe Checksumme -> muss '0' und die angegebene Datenmenge vorhanden sein */
                        if(hex_check == 0) {
                            if(hex_type == 1 ) return true;
                            eeprom_update_block(&flash_data, (void *)hex_addr, hex_size);
                            parser_state = PARSER_STATE_START;
                        } else parser_state = PARSER_STATE_ERROR;
                    }
                break;
                /* Parserfehler (falscher Zeilentyp oder Datenfehler) */
                case PARSER_STATE_ERROR:
                    return false;
                break;
                default:
                break;
            }
        }
    }
    Ich möchte übrigends die Geschichte benutzen um ab und zu Zeichentabellen fürs LCD Display im EEPROM abzulegen die bei Displayinit() auf das Display geladen werden. Solche Zeichen ändern sich ab und an aber nicht bei jedem Programmstart... und da es 8x8 Byte sind, die im Programmspeicher oder RAM nix verloren haben, sind sie im internen EEPROM auch bestens aufgehoben. Die Nutzung vom EEPROM als nichtflüchtigen Speicher hat erst mal nichts mit Konstanten oder Vars zu tun, da lasse ich mich auch nicht auf ein Definitionsgerangel um Haarspaltereien ein. Bekanntlich sind Daten, die ich zur Compile Zeit im RAM oder auf PGM anlege und dann aufs eprom schreibe zunächst 2 mal im System vorhanden und ich muss mich zusätzlich um deren Adressmanagement incl. copieren kümmern. Alles Dinge die mir der Compiler bei Nutzung der entsprechenden Direktiven abnehmen würde. Das man das auch "zu Fuß" machen kann... klar... aber warum soll ich Kompromisse eingehen und Fehlerquellen akzeptieren, wenn ich nicht zwingend muss?

    @Slyd hmm.. also grade bei der M256 wäre es dann besonders interessant, wie man die ersten Bytes blockt/reserviert damit GCC nicht die Daten auf EEPROM Adresse 0x0000 legt. Hatte den Post erst gesehen nachdem ich abgeschickt hab. Aber Du bist schon auf das Problem am Rande eingegangen. Es wäre aber besser gewesen, die Bootloaderdaten am Schluß des EEPROMS anzulegen so das die Compilerdaten und Bootloaderdaten wie bei Stack und Vars im Ram entgegen wachsen können.
    Naja da is nu nichts mehr dran zu ändern... aber falls du mal ein RP7 auflegen solltest... *schmunzels

    OK Auf Grund der Überlegungen und Infos noch mal der Hinweis: Man sollte überlegen ob man den Code in der aktuellen Fassung bzw. die Vorgehensweise mit EEMEM so benutzt. Auf der M256 zerschiesst man sich vermutlich damit die (Wlan-Netzwerk?)-Einstellungen, auf den kleineren Boards die LED Steuerung des Bootloaders. Bitte die Vorgehensweise aus dem NACHTRAG mit EEPMEM anwenden.

    NACHTRAG:
    Ich hab eine Möglichkeit gefunden bezüglich der ersten Bytes im EEPROM.
    Man legt eine neue Section an indem man dem Linker im AVR Studio Projekt bei Memory Settings unter EEPROM Segment ohne " einträgt: ".realeep=0x810020"
    Das ist vergleichbar mit -Wl,-section-start=.realeep=0x810020 im Makefile.
    Dann definiert man im .h File mit #define EEPMEM __attribute__((section(".realeep")))
    ein neues Segmentarttribut und gibt das z,.B. als const uint8_t chrdata0[8] EEPMEM = {data...}; an.
    Const weil es vom normalen Code aus nicht beschreibbar ist. Man kann selbstverständlich mit den eeprom Funktionen aus eprom.h die Daten auch händisch lesen und beschreiben. Aber z.B. eine weitere Wertezuweisung ausserhalb von epp Dateien sollte der Compiler schon durch die Type Prüfung nachhaltig verhindern da man zum beschreiben der EPROMZellen eben mehr als nur eine Zusweisung braucht!
    Das resultierende epp file sieht dann so aus:
    Code:
    :02000004008179
    :100020002E2C6F4F302A304F6F2C2E2000000006F0
    :100030000906000000000000000A1F0E0400000076
    :10004000000A1F0E04000000000A1F0E040000003A
    :10005000000A1F0E04000000000A1F0E0400000426
    :100060000404040404000000000A1F0E0400000041
    :100070000000000000000000000000000000000080
    :0F00800000000000000000000000000000000071
    :00000001FF
    Man sieht, das in der ersten Zeile nun der Befehlscode 04 (Lienaradressextension) verwendet wird was in in dem import_epp(); durch case 4: parser_state = PARSER_STATE_ERROR; break; //PARSER_STATE_EXT_LINEARADRESS noch zu einem Error führt weil das setzen der virtuellen Adresse 0x810020 nicht umgesetzt ist. Das werde ich dann noch korrigieren. <-[erledigt, Tags mit Adressfeldern werden nun überlesen]
    Damit sind aber im Programm selbst alle Adressen im Eeprom ab 0x810020 alloziiert und das import_epp(); wird das dann auch beim Schreiben der Daten berücksichtigen. Dann besteht auch die Gefahr des Überschreibens der eeprom Daten des Bootloaders nicht mehr. Zumindest so lange man die Finger von EEMEM lässt und stattdessen dann EEPMEM nutzt.
    So kommt man nun an die Vars einfach und problemlos dran...
    Code:
    const uint16_t reboot_counter_ee EEPMEM;
    uint16_t reboots = eeprom_read_word(&reboot_counter_ee); //das konnte man bisher auch von Hand als Hex... oder #define
    reboots++;
    eeprom_write_word(&reboot_counter_ee, reboots); //das geht auch trotz const 
    printf("Wir haben %d mal gebootet.\n",reboot_counter_ee); //das geht nun auch und spart Code&Platz weil ich die Daten nicht mehr zwischenlagern muss!!!
    reboot_counter_ee=0; //das muss der compiler natürlich verhindern...
    Gruß
    Geändert von RolfD (20.05.2014 um 08:52 Uhr)
    Sind Sie auch ambivalent?

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hallo,

    hab noch nie einen Compiler automatisch Daten in ein EEPROM legen lassen - das mache ich per Hand. Für die paar Datenbereiche ist das ja kein großer Aufwand.
    Sonst ändert man irgendwas am Programm, fügt Variablen hinzu oder sowas oder nimmt ne neue Compiler Version und evtl. liegen die Daten dann doch wieder an einer ganz anderen Stelle im EEPROM und die da bereits (schon von der letzten Programmversion) gespeicherten Werte sind ungültig...


    > wie man die ersten Bytes blockt/reserviert damit GCC nicht die Daten auf EEPROM Adresse 0x0000 legt.
    >

    Man kann sicher die eeprom section umlegen - muss man dem Linker sagen.
    (such mal im Makefile nach "section" und ".eeprom")



    > Auf der M256 zerschiesst man sich vermutlich damit die (Wlan-Netzwerk?)-Einstellungen
    >


    Nö (die Netzwerkeinstellungen werden im Flash ROM des WLAN Funkmoduls gespeichert), nur die Einstellungen die den Mikrocontroller und den Bootloader bzw. (optionalen) 2nd stage Bootloader betreffen. Und wie gesagt, das bekommt der Bootloader mit wenn man da dran rumpfuscht und überschreibt dass dann wieder mit den Standardwerten also passiert nix schlimmes dabei
    Die LED/LCD Steuerung ist nur LEDs an/aus. Man kann z.B. auch die WLAN Baudrate anpassen und da es im EEPROM liegt, bekommt das auch die M256 Lib mit - so können Bootloader und Hauptprogramm die gleiche Baudrate (fürs WLAN Modul) verwenden und man kann das direkt im RobotLoader umstellen.



    MfG,
    SlyD

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Ja unsere Posts haben sich überschnitten, Lösung im Nachtrag letzter Post von mir Mittels "section".
    Die geänderte Fassung welche sich nicht an der Linearadresse stört liefer ich noch nach. <-[erledigt]

    hab noch nie einen Compiler automatisch Daten in ein EEPROM legen lassen - das mache ich per Hand.
    Naja bisher war das auch schwierig wegen der Adressen die vom Bootloader überschrieben werden aber mit dem Wissen kriegst Du das jetzt auch hin

    Ok wenn man weiss das eeprom-Bytes vom Bootloader "verseucht" sind kann man natürlich einfach ein genulltes Array an den Anfang von EEMEM setzen und das Array eben im Programm einfach nicht nutzen. Du sagst ja das es im Prinzip dann aufs neu setzen der Werte vom Bootloader im eeprom hinaus läuft nachdem ein eep File geschrieben wurde. Das muss jeder selbst wissen aber mir gefällt die Lösung mit der Section ohne überschreiben der Bootloaderdaten besser.
    In meinem Prozessor herrscht Ordnung!
    Gruß

    NACHTRAG:
    Was bei mir sehr gut klappt ist die Nutzung des EPP / PROGMEM über ein #define umschaltbar zu machen.
    So ist zu Testzwecken das normale Flashmemory nutzbar und wenn man eine epp Version bauen will, reicht es die defines umzukommentieren.
    Es erspart also die Notwendigkeit wärend der Entwicklung dauernd das epp-file hochladen zu müssen. (War als Kritikpunkt für epp ja angesprochen.)
    Code:
    // Speicherconfig: in der RP6CONTROLLIB.H einfügen
    
    #define MEMORY 0 /*0=PROGMEM,1=EEPMEM,2=EEMEM*/
    
    #if MEMORY==0
    #define MEM PROGMEM
    #elif MEMORY==1
    #define EEPMEM __attribute__((section(".realeep")))
    #define MEM EEPMEM
    #elif MEMORY==2
    #define MEM EEMEM
    #endif
    ----3<---
    // im Programm irgendwo nutzen...
    const char lcd_wheelchar[] MEM = ".,oO0*0Oo,. "; // sinnvoll wäre auch noch const char wheel[] = "0123456789ABCDEF";
    const uint8_t LCDLineAdr[] MEM = {LCD_START_LINE1, LCD_START_LINE2, LCD_START_LINE3, LCD_START_LINE4};
    ----3<---
    //in der Init Funktion in RP6CONTROLLIB.C einfügen
        UART_Mode(UART_INIT);
    #if    MEMORY!=0
    #ifndef WENEEDASCII //// damit xon/off im Ascii mode meiner uartLib funktioniert auch wenn sie nicht configuriert ist 
    #define WENEEDASCII 1
    #endif
    #ifndef WENEEDTXXONOFF
    #define WENEEDTXXONOFF 1
    #endif
    #ifndef WENEEDRXXONOFF
    #define WENEEDRXXONOFF 1
    #endif
    #ifndef WENEED7BIT
    #define WENEED7BIT 1
    #endif
    #ifndef WENEEDCRLF
    #define WENEEDCRLF 1
    #endif
        UART_Mode(UART_ASCII);
        puts_P(PSTR("load epp...[x]"));
        if (import_epp()) puts_P(PSTR("ok")); else {
            puts_P(PSTR("ERROR"));
            while(1);
        }
        UART_Mode(UART_RP6);
    #endif
    ----3<---
    // in der import_epp() , liegt bei mir derzeit in der uartlib
        while (true) {
            c = getchar();
            if (c=='x') return true; // <- die Zeile neu einfügen
            switch(parser_state) {
    ----3<---
    //verarbeiten kann man die Daten z.B. so
    #if MEMORY==0        
            eeval = pgm_read_byte(&chrdata[i]);
    #else
            eeval = eeprom_read_byte(&chrdata[i]);
    #endif
    Man kann die import_epp() Funktion übrigends auch gut aus dem Init der Unit nach der Initialisierung von stdio aufrufen und den Import mit Prüfung auf ein esscape char abbrechen wenn man das eeprom nicht neu beschreiben möchte (ändert sich ja nicht dauernd was).
    Wenn man dann auch noch über Preprozessorbefehle testet ob überhaupt EE(P)MEM genutzt wird und ggf. den Import_epp Code ausschließt, hat man alles beisammen um flüssig mit EPP zu arbeiten, aber keinen zusätzlichen Code bei Nutzung von PROGMEM. Damit wird bei Programmstart & Nutzung von EEPROM immer erst das abbrechbare Laden des epp angeboten.
    Da die Importfunkton nicht größer 1kb ist, hat man allein durch auslagern von Strings in jedem Fall ein Platzgewinn und wenn man die Importfunktion nicht mehr braucht kann man sie auskommentieren. Wie am Codebeispiel oben zu sehen, alles mit einer einzigen Ziffer (0,1,2) einstellbar. Also 1 KB mehr Platz für Constanten bzw. Code letztlich ohne eine einzige Zeile Code mehr! Eigene.. "händisch" verwaltete Daten (deren Verwaltung sicher Codezeilen kosten!!) kann man zudem in der Adressierung als Topdown Model anlegen.. also "von oben runter". Dann besteht auch kaum die Gefahr das sich die Compilervars und die eigenen im Speicher begegnen da der Compiler die Daten als Bottomup ablegt.
    Geändert von RolfD (21.05.2014 um 18:26 Uhr)
    Sind Sie auch ambivalent?

Ähnliche Themen

  1. [ERLEDIGT] EEPROM - leer / .eep Datei ins EEPROM schreiben
    Von dj_cyborg im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 25.08.2013, 20:50
  2. Prozessor
    Von grizzly im Forum Elektronik
    Antworten: 17
    Letzter Beitrag: 23.06.2010, 16:12
  3. Neuer Prozessor
    Von frank1210 im Forum Asuro
    Antworten: 6
    Letzter Beitrag: 30.12.2009, 18:30
  4. Prozessor
    Von letori im Forum Robby CCRP5
    Antworten: 1
    Letzter Beitrag: 16.03.2008, 18:20
  5. ATmega8 aus dem EEPROM lesen und ins EEPROM Schreiben
    Von melowtrax im Forum AVR Hardwarethemen
    Antworten: 6
    Letzter Beitrag: 20.02.2006, 23:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •