Hallo,
ich möchte einen 512 Byte großen Speicherbereich im
Flash-Programmspeicher für Benutzereingaben reservieren.
Wie reserviere ich das in C, so das der Compiler Bescheid weis und es
keinen Adressen Konflikt gibt?
Mein C-Lehrbuch bezieht sich eher auf C-Programme die auf einem PC
laufen,
deshalb muss ich die erfahrenen µC-Programmierer hier fragen :-)
Ich benutze den Arm Realview Compiler und µVision3, meine MCU ist ein
ADuC7126
Mr.T schrieb:> Den Compiler interessiert das nicht. Such mal im Linker Manual, wie Du> sections im Linkerscript anlegst.
Ich habe mal in einem C-Programm für den 8051 gesehen, wie jemand da
einen bestimmten Bereich im Programmspeicher reserviert hat.
Da war irgenwas mit
Kapitän Nuss schrieb:> Wie reserviere ich das in C, so das der Compiler Bescheid weis und es> keinen Adressen Konflikt gibt?
Wie das genau geht, ist compiler-/linker-abhängig.
Grundsätzlich kannst Du entweder direkt im C-Code eine fixe Adresse
angeben (wie in Deinem Beispiel) oder legst im Linker-Script eine eigene
Section für Deine Zwecke an.
Mit einer eigenen Section legst Du erst im Linker-Script fest, wo diese
Section liegen soll. Das ist meiner Ansicht nach sauberer.
Markus B. schrieb:> oder reicht nicht einfach> ein Char Array mit 512 Stellen?
Ja genau!
> Der Compiler hält 512 Byte frei und gut ist?!
So würde ich mir das wünschen,
das diese 512 byte nicht mit dem Programmspeicher kollidieren.
Und das diese 512 Byte an einer 512 Byte Grenze anfangen.
Die syntax kann natürlich auch so gewesen sein:
Mr.T schrieb:>> Der Compiler hält 512 Byte frei und gut ist?!> Und die legt er dir an eine vorher definierte Adresse?
Die Frage ist, ob man das überhaupt will. (also jetzt: an eine bestimmte
konkrete Adresse).
In dein meisten Fällen will man das ja gar nicht. Es reicht, wenn man
dem Compiler/Linker sagt, dass das Zeug ins Flash soll. Wo genau im
Flash - das ist Sache der Tools. Und wie das genau geht: Compiler/Linker
Doku.
Kapitän Nuss schrieb:> ich möchte einen 512 Byte großen Speicherbereich im> Flash-Programmspeicher für Benutzereingaben reservieren.
Sollen da die Eingaben des Nutzers abgespeichert werden oder eine
Benutzerführung angelegt => Menueinträge ?
Mr.T schrieb:>> Der Compiler hält 512 Byte frei und gut ist?!> Und die legt er dir an eine vorher definierte Adresse?
Diese Anforderung lese ich aber nirgends. Wo kommt die her?
Kapitän Nuss schrieb:> ich möchte einen 512 Byte großen Speicherbereich im> Flash-Programmspeicher für Benutzereingaben reservieren.>> Wie reserviere ich das in C, so das der Compiler Bescheid weis und es> keinen Adressen Konflikt gibt?
macht genau das! Wie man das ins flash verlagert und dort beschreibt ist
der Dokumentation der (Compiler-) tools oder entsprechenden Beispielen
zu etnehmen.
Zuerst müßte man mal klären, ob der Flash des MC überhaupt zur Laufzeit
gelöscht und geschrieben werden kann (IAP In application programming).
Und dann, wie.
Dann muß man sich nur noch eine Routine dafür schreiben. Vielleicht gibt
es auch schon einen API-Call dafür im Bootloader.
Ob man die Routine dann so schreibt, daß sie nur an festen Pagegrenzen
schreiben kann, oder an beliebigen Adressen, ist jedem selbst
überlassen.
Leider mag mein Compiler (Realview) diese Syntax nicht.
Ich habe allerdings keinen 8051 sondern einen ADuC7126.
Ich könnte schon während der Laufzeit ins Flash schreiben,
man kann immer nur 512 Byte Blöcke schreiben (FEE0ADR Register).
Wär natürlich blöd, wenn ich dabei das eigentliche Programm
überschreiben würde.
Für das Lesen aus dem Programmspeicher habe ich jetzt diese hinbekommen:
Kapitän Nuss schrieb:> Leider mag mein Compiler (Realview) diese Syntax nicht.
Tu dir selbst einen Gefallen und fang endlich damit an, das zu tun, was
dir seit Stunden vorgeschlagen wird: durchforste die Doku!
Wenn da etwas dafür vorgesehen ist, das man Flash-Bereiche als
Zwischenspeicher verwenden kann, dann findest du das in der Doku und
nicht hier im Forum!
> Wie kann ich das ohne PEEK schreiben?
Doku nachsehen!
Das ist wichtig! Du musst MIT dem Compiler/Linker arbeiten und nicht
GEGEN ihn! Wie das genau geht findet sich, wenn überhaupt, in der
Compiler/Linker Doku!
Kapitän Nuss schrieb:> Kapitän Nuss schrieb:>> ich möchte einen 512 Byte großen Speicherbereich im>> Flash-Programmspeicher für Benutzereingaben reservieren.>>>> Wie reserviere ich das in C, so das der Compiler Bescheid weis und es>> keinen Adressen Konflikt gibt?
Das heißt ja erstmal nur, daß du es im Flash haben willst, aber nicht,
daß es an einer ganz bestimmten Adresse stehen muß. Wie schon gesagt
wurde, ist es besser, dem Compiler (bzw. eigentlich dem Linker) die
Aufgabe zu überlassen, die Adressen zu verteilen und ihm lediglich zu
sagen, daß es halt im Flash sein soll. Dafür gibt es in C aber keinen
Standard-Weg. Es ist Compiler-abhängig.
Kapitän Nuss schrieb:> Aber wie sage ich jetzt dem Compiler, halte mir mal den Speicher> von...bis frei und nenne das z.B. user_daten
Das steht in der Doku Deines speziellen Compilers.
Hat Dein Compilerhersteller etwa keine Webseite bzw. Deine
Compilerinstallation keine Hilfe und kein Manual?
Oftmals haben Compilerhersteller sogar einen Support, Knowledge Base
oder Forum, wo man spezielle Fragen stellen kann.
Man sollte dort aber erstmal nachlesen, ob die Frage nicht schon
beantwortet wurde. Es macht keinen guten Eindruck, wenn man eine Frage
zum 1000-sten mal stellt.
Kapitän Nuss schrieb:> Ich habe einen C-Code gefunden, der (bei einem 8051) etwas in den> Programmspeicher schreibt und diesen Speicherbereich freihält:>> const code unsigned char at 0x80 Beschreibung1[] = "528302B0";> const code unsigned char at 0x89 Beschreibung2[] => "Schrittmotorsteuerung und die Anzeige";> const code unsigned char at 0xaf Beschreibung3[] = "2003-08-29";
Das ist kein C:
• "code" ist kein Schlüsselwort in C
• "at" ist kein Schlüsselwort in C
• "0x.." ist an der Stelle wo es steht syntaktisch nicht erlaubt in C
Vielleicht ist das ja BASIC oder so?
Johann L. schrieb:> Vielleicht ist das ja BASIC oder so?
Offenbar, denn schließlich gibt es ja auch einen "PEEK"-Befehl...
Kapitän Nuss schrieb:> Aber wie sage ich jetzt dem Compiler, halte mir mal den Speicher> von...bis frei und nenne das z.B. user_daten
Einfach mit "POKE" an die gewünschte Adresse schreiben...
Lies das Handbuch und leg im Linker-Script eine Section an. Und beleg
mit der Section vollständige Flash-Page(s), sonst kannst Du die Section
nicht löschen, ohne Kollateralschaden anzurichten.
Johann L. schrieb:> Das ist kein C:>>>> • "code" ist kein Schlüsselwort in C>> • "at" ist kein Schlüsselwort in C>> • "0x.." ist an der Stelle wo es steht syntaktisch nicht erlaubt in C>>>> Vielleicht ist das ja BASIC oder so?
Wenn der jeweilige Compiler mit dieser Syntax klar kommt ist es
spezieller C-Code.
Sieht mir aber her wie der Code aus nem Visual Studio aus.
Karl Heinz Buchegger schrieb:> Kapitän Nuss schrieb:>>> Leider mag mein Compiler (Realview) diese Syntax nicht.>> Tu dir selbst einen Gefallen und fang endlich damit an, das zu tun, was> dir seit Stunden vorgeschlagen wird: durchforste die Doku!
YMMD :-D
> Wenn da etwas dafür vorgesehen ist, das man Flash-Bereiche als> Zwischenspeicher verwenden kann, dann findest du das in der Doku und> nicht hier im Forum!
In der Doku wohl kaum. Wichtig ist, dass man das Flash
- zur Laufzeit beschreiben kann
- sich u.U. Code dafür baut
>> Wie kann ich das ohne PEEK schreiben?>> Doku nachsehen!
Auch hier: welche Doku?
Entweder er nimmt das PEEK-Makro (wie das aufgebaut ist steht ja in
derselben Zeile) oder er überlagert den Flashsektor mit einem pointer
auf ein char-array z.B. Dann kann er byteweise über Index drauf
zugreifen.
Sowas orndne ich unter C-Allgemeinwissen ein.
Grundsätzlich stimme ich Dir aber zu: lesen bildet ungemein ;)
Ein kurzer Blick ins Datenblatt vom ADuC7126 zeigt, das der Flash in 2
Blöcke von je 64kB aufgeteilt ist, wobei beim ersten Block nur 62kB zur
Verfügung stehen. Zum Schreiben in das Flash muss vorher der
entsprechende Block gelöscht werden.
Das bedeutet für dich:
Du bekommst dein Programm vollständig in einen Block, dann kannst du den
anderen Block löschen und neu beschreiben.
Wenn sich noch andere Daten im dem zu löschenden Block befinden musst du
die vorher ins Ram sichern und hinterher wieder ins Flash schreiben.
Deine Flash Programmieroutine, darf dabei natürlich auch nicht in dem zu
löschenden Block liegen, sonst muss die auch aus dem Ram laufen.
Siehe Datenblatt unter: NONVOLATILE FLASH/EE MEMORY
Aber so wie es aussieht kann das Flash nur über Bootloader geschrieben
werden und es gibt noch Fuses um das Flash zu sichern.
Da ändert auch ein C Compiler nichts daran ;)
Bei den Keil 8051/80166 Compilern kann man in bei den Linker
Einstellungen Speicherbereiche reservieren.
Für mich stellen sich noch andere Fragen:
Warum überhaupt Werte in den Programmspeicher schreiben? Warum nicht mit
normalen Variablen hantieren und gelegentlich eine Datensicherung in den
EPROM? Kannst du auch fix 'ne Funktion in Assembler mit einfügen? -> Da
würde ich gar nichts reservieren, sondern einfach den Speicherblock ans
Ende vom Flash legen und die Daten über so eine Funktion an die
entsprechende Stelle schreiben. Da muss der Compiler/ Linker gar nichts
davon wissen ;-)
Edit: bei einem einfachen AVR sollte das so gehen.
Ich habe das jetzt hinbekommen:
Unter Options für Target1 habe ich die IROM Größe von 0x1F800 auf
0x1F600 veringert, d.h. es werden 512 Byte frei ab 0x9F600
Ich habe 3 Funktionen geschrieben:
erase_page, save und Hexdump
1
FEE0MOD=1<<3;// Enable erase & write commands for 0x90000