Forum: Mikrocontroller und Digitale Elektronik LPM-Befehl aus Bootloaderbereich


von Daniel (Gast)


Lesenswert?

Hallo,
ich programmierte mir einen Bootloader der bisjetzt funktioniert. Nun 
möchte ich diesen um einen Verify-Funktion erweitern:
Nach der Übertragung einer Seite in den temp. Seitenspeicher und dem 
Schreiben dieser Seite in den Flash, möchte ich diesen beschriebenen 
Flash speicher auslesen um diesen dann PCseitig mit der übergeben Seite 
zu prüfen und gegebenfalls diese Seite bei einem Fehler erneut zu 
übertragen, ansonsten soll die nächste Seite übergeben werden. Leider 
funktioniert dies nicht und ich erhalte ständig 0xFF durch den 
"lpm"-Befehl.
Ist es nicht möglich aus dem Bootloaderbereich, mit dem lpm-Befehl auf 
das Flash zuzugreifen?
Denn wenn ich die Funktion in mein Anwenderprogramm integriere, lese ich 
eine Seite aus dem Flash und das ganze funktionert wie zu erwarten.

von flo (Gast)


Lesenswert?

>>Ist es nicht möglich aus dem Bootloaderbereich, mit dem lpm-Befehl auf
>>das Flash zuzugreifen?

ja es ist möglich, vorausgesetzt du hast nicht die lock bits gesetzt

>>...ich erhalte ständig 0xFF durch den "lpm"-Befehl.

kann es vielleicht sein das der flash die seite noch nicht komplett 
geschrieben hat?


gruß
flo

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Lädst Du den Z-Pointer auf die richtige Adresse? Was ist das für ein 
Controller? Poste mal den Code.

von Daniel (Gast)


Lesenswert?

Ja den Z-Pointer lade ich korrekt, denn die Funktion funktioniert in 
meinem Anwenderprogramm einwandfrei und gibt mit die erste seite aus dem 
Flash zurück.
1
...
2
#pragma regalloc-        /* Deaktivierung der automatischen Vergabe von Adressen an Variablen*/
3
register unsigned int    daten               @0x0002;
4
register unsigned int    SiteAdress          @0x0004;
5
register unsigned int    CurrentAdress       @0x0006;
6
#pragma regalloc+        /* Aktivierung der automatischen Vergabe von Adressen an Variablen*/
7
...
8
9
void CHECK_PAGE(void)
10
{
11
     for(i=0;i<128;i++)
12
     {
13
          CurrentAdress = SiteAdress * (1<<7) + i;  //CurrenAdress = R6+R7
14
          #asm
15
               movw r30,r6;             //CurrentAdress in Z-Register laden  || Kopiere R6+R7 nach R30+R31(Z-Pointer)
16
               lpm r2,z;                //Programmspeicher[Z_Register] in Daten(R2+R3) gespeichert
17
          #endasm
18
          putchar(daten);
19
     }
20
}
21
...

von Daniel (Gast)


Lesenswert?

Atmega16 mit Codevision

von Daniel (Gast)


Lesenswert?

>>...kann es vielleicht sein das der flash die seite noch nicht komplett
geschrieben hat?

Wie prüfe ich das nach?
Denn ich prüfe als erstes ob eine SPM-Operation noch ausgeführt wird.
Danach aktiviere ich durch Setzen des RWWSRE-Bit den RWW Bereich.
Nun prüfe ich ob das RWWSB-Bit noch gesetzt ist, um danach den Flash mit 
lpm-Befehl auszulesen. Leider bleibt er beim Prüfen des RWWSB-Bit in 
einer Schleife hängen
1
...
2
     #asm
3
//REENABLE_RWW
4
          ldi r17,(1<<4) | (1<<1);   //RWWSRE + SPMEnable
5
//Abfragen ob SPM-Operation noch ausgeführt wird
6
     WAIT_SPM:
7
          in   r16,0x37;           //SPMCR in Register r16 einlesen
8
          sbrc r16,0;              //Skip if Bit in Register is Cleared
9
          rjmp WAIT_SPM;
10
//SPM-Operation ausführen mit dem in Register R17 abgelegtem Wert
11
          out  0x37,r17;           //schreibe in SPMCR-Register und führe aus
12
          spm;
13
//Abfragen ob Write oder Erase Page ausgeführt wird
14
     WAIT_WHILE_WRITE:
15
          in   r16,0x37;
16
          sbrc r16,6;
17
          rjmp WAIT_WHILE_WRITE;     
18
     #endasm
19
     for(i=0;i<128;i++)
20
     {
21
          CurrentAdress= SiteAdress * (1<<7) + i; //CurrenAdress = R6+R7
22
          #asm
23
               movw r30,r6;             //CurrentAdress in Z-Register laden  || Kopiere R6+R7 nach R30+R31
24
               lpm r2,z;                //Programmspeicher[Z_Register] in Daten gespeichert
25
          #endasm
26
          putchar(daten);
27
     }
28
...

von flo (Gast)


Lesenswert?

>>Wie prüfe ich das nach?
wie du schon richtig erkannt hast in dem du abfragst ob SPMEN null ist.

wichtig ist auch noch das du den rww bereich bevor du ihn lesen willst 
freigibst, dies geht aber auch nur wenn SPMEN null ist.

>>//REENABLE_RWW
>>          ldi r17,(1<<4) | (1<<1);   //RWWSRE + SPMEnable
sollte eher heissen: ldi r17,(1<<4) | (1<<0);

>>//Abfragen ob Write oder Erase Page ausgeführt wird
kannst dir eingentlich sparen.


gruß
flo

von flo (Gast)


Lesenswert?

nachtrag:

>>Leider bleibt er beim Prüfen des RWWSB-Bit in
>>einer Schleife hängen
das RWWSB bit wird nur auf null zurückgesetzt wenn man den rww bereich 
wieder freigibt mit RWWSRE.

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.