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


von Knecht R. (Firma: Weihnachtsmann GmbH) (ruprecht)


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!

von Magnus (Gast)


Lesenswert?

Hallo K.R.,

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

von Knecht R. (Firma: Weihnachtsmann GmbH) (ruprecht)


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.....

von Magnus (Gast)


Angehängte Dateien:

Lesenswert?

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

--Magnus

von Magnus (Gast)


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...)

von Knecht R. (Firma: Weihnachtsmann GmbH) (ruprecht)


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:
1
#ifdef USING_LPC2138
2
//----- sector numbers for LPC2129
3
  if((addr >=0x00008000) && (addr <= 0x0000FFFF))
4
  {  return 8;   }
5
  if((addr >=0x00010000) && (addr <= 0x00017FFF))
6
  {  return 9;   }
7
  if((addr >=0x00018000) && (addr <= 0x0001FFFF))
8
  {  return 10;   }
9
  if((addr >=0x00020000) && (addr <= 0x00027FFF))
10
  {  return 11;   }
11
  if((addr >=0x00028000) && (addr <= 0x0002FFFF))
12
  {  return 12;   }
13
  if((addr >=0x00030000) && (addr <= 0x00037FFF))
14
  {  return 13;   }
15
  if((addr >=0x00038000) && (addr <= 0x0003FFFF))
16
  {  return 14;   }
17
  if((addr >=0x00040000) && (addr <= 0x00047FFF))
18
  {  return 15;   }
19
  if((addr >=0x00048000) && (addr <= 0x0004FFFF))
20
  {  return 16;   }
21
  if((addr >=0x00050000) && (addr <= 0x00057FFF))
22
  {  return 17;   }
23
#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

von Magnus (Gast)


Angehängte Dateien:

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
1
#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/microcontrollers/pdf/an10256.pdf)
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!

von Knecht R. (Firma: Weihnachtsmann GmbH) (ruprecht)


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???

von Magnus (Gast)


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

von Knecht R. (Firma: Weihnachtsmann GmbH) (ruprecht)


Lesenswert?

Moin Magnus,

dein Code:
1
      else
2
      {
3
        #ifdef DEBUG        
4
        UART1_IO_Send_String("\nData successfully written! \n\r ");
5
        #endif        
6
        return 0;      
7
      }
8
    }
9
  }
10
  VICIntEnable = buffer_vic;    // set back ints
11
}
mein Code:
1
      else
2
      {
3
        lcd_clear();
4
        set_cursor (0, 1);
5
        lcd_print (" Data successfully  ");
6
        set_cursor (0, 2);
7
        lcd_print (" written on FLASH!  ");
8
        waiting_for_the_eye();  
9
        VICIntEnable = buffer_vic;    // set back ints  
10
        return 0;      
11
      }
12
    }
13
  }
14
}

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

von Magnus (Gast)


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:

1
unsigned long *addr = NULL;
2
char buf[512];
3
int k=0;
4
int i=0;
5
  
6
addr = (unsigned long *) 0x8000; // die adresse, an der zuvor irgendwann ein Teststring gespeichert wurde
7
8
for(k=0, i=0; k < 16; k++, i=i+4)
9
{
10
    buf[k] = *(addr+i);  
11
    UART1_IO_Send_Char(buf[k]);  // damit man mal was sieht ;)
12
}


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...

von Knecht R. (Firma: Weihnachtsmann GmbH) (ruprecht)


Lesenswert?

Hey Magnus,

sorry, dass ich mich solange nicht gemeldet habe, aber dafür habe ich 
die Lösung:
1
char *addr = NULL;
2
3
addr = (char *) 0x00010000;
4
for(i=0; i < 16; i++)
5
{
6
    OnFlash[i] = *(addr+i);  
7
}
Viele Grüße und noch einmal ein dickes Dankeschön für die viele Hilfe!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.