Flash-ROM in C beschreiben und auslesen



  • Hallo,

    möchte in einem Mikrocontroller-Projekt in C auf Daten aus einem Flash-ROM zugreifen bzw. diese überschreiben. Nun ist Flash ja nicht wie RAM, sondern es müssen z.B. bestimmte Bitfolgen geschrieben werden, um überhaupt darauf zugreifen zu können. Gibt es für sowas schon Treiber, die man nur modifizieren muss? Ich habe im Moment leider gar keine Ahnung wie ich so etwas angehe. Kann mir jemand Tipps geben?

    Gruß

    seventh_son



  • Du solltest erstmal sagen was du hast und nicht einfach Flash rom. Die gibt es wie sand am Meer.
    Bissel mehr informationen 😉

    MfG schirrmie



  • Aber gerne doch.

    Ich programmiere einen MicroBlaze-Softcore-CPU. Der Flashbaustein ist ein AM29LV640D und hängt am On-Chip-Peripheral-Bus.



  • Dann würde ich mal in das Datenblatt vom Flash schauen.

    Da steht der Befehlssatz. Normalerweise gibst du dem Flash über Schreibvorgänge von bestimmten Werten an Bestimmte Aderessen in einer bestimmten Reihenfolge einen Befehl. z.B. einen Programmierbefehl. Danach kannst Du dann eine Speicherstelle mit einem Wert beschreiben.

    Löschen geht immer nur Blockweise. Löschen bedeutet, dass der Speicher komplett mit 0xFF beschrieben wird. Beim Programmieren können dann einzelne Bits auf 0 gesetzt werden.



  • Ach so und denk dran, dass Dein C-Programm natürlich nicht aus demselben Flash laufen darf, dass Du programmieren willst 😉



  • Danke, so ähnlich hatte ich das auch bisher verstanden. Das Datenblatt hab ich hier.

    Also schreibt man sich am besten Funktionen wie "WriteFlashAdress", oder?

    Leider wird in dem Flash sehr wohl auch das Programm abgelegt. Aber man kann einfach aufpassen, dass sich die jeweiligen Adressbereiche nicht überschneiden, oder? Zur Laufzeit wird das Programm ja eh ins RAM geladen.



  • Genau.

    Aber warum sollte der Code ins RAM geladen werden? Genau dafür musst du sorgen, wenn Du das so machen willst. Aber normalerweise wird der Code direkt aus dem Flash ausgeführt, wäre ja sonst auch RAM-Veschwendung. Denk dran, das ist kein PC und der Flash-Speicher ist keine Festplatte 😉



  • Ich meine die Geschichten die zur Laufzeit passieren, Variablen auf dem Stack erstellen etc. Er kann ja zur Laufzeit nicht ins Flash-ROM schreiben.



  • By the way, wie kann er das Programm aus dem Flash-ROM ausführen? Zum Lesen des Flash braucht es ja auch bestimmte Befehls-Kombinationen, oder nicht? Der Prozessor kann also doch gar nicht so einfach darauf zugreifen, wie er es mit dem RAM macht.



  • seventh_son schrieb:

    By the way, wie kann er das Programm aus dem Flash-ROM ausführen? Zum Lesen des Flash braucht es ja auch bestimmte Befehls-Kombinationen, oder nicht? Der Prozessor kann also doch gar nicht so einfach darauf zugreifen, wie er es mit dem RAM macht.

    wenn dein controller die adress/daten/steuerbusse nach aussen geführt hat, dann kannst du dort speicherchips anschliessen, die im adressraum der CPU sichtbar sind und dann kann sie auch code von dort ausführen.
    lies dir einfach das datasheet genau durch 😉
    aber, wie schon gesagt wurde: wenn du den flash-chip umprogrammieren willst, muss sich die programmierfunktion im RAM befinden. eventuell ist der flash in 'banks' unterteilt, so dass code der in einer bank läuft, eine andere programmieren kann.
    das müsste aber alles im datenblatt genau beschrieben sein, also RTFM 😉



  • Hallo,

    der Adressraum ist natürlich fest vergeben und für die CPU auch sichtbar. Aber wie soll die CPU das Programm aus dem Flash laden, wenn sie nicht weiß mit welcher Befehlsfolge sie darauf zugreifen kann? Sie kann eben nicht wie im RAM befehlen "Lese von Adresse 0xff000", da zum Lesen aus dem Flash eine bestimmte Folge an Schreibbefehlen abgearbeitet werden muss.

    Von daher gehe ich davon aus, dass das Programm eben im RAM abgearbeitet werden muss. Kann natürlich durchaus sein dass ich dafür sorgen muss, dass das auch so passiert.

    Deinen Post verstehe ich nicht ganz. Kannst du das bitte nochmal genauer erklären?



  • Hallo nochmal,

    ich habe einen Denkfehler gemacht. LESEN kann die CPU den Speicher natürlich ohne besondere Kommandos. Von daher habt ihr Recht.

    Trotzdem würde mich interessieren, wie man genau z.B. einen Programmier-Befehl für das Flash in C realisiert. Könnte das vielleicht mal jemand posten? Wäre super!

    Das Datenblatt findet sich unter

    http://www.datasheetarchive.com/datasheet.php?article=780262



  • seventh_son schrieb:

    Das Datenblatt findet sich unter
    http://www.datasheetarchive.com/datasheet.php?article=780262

    warum liest du es denn nicht 😕
    da steht doch alles drin...



  • Ich habe das Datenblatt gelesen und auch die Tabelle mit den entsprechenden Kommandos gefunden.

    Meine Frage ist nun, wie man das in C-Code umsetzt.

    Das Beschreiben der Adressen mit den nötigen Werten zur "Entriegelung" des Flash soll ja laut Datenblatt taktgenau erfolgen. Wie kann ich das in C realisieren?

    Da reicht ja wahrscheinlich nicht einfach

    int *p=0xC00555;
    *p=0xAA;   //Erster Takt für Write-Command
    
    p=0xc002AA;
    *p=0x55;   //Zweiter Takt für Write-Command
    

    Im Prozessor sind das ja sicher mehr als zwei Takte.

    Es wäre nett wenn mir hier jemand einfach mal einen kurzen Beispielcode postet. Ich stehe auf dem Schlauch.



  • Hmne, nene, das ist CPU-abhängig.

    In C ist das schwierig. Du solltest halt Interrupts verbieten und dann musst du dir was ausdenken wie du den Code ins RAM bekommst. Da gibt es Entwicklungstools-abhängiges Zeugs für. Oder du schreibst es in ASM und kopierst es dir einfach selber ins RAM und springst dann dorthin.



  • So, ich habe es nun halbwegs hinbekommen. Hier mein Code. Die einzelnen Aktionen bestehen aus mehreren Kommandos, um das Flash zu entriegeln.

    Im ersten Block wird die Device-ID ausgelesen, was auch funktioniert. Die Variable f enthält danach den richtigen Wert.

    Im zweiten Block wird programmiert. Laut Debugger wird der Wert aber nicht einmal, sondern in zwei aufeinanderfolgende Adressen geschrieben. Wenn ich den Wert in die Variable f auslesen möchte, kommt IMMER der Wert 32 heraus, egal ob und was ich vorher in die Adresse programmiert habe. Woran könnte das liegen?

    Der Sector Erase im dritten Block funktioniert wiederum.

    unsigned short f=0;
    
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x00AA; //Auto Select Sequence
    *((unsigned short*)(0xC00000L + 2 * 0x02AA)) = 0x0055;
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x0090; 
    f=*((unsigned short*)(0xC00000L + 2 * 0x0001)); //Get DeviceID
    *((unsigned short*)(0xC00000L + 2 * 0x0010)) = 0x00F0; //Reset
    
    f=0;
    
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x00AA;//Write Command Sequence
    *((unsigned short*)(0xC00000L + 2 * 0x02AA)) = 0x0055;
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x00A0;
    *((unsigned short*)(0xC00000L + 2 * 0x0002)) = 0x0001;// Schreibe Wert 1 in Adr.
    f=*((unsigned short*)(0xC00000L + 2 * 0x0002)); //Lese Wert zurück: f=32
    
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x00AA;//Sector Erase Command
    *((unsigned short*)(0xC00000L + 2 * 0x02AA)) = 0x0055;
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x0080;
    *((unsigned short*)(0xC00000L + 2 * 0x0555)) = 0x00AA;
    *((unsigned short*)(0xC00000L + 2 * 0x02AA)) = 0x0055;
    *((unsigned short*)(0xC00000L + 2 * 0x0000)) = 0x0030;
    




  • Danke, aber wo liegt jetzt mein Fehler? Die Kommandos an sich müssen ja stimmen, sonst dürfte der Erase und das Auslesen der IDs nicht klappen.


Anmelden zum Antworten