Forum: Compiler & IDEs Probleme mit externem Flash


von Stefan (Gast)


Lesenswert?

Hallo,
ich habe einen externen Flashbaustein (AT25DF) und folgendem Code:
1
void writeFlash(unsigned long int address, unsigned char data)
2
{ 
3
unsigned char temp;   
4
       
5
while( (Flash_impl_readFlashStatus(me) & 0b00000001) )   
6
        ;         //wenn bereit, dann weiter
7
     
8
SS_FLASH = 0;    
9
spi(WRITE_ENABLE);
10
SS_FLASH = 1;
11
     
12
SS_FLASH = 0;     
13
spi(WRITE_BYTE);
14
spi((unsigned char)(0x00));
15
spi((unsigned char)(0x07));
16
spi((unsigned char)(0XD0));
17
spi('1');
18
spi('2');
19
spi('3'); 
20
spi(data);
21
spi('a');
22
spi('b');
23
spi('c');   
24
SS_FLASH = 1;  
25
 
26
putchar1('d'); 
27
putchar1(':');      
28
putchar1(data);  
29
putchar1(' ');   
30
31
//nur zum Test
32
while( (Flash_impl_readFlashStatus(me) & 0b00000001) )   //warten bis ready
33
        ;     //wenn bereit, dann weiter
34
    
35
SS_FLASH = 0;       
36
spi(READ_ARRAY);
37
spi((unsigned char)(0x00));
38
spi((unsigned char)(0x07));
39
spi((unsigned char)(0XD0));
40
spi(0);
41
temp = spi(0); 
42
  putchar1(temp); 
43
temp = spi(0); 
44
  putchar1(temp);
45
temp = spi(0); 
46
  putchar1(temp); 
47
temp = spi(0); 
48
  putchar1(temp);
49
temp = spi(0); 
50
  putchar1(temp); 
51
temp = spi(0); 
52
  putchar1(temp);
53
temp = spi(0); 
54
  putchar1(temp);
55
putchar1(' '); 
56
SS_FLASH = 1; 
57
58
putchar1('T');
59
putchar1(':');
60
putchar1(data);     
61
}

Ich verwende den Codevisioncompiler und dort ist die Funktion spi wie 
folgt definiert:
unsigned char spi(unsigned char data);

Beim obigem Code erhalte ich folgende Ausgabe:
d:s 1230abc T:s

>>wenn ich einzelne char's ins Flash speichere, so kann ich diese auch wieder 
auslesen, aber nicht die übergebene unsigned char Variable "data"!!!

Schlimmer noch wird es, wenn ich statt der konstanten Adresse beim Lesen 
und beim Schreiben
1
          
2
spi((unsigned char)(address >> 16));
3
spi((unsigned char)(address >> 8));
4
spi((unsigned char)(address));
ersetze, dann kann ich gar nichts mehr aus dem Flash ausgeben nur \0

Woran sollte das liegen?? Ich dachte, dass es keinen Unterschied macht 
ob ich
spi((unsigned char)(0x00));
spi((unsigned char)(0x07));
spi((unsigned char)(0XD0));
oder
address = 2000;
spi((unsigned char)(address >> 16));
spi((unsigned char)(address >> 8));
spi((unsigned char)(address));

schreibe. Anscheinend liege ich falsch, warum??

von Bernhard S. (berns)


Lesenswert?

Hallo Stefan,

ich ab da ein paar Fragen:

 - Wann löscht du das Flash? Flash Speicher kann nämlich nicht so 
beschrieben werden wie ein RAM -> siehe Datasheet.

 - Wenn du debuggst, kannst du dir den Inhalt von Variablen ja ansehen, 
probier doch mal:
1
unsigned long int address = 2000;
2
unsigned char test;
3
4
test = (unsigned char)address>>16;
5
spi(test);
6
test = (unsigned char)address>>8;
7
spi(test);
8
test = (unsigned char)address;
9
spi(test);

Was steht in test, jeweils vor Ausführung des spi Befehls? das 
"Erwartete"?

 - Was ist SS_FLASH?

 - Um welche CPU handelt es sich? Bei Compiler (bzw ev. IDE) um welche 
Version?

Grüße

von Stefan (Gast)


Lesenswert?

Hallo Bernhard,

das ist ja das komische, wenn ich mir dir die test-Variablen ausgebe, 
erhalte ich
00 07 D0
als char-Werte. Also genau das was ich erwartet habe. Und selbst die 
data-Variable die sowieso schon vom Typ unsigned char ist bekomme ich 
nicht richtig wieder, kommischerweise einzelne konstante Zeichen wie 'a' 
schon.

Löschen kann ich den Baustein, mache ich dazwischen aber nicht. Das 
externe Flash wird über SPI aufgerufen und SS_FLASH ist das ChipSelect 
dafür. Ich kann auch die ID des Bausteins auslesen, die grundsätzliche 
Kommunikation funktioniert also.

Ach ja und der Mikrocontroller zum Ansteuern ist ein Atmega128.

von Bernhard S. (berns)


Lesenswert?

- Was passiert, wenn du die test Variable an die spi Funktion als 
Adresse übergibst? Verhält sich die Kommunikation dann auch "falsch"?

 - Zum Thema löschen: wenn du an die Stelle 0x07D0 im Flash 0x00 
schreibst, kann diese Stelle bis zum nächsten löschen nicht mehr 
beschrieben werden. Wie stellst du sicher, dass beim Beschreiben des 
Flash der "Ziel" Speicherblock gelöscht ist? Wenn du nämlich im 2. 
Durchgang an die Stelle 0x07D0 0x10 schreiben willst, wird dort 
weiterhin 0x00 stehen -> bis nach dem Löschen (das "setzt" den Speicher 
auf 0xFF).

von Stefan (Gast)


Lesenswert?

Hallo

ist das mit dem Beschreiben wirklich so? Ich wollte das externe Flash 
als Ringspeicher nutzen, doch diese Anwendung wäre ja dann nicht 
möglich!

Ist es nur bei dem Wert 0x00 so, oder kann ich generell ein Byte nicht 
mehr überschreiben ohne es vorher zu löschen??

Wenn ich z.B. die Zelle vorher mit 0x0F beschrieben habe, kann ich sie 
dann mit 0xF0 überschreiben??

von Stefan E. (sternst)


Lesenswert?

Stefan schrieb:
> Wenn ich z.B. die Zelle vorher mit 0x0F beschrieben habe, kann ich sie
> dann mit 0xF0 überschreiben??

Nein. "Schreiben" bezeichnet immer nur einen der beiden möglichen 
Bit-Wechsel (in der Regel von 1 nach 0). Die andere Richtung nennt sich 
dann "Löschen". Von 0x0F nach 0xF0 beinhaltet aber beide Richtungen.

von Christian R. (supachris)


Lesenswert?

Stefan schrieb:
> Ist es nur bei dem Wert 0x00 so, oder kann ich generell ein Byte nicht
> mehr überschreiben ohne es vorher zu löschen??

Du kannst ein Bit durch schreiben nur von 1 auf 0 setzen. Von 0 auf 1 
geht nur duch löschen. Einmal 0, bleibt es auch nach x mal 1 drauf 
"schreiben" 0....einen Flash als Ringspeicher ist natürlich ziemlich 
daneben. Nimm seriellen SRAM, den gibts mittlerweile. Zum Beispiel hier: 
http://www.ipsilog.com/content/index.php?id=5 oder hier: 
http://www.onsemi.com/PowerSolutions/parametrics.do?id=2206

von Bernhard S. (berns)


Lesenswert?

Flash hält Daten auch stromlos zur Verüfung und wird daher meist zum 
Ablegen des Programmcodes oder von statischen Daten verwendet. Sollen 
Daten wie ein Ringbuffer verwendet werden ist ein Flash das denkbar 
ungünstigste Bauteil *).
Wenn die Daten im Buffer einen Stromausfall/ein Abschalten überdauern 
sollen, kannst du auch z.b. ein (serielles) FRAM verwenden, ansonsten 
eben ein (serielles) SRAM.

*) er "hält" auch nur für eine gewisse Anzahl Löschzyklen, danach können 
einzelne Zellen ausfallen.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Man kann Flash-Speicher durchaus als (Ring-)Speicher z.B. für einen 
Datenlogger verwenden. Ob diese Art Speicher geeignet ist oder nicht, 
hängt hauptsächlich vom Datenaufkommen ab, da für Flashspeicherzellen 
bzw. -seiten nur eine begrenzte Zahl möglicher Schreib-/Löschzyklen 
garantiert wird (oft 10000). Programmierung der Speicherveraltung ist 
wegen der üblichen seitenweisen Organisation von Flashspeicher nicht 
ganz trivial, aber zu machen.

von Stefan (Gast)


Lesenswert?

Hallo,

Vielen Dank für eure Hilfe!! Habt ihr ein Beispiel zur 
Speicherverwaltung?

von Bernhard S. (berns)


Lesenswert?

Was möchtest du denn genau machen?

Bei einem Ringbuffer kannst du so vorgehen (allgemeiner RB 
vorausgesetzt):

Block/Seite/Page: kleinste Einheit im Flash, die gelöscht werden kann
Blockgröße/Seitengröße/Pagesize: von Flash zu Flash verschieden - siehe 
Datenblatt

 - Initialisierung (= Blöcke löschen) - Bsp. mit mehreren Blöcken
 - Daten beginnend von der Startaddresse reinschreiben
 - Ist ein Block voll wird in den nächsten geschrieben
 - erreicht der Lesepointer das Blockende, wird der Block gelöscht
 - ist der Schreibpointer "hinter" dem Lesepointer und im selben Block 
wie dieser, ist der Buffer (zusätzlich zu den Bedingungen des normalen 
RB) voll.

Der eigentliche Unbterschied zu einem normalen RB wäre die Prüfung auf 
einen vollen Buffer und dass der RB (vernünftigerweise) nicht kleiner 
als 2 Blöcke sein soll.

Problem: du solltest versuchen alle Blöcke des Flash gleichermaßen zu 
verwenden, da sonst Teile des Chips schneller altern (Löschzyklen). 
Daher kann es vorteilhaft sein, jeweils am Anfang des Blockes einige 
wenige Bytes Verwaltungsinformation zu speichern, die dir sagen wie oft 
der Block gelöscht wurde und ob er voll oder leer ist. Es kann auch 
geschickt sein, für die Verwaltungsinformation*) ein verhältnismäßg 
teures, aber kleines NV-RAM zu verwenden und das Flash für die 
eigentlichen Daten.

*) in diesem Falle Daten zu den Speicherblöcken und Buffer-Pointer

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.