Hallo Zusammen, ich habe ein Probklem bei der initialisierung des AT91SAM7X. Ich benute ihn zusammen mit dem RTOS freeRTOS, wobei ich mir dazu ein Beispiel von der freeRTOS Seite runtergeladen habe. Als Tipp steht hier ein bestehendes beispiel so zu ändern, dass man es auf die eigenen Bedürfnisse anpasst. Gesagt, getan. Funktioniert sowiet, bis auf den Remap befehl. Um die maximale Performance zu erreichen will ich den Code aus dem RAm laufen lassen und musss dazu den Speicherbreich remappen. Hierzu copiere ich den gesamten Code aus dem Flash in den RAM und setzte dann das Remap Bit. memcpy(0x00200000,0x00100000,0x2000); AT91C_BASE_MC->MC_RCR = AT91C_MC_RCB; Das ganze mache ich in der LowLevelInit.c, welche nach den Befehlen mit dem Wort SECTION ausgeführt wird (siehe unten). Von den Speicherbereichen passt das soweit auch noch, nur dass ich mir damit selber die Beine wegziehe und mir damit meine verschiedenen Stacks überschreibe. In der CStartup.s Datei, in welcher die Stacks initialisiert werden steht ein Befehl den ich nicht verstehe. Evtl. kann mir jeamnd diesen Erklären: Ich kopier hier mal einen größeren Zusammenhang... ;----------------------------------------------------------------------- ------- ; ?INIT ; Program entry. ;----------------------------------------------------------------------- ------- SECTION FIQ_STACK:DATA:NOROOT(3) ?????? SECTION IRQ_STACK:DATA:NOROOT(3) ?????? SECTION SVC_STACK:DATA:NOROOT(3) ?????? SECTION ABT_STACK:DATA:NOROOT(3) ?????? SECTION UND_STACK:DATA:NOROOT(3) ?????? SECTION CSTACK:DATA:NOROOT(3) ?????? SECTION text:CODE:NOROOT(2) ?????? REQUIRE __vector ?????? EXTERN ?main ?????? PUBLIC __iar_program_start ?????? EXTERN AT91F_LowLevelInit ?????? __iar_program_start: ;----------------------------------------------------------------------- ------- ;- Low level Init is performed in a C function: AT91F_LowLevelInit ;- Init Stack Pointer to a valid memory area before calling AT91F_LowLevelInit ;----------------------------------------------------------------------- ------- ;- Retrieve end of RAM address ldr r13,=TOP_OF_MEMORY ;- Temporary stack in internal RAM for Low Level Init execution ldr r0,=AT91F_LowLevelInit mov lr, pc bx r0 ;- Branch on C function (with interworking) ; Initialize the stack pointers. ; The pattern below can be used for any of the exception stacks: ; FIQ, IRQ, SVC, ABT, UND, SYS. ; The USR mode uses the same stack as SYS. ; The stack segments must be defined in the linker command file, ; and be declared above. mrs r0,cpsr ; Original PSR value bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#SVC_MODE ; Set SVC mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#UND_MODE ; Set UND mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(UND_STACK) ; End of UND_STACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#ABT_MODE ; Set ABT mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#FIQ_MODE ; Set FIQ mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(FIQ_STACK) ; End of FIQ_STACK ;- Init the FIQ register ldr r8, =AT91C_BASE_AIC bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#IRQ_MODE ; Set IRQ mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(IRQ_STACK) ; End of IRQ_STACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#SYS_MODE ; Set System mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(CSTACK) ; End of CSTACK ;----------------------------------------------------------------------- - Hab die komplette Startup Datei nochmal als Anhang dran gehangen. Meine Fragen jetzt: Wo werden den die Stacks hingelegt (Speicherbereich)? Und wie kann, bzw. muss ich sie legen, damit ich sie mit dem Remap Befehl nicht überschreibe und es trotzdem funktioniert? Hoffe jemand kann mir da helfen. Viele Dank schonmal im Vorraus MfG Stefan
hallo stefan, ich würd dir empfehlen, nur die zeitkritischen funktionen ins ram zu kopieren. wenn du bei der definition der funktion dem compiler/linker mitteilst dass welche funktionen im ram liegen sollen dann macht das ganze der startup-code für dich. unter iar workbench gibt es dafür das schlüsselwort "__ramfunc", unter gcc kenne ich es leider nicht, es gibt aber dort auch diese möglichkeit. gruss gerhard
Vorab: nutze EWARM fast nie und dann auch nur zum Spielen, folgendes also nur ein paar Ansätze. IAR bietet Support für ihre Produkte, dort schon gefragt? >... > Funktioniert sowiet, bis auf den Remap befehl. Um die maximale > Performance zu erreichen will ich den Code aus dem RAm laufen lassen und > musss dazu den Speicherbreich remappen. Hierzu copiere ich den gesamten > Code aus dem Flash in den RAM und setzte dann das Remap Bit. > > memcpy(0x00200000,0x00100000,0x2000); > AT91C_BASE_MC->MC_RCR = AT91C_MC_RCB; Dem Linker wurde nicht mitgeteilt, dass ein Teil der RAM-Bereichs für Code genutzt werden soll. Wenn man alle sections in die RAM region linkt, sollte der Linker Adressebereiche für code, rodata, data, stacks automatisch zuweisen. Kann man wohl per Linker configuration file (Linker-Script auf IARisch) machen. Nur der Startup-Code und die Kopierroutine für alle sections bleiben im ROM. > Das ganze mache ich in der LowLevelInit.c, welche nach den Befehlen mit > dem Wort SECTION ausgeführt wird (siehe unten). > > Von den Speicherbereichen passt das soweit auch noch, nur dass ich mir > damit selber die Beine wegziehe und mir damit meine verschiedenen Stacks > überschreibe. Warum "passt" das mit den Speicherbereichen. Gibt es eine Art Map-File, dass die vom Linker zugewiesenen Adressen für die sections auflistet? > In der CStartup.s Datei, in welcher die Stacks > initialisiert werden steht ein Befehl den ich nicht verstehe. SFE? Wenn ja: gibt w.r.e die letzte Adresse einer section zurück, würde auch zum restlichen Code passen. > Meine Fragen jetzt: > > Wo werden den die Stacks hingelegt (Speicherbereich)? In jeweils eigene sections in data. In welcher Memory region data liegt, wird im linker configuration-file festgelegt. Mglw. auch die Position der Stacks, kann man aber erst was zu sagen, wenn man ins Linker-Conf.-File schaut. > Und wie kann, bzw. > muss ich sie legen, damit ich sie mit dem Remap Befehl nicht > überschreibe und es trotzdem funktioniert? Am einfachsten an das Ende des RAM-Speichers ohne eigene Sections sondern mit vorgegebenen Größen. Sollte in den Beispielcodes von Atmel (Software-Package) demonstriert sein. Ist zumindest so für die GNU Beispiele. Ist aber nur die halbe Miete, neben den Stacks werden ja noch schreib/lese Variablen im RAM vorwaltet. Falls man an den Programmcode auch Speicheraddressen kopiert, die eigentlich vom Linker für Variablen zugewiesen wurden, passiert schlimmes. Ein Holzhammer-Lösung wäre evtl, wenn man die Origin der Region RAM so einstellt, dass genug Platz für den Code im RAM freibleibt. Ist aber nicht wirklich schick. Sollte durch Einstellungen im Linker-Conf.-File besser zu lösen sein. (Hoppla, bei der Vorschau gesehen, das dies von gerhard schon angemerkt wurde, ich lasse es einfach mal stehen:) Ansonsten bleibt noch die Möglichkeit per RAMFUNC (o.ä.) nur bestimmte Funktionen in RAM zu legen (IRQ-Wrapper, Handler usw.), Assembler code dann aber auch genau anschauen, insbes. wenn man von dort andere Funktionen z.B. aus der libc aufruft, denn die können sich noch im ROM befinden.
Hallo zusammen, danke schonmal für die Antworten! Hab auch gleich mal ins Linkerfile geschaut. Sieht für mich als Laien recht gut aus... place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, block UND_STACK, block ABT_STACK, block HEAP }; Davor werden noch die Größen der Stacks definiert. Hab jetzt auch mal das Linkerfile mit rangehängt Das bedeutet doch fürs remappen, er nimmt den Code im ROM und packt ihn an den Anfang vom RAM. Danach werden die ganzen Stacks ins RAM gelegt. Mittlerweile glaub ich mein Remap Befehl kommt einfach zum falschen Zeitpunkt. Hab auch gelesen dass vor dem Remappen die Execption Vektoren ins RAM kopiert werden sollen, damit wenn beim Remappen was schief geht, auch das noch abgefangen werden kann. Wann soll ich das am besten machen? In meiner Cstartup.s Datei? Dass das Remap durchgeführt wird sehe ich beim debuggen. Da sehe ich ja die Befehle die an der Adresse 0x00 sind und vergleiche die einfach mit den Befehlen am Anfang vom RAM. Das passt dann. Auch wenn ich nur bestimmte Funktionen in den RAM lege, würde ich das Thema gern verstehen. Da ich ja auch ein Betriebssystem verwende, müsste ich dann wohl recht viele Funktionen in den RAM mappen, wieso also nicht gleich alles? Die gesamte Applikation wird auf keinen Fall größer als 64k. Ach so, was meinst du denn mit SFE? und was mit w.r.e? "SFE? Wenn ja: gibt w.r.e die letzte Adresse einer section zurück, würde auch zum restlichen Code passen" Glaub wir sind der Lösung schon recht nahe. Nur der entscheidende Hint fehlt noch... Grüße Stefan
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.