Wie führe ich eine Funktion aus dem RAM auf einem Cortex-M3 (STM32)?
Ich versuche, eine Funktion ausführen aus dem RAM auf einem Cortex-M3-Prozessor (STM32). Die Funktion löscht die und schreibt den internen Blitz, so dass ich auf jeden Fall muß sich im RAM befinden, aber wie mache ich das?
Was ich versucht habe ist dieser: Kopiere die Funktion in ein byte-array im RAM mit memcpy (überprüfung, dass es korrekt ausgerichtet), die Einstellung der Funktion-Zeiger auf den byte array ein, dann das aufrufen der Funktion(pointer).
Dies funktioniert gut für vielleicht 10 Anleitungen (die ich Folgen kann die Ausführung mit dem debugger), aber dann bekomme ich eine buss-Fehler und der Prozessor wird zurückgesetzt. Die buss-Fehler tritt auf den zweiten Durchgang durch eine Schleife, so dass der code sollte in Ordnung sein (da es den ersten pass). Ich denke, dass die schnelleren RAM-Zugriff mucks bis der buss timing in gewisser Weise...
Jedenfalls gibt es einen richtigen Weg, dies zu tun? Wie wäre es mit einer scatter-Datei so Aussehen, dass Orte, die eine Funktion im RAM automatisch (ich verwende Keil uVision für Cortex-M3)?
Edit: Mehr info:
Toolchain: RealView MDK-ARM V 4.10
Compiler: Armcc v4.0.0.728
Assembler: Armasm v4.0.0.728
Linker: ArmLink v4.0.0.728
Prozessor: STM32F103ZE
Den IMPRECISERR bit gesetzt ist, in der buss-Fehler registrieren, wenn Sie die reset passiert.
- Ähmm ich denke, Sie sollten mehr oder weniger post, die der Hersteller dem forum, wie Sie mit Hilfe einer bestimmten hardware-Komponente, dennoch kann man mehr details, welchen compiler benutzt du, wie sind Sie Debuggen, alle code-Beispiele, vielleicht einer person, die wissen könnte in der Lage sein, diese zu beantworten, als die anderen....
- Aber ich mag Sie Jungs mehr!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den crash auf loop-iteration ist wahrscheinlich, weil die Funktion Verzweigung in eine absolute Adresse und nicht bezogen auf die neue Funktion Speicherort im RAM. Würde auf den ursprünglichen code Lage an diesem Punkt die Ursache bus-Fehler, da der flash erase operation?
Ich glaube, Sie können markieren Sie eine Funktion kompiliert werden und in den RAM kopiert, richtig mit CARM durch anfügen der
__ram
Richtlinie zur definition der Funktion. Für Anleitung, wie Sie das gleiche zu tun mit den RealView-compiler finden Sie in der AUSFÜHRUNG VON FUNKTIONEN IM RAM technische support-Artikel:Sollte generieren startup-code zu kümmern kopieren Sie die Funktion RAM und die Verknüpfung Aufrufe, die Lage richtig. Ansonsten, wenn Sie brauchen, um dynamisch kopieren von beliebigen Funktionen an RAM, dann schauen Sie in die Kompilierung position independent code (PIC) mit RealView.
Ohne zu wissen, mehr über Ihre situation, kann ich nur empfehlen, ein paar Allgemeine Dinge... stellen Sie sicher, Sie haben einen gültigen stack für diese Funktion (oder vermeiden Sie alle stack-Operationen in der Funktion), dass deine interrupts deaktiviert sind, und dass alle Vektoren in der system-Vektor-Tabelle zeigen Sie nicht, um code, der geht Weg, wenn Sie erase flash. Schließlich, stellen Sie sicher, Ihre Funktion ist verbunden laufen an die Adresse, die Sie setzen es... der code darf nicht verschiebbar und kann springen zu einer Stelle in alt-Lage.
Weil der ARM hat eine begrenzte Fähigkeit, zu laden, sofortige Daten, Programme, das generieren von code für die ARM-Häufig Gegenüberstellung von code und Daten. Zum Beispiel, eine Aussage wie
könnte am Ende so etwas wie:
Beachten Sie, dass _myVar und 0x12345678 abgelegt werden darf, sofort nach dem code für die routine, in der Sie angezeigt, wenn Sie versuchen, um zu bestimmen, die Länge der routine mit einem label, das folgt die Letzte Anweisung, eine solche Länge nicht enthalten die zusätzlichen Daten.
Eine weitere Sache zu beachten, der ARM ist, dass aus historischen Gründen, code-Adressen haben oft Ihre " least significant bit gesetzt ist, obwohl der code eigentlich beginnt auf Halbwort-Grenzen. So, eine Instruktion, deren Adresse ist 0x12345679 belegen entweder zwei oder vier bytes, beginnend bei 0x12345678. Dies kann erschweren Adresse Berechnungen für Dinge wie memcpy.
Meine Empfehlung wäre zu schreiben Sie eine kleine routine, in Assembler zu tun, was Sie brauchen. Es ist nur ein paar Anweisungen, können Sie genau wissen, was der code tut und was Adresse Abhängigkeiten haben könnten, und Sie nicht haben, um sorgen über zukünftige compiler Versionen ändern Sie den code in einer solchen Weise, als etwas kaputt zu machen [z.B. die Dritte version der obige code würde kein problem haben, auch wenn
dat1
landete auf einer ungeraden halfword Grenze, da der M3 ist LDR-Anweisung verarbeiten kann, nicht liest, aber die vierte (etwas kompakter und schneller) version mit LDRM scheitern würde in einem solchen Fall; auch wenn heute die version eines Compilers verwendet vier LDR-Anweisungen, eine zukünftige version verwenden könnte LDRM].Mit dem IAR-compiler (ich weiß, Ihre Frage ist über Keil aber ich habe es nicht zum spielen) Sie können markieren Sie entweder das gesamte Projekt oder eine einzelne Datei sein, "position independent". Mit dieser in der Vergangenheit mit anderen Prozessoren es heißt, Sie können verschieben Sie es "irgendwo" und es wird immer noch funktionieren ok