Hallo Leute! Ich beginne gerade mit dem RealView-Compiler. Ich wollte fragen, wie ich es schaffe, eine Variable an eine bestimmte Speicherstelle zu schieben. Mit dem Keil-Compiler funktioniert das z.B. folgendermaßen: uint32_t const f_protect __at 0x1FC = 0x87654321; Leider hat der RealView hier anscheinend eine andere Syntax, weil er bei obiger Zeile folgenden Fehler meldet: ": error: #65: expected a ";" Ich habe leider im Benutzer-Guide nicht die richtige Stelle finden können, um das Problem zu lösen. Gibt es bei dem RealView-Compiler eine Möglichkeit, die Variablen ebenfalls auf eine bestimmte Speicherstelle zu schieben? Danke für eure Antworten. Tschüss, Martin PS: Schönes Wochenende
Wer sich nicht an einen bestimmte Compiler binden will, tut gut daran, C nicht bloss aus dem Handbuch des Compilers zu lernen. Und verwendet folglich so weit wie möglich nur Standard-Konstrukte (geht nicht immer, z.B. bei Interrupts geht's eher selten). Konkret heisst es, dass man keine Variable per Compiler-spezifischer Option (__at) irgendwo plaziert, denn das sieht jedesmal anders aus. Sondern dass man einen Makro verwendet wie: #define f_protect (*(volatile unsigned int *)0x12345678) denn das geht zumindest ausserhalb des vom Linker verwalteten Speicherplatzes immer. Wenn die Variable freilich irgendwo im RAM liegen soll, also in dem Bereich der üblicherweise von Compiler und Linker verwaltet wird, dann sollte man mal überlegen, ob man überhaupt den richtigen Ansatz hat.
Hallo! Es geht darum auf die Speicherzelle Adresse 0x1FC, das ist eine Speicherzelle im Flash, den Wert 0x87654321 zu schreiben. Ich verwende den LPC2138 und dieser ist, wenn dieser entsprechende Wert an die entsprechende Speicherstelle geschrieben wurde lesegeschützt. Ich kenne mich mit diesem Makro nicht ganz so gut aus. #define f_protect (*(volatile unsigned int *)0x12345678) Bedeutet diese Definition, dass f_protect nun ein Zeiger ist, der auf die Speicherzelle 0x12345678 zeigt? Tschüss, Martin
Nicht direkt. #defines in C werden vom Präprozessor behandelt, d.h. bevor das Programm compiliert wird, wird jedes vorkommen von "f_protect" in deinem Quelltext durch "(*(volatile unsigned int *)0x12345678)" ersetzt. Siehe http://de.wikipedia.org/wiki/Pr%C3%A4prozessor
Dann schreibst du in deinem Programm einfach: { (*(volatile unsigned long *)0x000001FC) = 0x87654321; } Fertig. Ums zu verstehen, muß man von rechts nach links lesen: Die "Zahl" 0x000001FC sei ein Zeiger auf einen flüchtigen unsigned long Wert - das ist der cast in der Klammer (volatile...*). Nun haben wir einen Zeiger an die gewünschte Adresse. Mit dem "*" links neben der Klammer wird der Zeiger nun dereferenziert. Sprich: Wir greifen auf den INHALT der Speicherzelle zu, auf die der Zeiger zeigt. Und eben dieser Inhalt wird auf den gewünschten Wert von 0x87654321 gesetzt. OK? Der Compiler macht dann daraus erstaunlicherweise genau das richtige ;-)
Der Umstieg auf RealView steht mir auch noch bevor :-{ Bei mir sieht die Syntax bisher noch ähnlich aus: const unsigned int Code_Read_Protection __at 0x1FC = 0x87654321; Alternativ kann man die Konstantendefinition auch in der Startup.s unterbringen: Man definiere dort an passender Stelle eine Checkbox für die Bedienung über den Configuration Wizard, damit man die Code Read Protection während der Softwareentwicklung auf einfache Weise ein- und ausschalten kann, denn eingeschaltet verweigert der Keil ULINK JTAG-Adapter nach dem Flash Download jeglichen Zugriff auf den Controller und damit auch einen erneuten Flash Download. Wohl dem, der für solche Fälle in seiner Hardware auf jeden Fall den UART0 für z.B. das Philips Flash Utility zugänglich gemacht hat. Hier die Erstellung der Checkbox: /* // <e> Flash Code Read Protection On / Off // </e> */ CODE_PROT_SETUP EQU 0 Je nach Zustand der Checkbox wird dem Symbol CODE_PROT_SETUP dann automatisch eine 0 oder 1 zugewiesen. Dann am Ende, vor das END-Label, die Segmentdefinition mit Festlegung von Speicheradresse und Daten: // Setup the Flash Code Read Protection: IF (CODE_PROT_SETUP != 0) CODE_PROT_BASE EQU 0x000001FC ; Flash Adresse CODE_PROT_DATA EQU 0x87654321 ; Flash Daten AREA CODE_PROT, DATA, READONLY, ALIGN=2, AT CODE_PROT_BASE RSEG CODE_READ_PROTECT ; selektiere Segment DD CODE_PROT_DATA ; Speicherreservierung ENDIF Das funktioniert ganz gut. Allerdings möchte ich nicht versprechen, dass Assemblersyntax zwischen RealView und z.B. Keil harmoniert. Gruß Dietmar
Sorry, im letzten Assemblerfile-Schnipsel war noch ein Dreckfuhler (für den Fall, daß jemand das ausprobieren möchte): // Setup the Flash Code Read Protection: IF (CODE_PROT_SETUP != 0) CODE_PROT_BASE EQU 0x000001FC ; Flash Adresse CODE_PROT_DATA EQU 0x87654321 ; Flash Daten AREA CODE_PROT, DATA, READONLY, ALIGN=2, AT CODE_PROT_BASE RSEG CODE_PROT ; selektiere Segment DD CODE_PROT_DATA ; Speicherreservierung ENDIF Dietmar
Hallo Leute! Danke. Danke Dietmar, ich werde das noch versuchen. Hallo Arm-Fan Das mit dieser Zeile hat leider nicht funktioniert. (*(volatile unsigned long *)0x000001FC) = 0x87654321; Der Kontroller kann von Haus aus nicht ins Flash schreiben. Es hadelt sich bei 0x1FC um eine Adresse im Flash-Baustein. Jedes Mal wenn der µC auf diese Zeile trifft, bleibt er hängen und läuft nicht mehr weiter. Vielleicht gibt es noch eine andere Möglichkeit. Gruß, Martin
Hallo Leute! Ich habe mich etwas rumgehört. Man muss für die einzelne Konstante ein eigenes Modul erstellen und dies dann auf die ensprechende Adresse anheben. Dies geschieht in "Options for Target - On-Chip - IROM2". Dort kann man nun den neuen Speicher eintragen, so wie es bei mir der Fall ist 0x1FC und Größe 0x04. Leider gibt es hier einen kleinen Haken. Das Problem ist nämlich, dass sich dieser neue Speicherbereich mit dem original überlappt, der nämlich folgendermaßen angegeben ist:IROM1: 0x000 Größe 0x80000. Um erste Versuche machen zu können, verkleinerte ich IROM1 und legte IROM2 hinter IROM1 an. Danach definierte ich im File "flashprotect.c" eine Kosntante: uint32_t const f_protect = 0x87654321; Wählte nun mit der rechten Maustaste dieses File an und aktivierte die Option "Options for File" unter Memory Assignment wies ich nun den Constanten das IROM2 zu. Während des Komplierens erhielt ich folgende tolle Mitteilung: warning: L6329W: Pattern flashprotect.o(RO) only matches removed unused sections. Nun war der Zahlenwert wieder nicht dort wo er hinsollte. Irgendwie habe ich das Gefühl wie wenn der RealView einwenig schwach wäre. Aber schimpfen bringt nichts. Vielleicht hat doch jemand eine einfache Lösung. Tschüss, Martin
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.