www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ARM LPC2138 & IAP (internen Flash schreiben/lesen)


Autor: Knecht Ruprecht (Firma: Weihnachtsmann GmbH) (ruprecht)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich versuche seit geraumer Zeit ein paar Variablen vor dem Neustart des 
LPC2138 in den Flash zu speichern. Hat jemand IAP bei seinem LPC am 
laufen und könnte hier ein komplettes Beispiel posten?

Da wäre ich sehr dankbar für!

Autor: Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo K.R.,

ich hab grade meinen iap treiber fertig. Wenn er fertig kommentiert ist, 
kann ich ihn dir gerne hier verlinken ;)

Autor: Knecht Ruprecht (Firma: Weihnachtsmann GmbH) (ruprecht)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre ja super! Ich hab schon das halbe Netz ohne Erfolg durchsucht. 
Außer dem EE_Demo.zip (welches mit meinem Compiler nicht läuft) gab es 
leider nix. Dann warte ich mal.....

Autor: Magnus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab ihn nun mal schnell zusammen gezippt, zusammen mit ner 
Readme.txt.
Hoffe, es hilft dir weiter.

--Magnus

Autor: Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S. Wenn Fragen sind: Immerzu... Ich steck ja grade noch voll IN der 
Materie und seh fehlende Hinweise noch nicht wirklich ;)...
Wenn du fehler findest, bin ich ebenso offen für Kritik!
(Wenn dann solls ja vernünftig sein...)

Autor: Knecht Ruprecht (Firma: Weihnachtsmann GmbH) (ruprecht)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Magnus,

erst einmal vielen Dank für deine Hilfe!
Das einzige was mir bisher aufgefallen ist -> In der iap.c wird Zeile 
194 angemeckert (statement is unreachable).

Ich habe gerade noch das define für den LPC2138 abgeändert:
#ifdef USING_LPC2138
//----- sector numbers for LPC2129
  if((addr >=0x00008000) && (addr <= 0x0000FFFF))
  {  return 8;   }
  if((addr >=0x00010000) && (addr <= 0x00017FFF))
  {  return 9;   }
  if((addr >=0x00018000) && (addr <= 0x0001FFFF))
  {  return 10;   }
  if((addr >=0x00020000) && (addr <= 0x00027FFF))
  {  return 11;   }
  if((addr >=0x00028000) && (addr <= 0x0002FFFF))
  {  return 12;   }
  if((addr >=0x00030000) && (addr <= 0x00037FFF))
  {  return 13;   }
  if((addr >=0x00038000) && (addr <= 0x0003FFFF))
  {  return 14;   }
  if((addr >=0x00040000) && (addr <= 0x00047FFF))
  {  return 15;   }
  if((addr >=0x00048000) && (addr <= 0x0004FFFF))
  {  return 16;   }
  if((addr >=0x00050000) && (addr <= 0x00057FFF))
  {  return 17;   }
#endif
Nur wofür ist dann diese #define IAP_LOCATION  0x7FFFFFF1 Definition? 
Liege ich da nicht hinter den eben von mir aufgelisteten 
Adressbereichen?

Muss ich eigentlich vor iap_Write ein iap_Erase auf den gleichen 
Adressbereichen durchführen?

Kannst du mir vielleicht noch ein kurzes Beispiel für das Schreiben und 
Löschen einer Variable in den Flash geben?

Gruß Ruprecht

Autor: Magnus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hej K.R.,

bitte, bitte, freut mich, wenn auch ich einmal Hilfe geben kann und sie 
nicht nur in Anspruch nehme ;)...

Hmm, komisch, bei mir meckert der Compiler nicht o_O...
Hab den Gnu-Arm 4.1.1.
Vllt hast du eine andere Version?

Ein Beispiel habe ich dir angehängt.
Damit hab ich die Routinen gestest, um auf nummer sicher zu gehen, hab 
ich danach ein simple LED-blink programm nur ins RAM geladen und danach 
mit dem Debugger mir den Speicherbereich von 0x00008000 angesehen.


Die
#define IAP_LOCATION  0x7FFFFFF1

Anweisung muss so sein, das geht aus dem manual hervor. (siehe mal hier 
in der Appplication note: 
http://www.standardics.nxp.com/support/documents/m...)
Grund dafür ist, dass der interne IAP/ISP Bootloader code an diesen 
Speicherbereich gemappt wird. (steht irgendwo in der Flash Memory 
Übersicht im Manual)

Ins Zip packe ich dir auch die uart-init und so weiter.
Dann kannst du dir übers Hyperterminal die Ausgaben ansehen (38400 8N1 
keine Flusssteuerung).
Lass dich dabei nicht von den Buffer-Fkt. beirren, die sind dafür da, 
wenn man die UART in einem kleinen Multitasking system nutzen will ;). 
Du braucht nur die Init wenn nötig anzupassen und eventuell die 
UART1_IO_Send_Char(). Die UART1_IO_Send_String() hab ich nachträglich 
eingefügt.


viel Spaß damit!

Autor: Knecht Ruprecht (Firma: Weihnachtsmann GmbH) (ruprecht)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Magnus,

wieder einmal tausend Dank für deine Hilfe!

Mein Compiler ist der RealView MDK-ARM Version: 3.22a
und dieser bemängelt auch immer noch iap.c Zeile
194 (statement is unreachable).
Womit er auch recht hat, da (bei mir zumindest) die Interrupts nicht 
wieder angestellt werden. Ich habe die "VICIntEnable = buffer_vic;" 
Zeile jetzt in die "Great Success" Klammerung geschoben. So läuft im 
Normalfall zumindest alles reibungslos.

Weiter mit den Erfolgen:
iap_Erase und iap_Write verkünden nach Abarbeitung ihres Codes "Sector 
successfully erased" bzw. "Data successfully written!".

...und jetzt die letzte, triviale Frage:
(Mein erstes Embedded Projekt,... bitte um Verzeihung)
Wie lese ich den Inhalt der Adresse wieder aus???

Autor: Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen ;),

also... ja... da war was... ich hab das irgendwann mal geschafft mit 
Hilfe des folgenden Threads:

Beitrag "LPC2148: Lesen von Flash nach Schreiben via IAP"


Danach ist irgendwann mein Rechner abgekackt, die Festplatte war hinüber 
und der Code natürlich nicht mehr da. Leider hab ich keine Ahnung mehr, 
WAS ich verändert habe, aber ich werd mich mal dran setzen, da ich auf 
kurz oder lang die gleiche Funktion wieder brauche ;)...

Falls du schneller sein solltest, lass mich den Trick wissen ;)

Beim Durchstöbern des Forums bin ich grad auch noch auf diesen Thread 
gestoßen:

Beitrag "IAP mit LPC2xxx"

wobei ich grad nicht weiß, ob das weiter hilft (ist einfach noch zu früh 
am morgen :P)

Kannst du mir noch eine Sache verraten? Was meinst du mit "Great 
Success"-Klammerung?

VG

--Magnus

Autor: Knecht Ruprecht (Firma: Weihnachtsmann GmbH) (ruprecht)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin Magnus,

dein Code:
      else
      {
        #ifdef DEBUG        
        UART1_IO_Send_String("\nData successfully written! \n\r ");
        #endif        
        return 0;      
      }
    }
  }
  VICIntEnable = buffer_vic;    // set back ints
}
mein Code:
      else
      {
        lcd_clear();
        set_cursor (0, 1);
        lcd_print (" Data successfully  ");
        set_cursor (0, 2);
        lcd_print (" written on FLASH!  ");
        waiting_for_the_eye();  
        VICIntEnable = buffer_vic;    // set back ints  
        return 0;      
      }
    }
  }
}

Danke für die beiden Threads. Ich probiers mal und melde mich dann!

Autor: Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahhhh, ok, verstehe ;)


Ich hab mir das noch mal angesehen und probiere die ganze Zeit mein 
Glück mir dem lesen. so in etwa müsste das aussehen:

unsigned long *addr = NULL;
char buf[512];
int k=0;
int i=0;
  
addr = (unsigned long *) 0x8000; // die adresse, an der zuvor irgendwann ein Teststring gespeichert wurde

for(k=0, i=0; k < 16; k++, i=i+4)
{
    buf[k] = *(addr+i);  
    UART1_IO_Send_Char(buf[k]);  // damit man mal was sieht ;)
}


Ein buffer, in den eingelesen wird, und dann eine Schleife, die in jedes 
Bufferelement den Wert der Speicherstelle schreibt, wobei sich der 
buffer logischerweise immer um eins erhöht, während die Adresse sich um 
4 erhöht.

Aber irgendwie kommt an meiner seriellen Schnittstelle nur Murks raus...
"Ir<LEERZEICHEN>"

(Der eingespeicherte Text ist immer noch "Ich fahre mit der Luftbahn 
durch die Nacht, und dass er sehr wohl im Speicher steht, habe ich mit 
dem RAM-LED-Testprogramm auch nachgesehen (denn dann funktioniert auch 
mein Debugger, bei Programmen im Flash zickt der immer rum.
Vllt schaffst du es das Problem zu lösen, ich komme momentan nicht mehr 
drauf, wie ich es damals gemacht habe :( und mir läuft die Zeit grade 
ein wenig davon...

Autor: Knecht Ruprecht (Firma: Weihnachtsmann GmbH) (ruprecht)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Magnus,

sorry, dass ich mich solange nicht gemeldet habe, aber dafür habe ich 
die Lösung:
char *addr = NULL;

addr = (char *) 0x00010000;
for(i=0; i < 16; i++)
{
    OnFlash[i] = *(addr+i);  
}
Viele Grüße und noch einmal ein dickes Dankeschön für die viele Hilfe!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.