Eingebettete Studiennotizen (12) Kompilieren des Startcodes zum Einrichten des Stapels und Aufrufen der C-Sprache

C-Laufzeitanforderungen und die Bedeutung des Stapels

„C-Sprachlaufzeit (Runtime)“ erfordert bestimmte Bedingungen, die von der Assembly bereitgestellt werden. Die C-Sprachlaufzeit benötigt hauptsächlich einen Stapel.

Die Beziehung zwischen C-Sprache und Stack: Lokale Variablen in der C-Sprache werden durch den Stack implementiert. Wenn unser Assembly-Teil keine sinnvolle und zulässige Stapeladresse für den C-Teil voreinstellt, schlagen die im C-Code definierten lokalen Variablen fehl und das gesamte Programm stirbt ab. (C-Sprache benötigt Assembler, um Stapelspeicher einzurichten und lokale Variablen zu realisieren.)

Wenn wir ein Einzelchip-Mikrocomputerprogramm (z. B. 51 Einzelchip-Mikrocomputer) oder ein Anwendungsprogramm schreiben, legen wir den Stapel nicht fest, aber das C-Programm kann trotzdem ausgeführt werden. Der Grund ist: Im Mikrocontroller wird beim Initialisieren der Hardware ein standardmäßig verfügbarer Stapel bereitgestellt. Tatsächlich fügen nicht alle C-Programme, die wir in das Anwendungsprogramm schreiben, der Compiler (gcc) beim Verknüpfen automatisch einen Header für uns hinzu. dieser Header Es handelt sich um einen durch Assembly implementierten Code, der die Ausführung unseres C-Programms leitet. Dieser Code hilft unserem C-Programm beim Einrichten des Stapels und anderer Laufzeitanforderungen.

7 Arbeitsmodi von CPU und Stacks in verschiedenen Modi

In den 7 Arbeitsmodi von ARM verfügt jeder Arbeitsmodus über ein eigenes unabhängiges SP-Register (r13). Die Gründe für diesen Entwurf sind:

Wenn jeder Modus denselben SP verwendet, bedeutet dies, dass das gesamte Programm (Betriebssystemkernprogramm, vom Benutzer geschriebenes Anwendungsprogramm) derselbe Stapel ist. Wenn Ihr Anwendungsprogramm einen Fehler macht (z. B. einen Stapelüberlauf), wird der Stapel des Betriebssystems beschädigt und das gesamte Betriebssystemprogramm stürzt ab. Ein solches Betriebssystemdesign ist sehr fragil und unvernünftig.

Die Lösung besteht darin, unterschiedliche Stapel in verschiedenen Modi zu verwenden. Unser Betriebssystemkernel verwendet seinen eigenen Stapel, und Anwendungen verwenden auch ihre eigenen unabhängigen Stapel, die separat sind und sich nicht gegenseitig beeinflussen.

Wenn wir den Stapel jetzt einrichten möchten, müssen wir zunächst unseren eigenen Modus finden und dann den Stapel in unserem eigenen Modus auf eine vernünftige und legale Position einstellen.

Hinweis: Das System wechselt nach dem Zurücksetzen standardmäßig in den SVC-Modus

Wie greifen wir im SVC-Modus auf den SP zu? Stellen Sie zunächst den Modus auf SVC ein und bedienen Sie dann den SP direkt. Da sich das System jedoch nach dem Zurücksetzen im SVC-Modus befindet, stellen Sie den SP einfach direkt ein.

Konsultieren Sie die Dokumentation und setzen Sie den Stapelzeiger auf einen zulässigen Speicherort

Der Stapel muss der aktuell verfügbare Speicher sein (verfügbar bedeutet, dass Speicher vorhanden sein muss, der initialisiert und zugänglich ist, und dieser Speicher wird nur von uns als Stapel verwendet und nicht von anderen Programmen angefordert).

Wenn die CPU gerade zurückgesetzt oder gestartet wird, wurde der externe DRAM nicht initialisiert und der einzige verfügbare Speicher ist iSRAM (da er ohne Initialisierung verwendet werden kann). Daher können wir im iSRAM nur einen Teil des Speichers als SVC-Stack finden.

In ARM erfordert ATPCS (ARMs Spezifikation zur Art und Weise, wie Programme implementiert werden sollen) die Verwendung von vollständigen und reduzierten Stapeln, es handelt sich also grundsätzlich um vollständige und reduzierte Stapel. .

Voller Minusstapel:

In den Stapel schieben: Zuerst den Zeiger nach unten bewegen und dann die Daten speichern. Aus dem Stapel heraus: Zuerst aus den Daten herausfahren und dann den Zeiger nach oben bewegen

In Kombination mit der iRAM-Speicherzuordnung in iROM_application_note ist ersichtlich, dass der SVC-Stack auf 0xD0037D80 gesetzt werden sollte

3.2.4 Gegenseitiger Aufruf zwischen Assembler und C-Programm

bl cFunktion

3.2.5 C-Funktionen schreiben und von Assembly aufgerufen werden

Erstellen Sie eine C-Quelldatei (led.c) und fügen Sie sie zum Projekt hinzu. Achten Sie beim Hinzufügen darauf, das Makefile zu ändern

Nachdem Sie den Stapel im Assembly-Startcode eingerichtet haben, rufen Sie mit bl xxx die Funktion xxx in C auf

3.2.6 Methode zur Verwendung der C-Sprache für den Zugriff auf Register

Die Adresse des Registers ähnelt der Speicheradresse (E/A und Speicher werden einheitlich adressiert), daher besteht das Problem hier darin, die C-Sprache zum Lesen und Schreiben von Registern zu verwenden, also die C-Sprache zum Lesen und Schreiben von Speicheradressen. Um in der Sprache C auf den Speicher zuzugreifen, werden Zeiger verwendet.

unsigned int *p = (unsigned int *)0xE0200240;

*p = 0x11111111;

Vereinfacht zu:

*((unsigned int *)0xE0200240) = 0x11111111;

Magie flüchtig

Die Funktion von Volatile besteht darin, dass der Compiler das Programm beim Kompilieren nicht optimiert. Optimierung ist manchmal in Ordnung, aber manchmal ist sie klug. Wenn eine Ihrer Variablen flüchtig ist und Sie nicht möchten, dass der Compiler bei der Optimierung hilft, fügen Sie einfach volatile hinzu, wenn die Variable definiert ist.

Zusammenfassen

Gegenseitige Aufrufe zwischen C- und Assembly-Funktionen (die wahre Bedeutung von Funktionsnamen und Assembly-Beschriftungen)

Die Art und Weise, wie die C-Syntax den Speicherzugriff kapselt (die Technik, Zeiger für den Speicherzugriff zu verwenden)

Die Bedeutung der Montage (Startcode und Effizienzschlüsselteile)

Der Lernweg von Embedded IoT ist sehr lang und viele Menschen verpassen das hochbezahlte Angebot, weil der Lernweg falsch ist oder die Lerninhalte nicht professionell genug sind. Aber keine Sorge, ich habe für Sie eine Lernressource von über 150 G zusammengestellt, die im Grunde alle Inhalte des eingebetteten IoT-Lernens abdeckt. Klicken Sie hier , um den Code zu scannen und die Informationen zum Gruppenleiter einzugeben . 0 Yuan, um Lernressourcen zu erhalten, damit Ihr Lernpfad reibungsloser verläuft! Denken Sie daran: „Gefällt mir“, „Folgen“, „Lesezeichen“ und „Weiterleiten“!

おすすめ

転載: blog.csdn.net/m0_70888041/article/details/132684106