Guten Tag!
Ich arbeite mit dem STM32F103VDT6 und dem uVision von Keil.
Nach einer Lernfahrt möchte ich zwei Arrays mit je 2100 Speicherstellen
ins Flash ablegen.
Ins Flash speichern habe ich auch schon gemacht. Jedoch nur Pageweise.
Ich kann mir einfach nicht vorstellen, wie man pageübergreifend ins
Flash speichert!?
Bis Jetzt:
Kann mir jemand einen Anhaltspunkt geben? Wie schaffe ich es, dass die
Tabelle (Array) auf zwei Pages aufgeteilt ist!?
Vielen Dank und freundliche Grüsse
M.B.
sollte es nicht eher wie folgt sein, wenn du 32bit-Daten auf den Flash
schreibst?:
1
intx=(sizeof(tSetup2)/sizeof(uint32_t));
Außerdem kann es dir dabei passieren, dass bei der Anzahl ein Rest
bleibt, x sollte also ggf. aufgerundet werden, z.B.:
1
if((sizeof(tSetup2)%sizeof(uint32_t)!=0)x++;
In dem Fall solltest du dir aber sinnvoll überlegen womit du das letzte
Datenwort befüllst, oder du stellst beim auslesen sicher, dass das
letzte Datenwort nur zum Teil in deine Variable vom Typ tSetup2
geschrieben wird.
Ansonsten muss ich dir ehrlich sagen, habe ich keine Ahnung was du mit
"Tabelle auf 2 Pages schreiben" meinst, mit dem von dir obig
beschriebenen Verfahren schreibst du doch bereits alle Bytes deiner
Variable setup in den Flash, wieso sollen es genau 2 Pages sein?
Um zu wissen ob das überhaupt geht sollten wir schon wissen wie viele
Byte tMotorCurrentSample benötigt und wie groß TRAV_MAXDIST_SAMPLES ist.
Der Struct, der ich bis jetzt ins Flash speichere ist nicht grösser als
2kB also nicht grösser als eine Page.
Die Arrays, die im oben aufgelisteten Struct liegen, sind jetzt grösser
als eine Page, 2100 * 2 Byte = 4.2 kB
Ich habs kompliziert beschrieben, aber ich muss einfach eine
Wertetabelle (Array[2100]) ins Flash legen, die grösser ist als eine
einzelne Page.
Gruss und Danke!
M.B.
Darf ich mal fragen, wo du den Registerwert FLSHBSEADRPG192 her hast?
Ich kann den gerade nicht definiert finden.
Ansonsten würde ich spontan vermuten, dass die nächste Page bei
FLSHBSEADRPG192 + 2048 anfängt und wenn du über 2048 Byte schreibst, du
mit deiner Implementierung sowieso dann auf der nächsten Page landest.
Oder hast du im Flash nach der Page 192 keine mehr die ungenutzt sind?
Tut mir leid, falls ich es jetzt vielleicht komplizierter mache als
nötig, aber ich verstehe offenbar noch nicht ganz wo das Problem liegt.
Dieser Struct ist aber wesentlich grösser (8444 Byte). Eine Page ist
2000 Byte gross. Also benötigt dieser Struct doch 5 Pages!?
Bis jetzt habe ich aber noch nie einen Struct ins Flash gespeichert, der
grösser war als eine Page des Flashs.
Ah ok, jetzt verstehe ich.
Also wenn du keine Folge von Pages zur Verfügung hast auf denen Daten
frei sind, kann ich dir nur empfehlen etwas zu machen wie:
Also indem du dir eine Liste (ggf. etwas intelligenter als Array o.ä.)
von freien Pages definierst und die dann geeignet auswählst.
Beim Auslesen aus dem Flash und beschreiben in deine Variable vom Typ
struct solltest du dann natürlich ebenfalls Stückchenweise vorgehen.
Ich hoffe das Hilft dir und ich stehe nicht immer noch auf em Schlauch.
Also alle auf einmal löschen wird wohl nichts, gibt zwar ein
FLASH_EraseAllPages() - aber das kann auch Pages löschen die du nicht
löschen willst.
Würde dabei bleiben ein Array von programmierbaren Pages zu definieren
und dann kannst du ja erst das ganze Array abarbeiten und immer die Page
löschen und im Anschluss beschreibst du die und nimmst die Adressen zum
schreiben wiederum aus dem Array.
EDIT:
Für das auslesen aus dem Flash wäre es natürlich günstig bei einer Seite
zu beginnen und nur die folgenden n Pages zu beschreiben, am besten
aufeinanderfolgend, dann lässt sich das leichter auslesen weil die
Registeradressen einfach folgend sind.
Eine Meldung wie: "war doch ganz anders" oder "hab es jetzt hinbekommen
indem ich ...", oder "ich probiere jetzt noch mal ..." wäre gut, sonst
machen wir uns nämlich weiter Gedanken wie wir dir helfen können.
Hallo!
Bin leider erst jetzt wieder dazu gekommen, um an diesem Projekt zu
arbeiten. Ich bin mir nicht sicher, ob wir das selbe Problem behandeln!?
Ich weiss, dass die Pages 186 - 190 mir zur Verfügung stehen um den
Struct, der 8444 Bytes gross ist, darin abzuspeichern. Die Pages liegen
also nacheinander. Ich weiss jetzt aber nicht wie ich den Struct so
ablegen kann, dass automatisch, nach dem die Page 186 voll ist auf die
Page 187 zugegriffen wird. Ich werde Deinen Vorschlag mal ausprobieren.
Aber da die Pages aneinander liegen benötige ich keine Liste mit
verfügbaren Pages!?
Wenn ich im Memory schaue hat er nicht gar nichts geschrieben, aber die
Werte, die ins Flash geschrieben wurden können nicht stimmen.
Ich frage mich auch, ob ich den erasePage am falschen ort platziert
habe.
Danke und Gruss
Ja, wenn du die Page nach dem Schreiben löscht ist das falsch. Dann
löscht du die Page nachdem du das erste Wort geschrieben hast nochmal
bevor du das 2. schreibst...
Nimm es mal aus der for-Schleife raus und füge eine zusätzliche Schleife
direkt nach dem ClearFlag ein, in etwa:
Ich hoffe bevor du zu lesen versuchst, gehst du mit z.B.:
FLASH_GetReadOutProtectionStatus() sicher, dass du überhaupt lesen
darfst und aktivierst es nötigen falls mit z.B.:
FLASH_ReadOutProtection(DISABLE)?
Kann der Debugger anzeigen was im Flash steht? Wäre davon ausgegangen,
dass das so nicht geht, weiß es aber nicht. Hast du das schon mal
gemacht oder von jemandem gesagt bekommen, dass im Debugger die Werte
aus dem Flash übernommen werden?
Im übrigen hast du in deinem letzten größeren Codebeispiel weiterhin:
1
intx=(sizeof(tSetup)/sizeof(int));
Ist das nun ein Denkfehler von mir gewesen am Anfang, dass es:
1
intx=(sizeof(tSetup)/sizeof(uint32_t));
heißen müsste? Wenn ja, warum muss es da int sein wenn du in der
for-Schleife 32-Bit-Int-Weise schreibst?
Hast du mal Interrupts bzgl. Flash aktiviert, wie z.B.: FLASH_IT_ERROR,
FLASH_IT_EOP und dann geguckt ob der InterruptHandler anspringt?
Wäre mal interessant ob das auftritt, dann würde das heißen, dass das
schreiben nicht funktioniert (mgl. schreibgeschützte Pages).
Das uint32_t anstelle int!
Bin aber selber erstaunt, dass dies den Unterschied ausmachte!
nochmals Danke!
Wenn ich auf eine Page des Flashes Zugreiffen möchte:
1
Setup2=*((tSetup2*)FLSHBSEADRPG192);
Jetzt kann ich doch einfach die erste Page angeben und es werden alle
nachfolgenden Pages ausgelesen, oder?
(Ich fülle Setup quasi "Byteweise" mit den Daten aus dem Flash um
sicherzugehen, dass ich nicht Bytes nach dem Ende von Setup mit Daten
aus dem Flash überschreibe.)
Hätte bei mir folgenden Grund: einem Operation wie
1
Setup=*((tSetup*)FLSHBSEADRPG186);
würde ich selber nicht unbedingt trauen, weil ich mir nicht sicher bin,
ob der = Operator für dein Struct genau das tut, was man erwartet (in
deinem Fall, wo du keine Pointer im Struct hast vermutlich kein
Problem).
Manche Leute würden mich wegen meiner Paranoia vermutlich lünchen und es
aus Prinzip genau wie von dir vorgeschlagen lösen, weil vermutlich
schneller und weniger Flash-Lesezugriffe, musst du mal einfach
ausprobieren, ob es funktioniert, oder du rufst schnell den Lünch-Mob
;-).
EDIT: Bei Pointern im Struct (als Repräsentanten für dynamisch
allozierte Variablen) würde auch mein Vorgehen nicht sicher sein, stell
ich gerade fest... Also vielleicht ignorierst du meine letzte Aussage
einfach ;)..