Heim  >  Artikel  >  System-Tutorial  >  Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

王林
王林nach vorne
2024-02-12 08:00:04827Durchsuche

Unter Linux gibt es viele Programmierideen, die es wert sind, gelernt zu werden. Viele technische Experten haben diese Ideen und Mechanismen auf die Mikrocontroller-Programmierung angewendet und insbesondere den automatischen Initialisierungsprozess des Linux-Kernels in STM32 simuliert.

Generell befolgen wir beim Schreiben von Programmen bestimmte Routinen. Wir werden Funktionen nacheinander gemäß der sequentiellen Logik ausführen.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Wenn die Logik sehr komplex ist und viele Module umfasst, wird der nacheinander ausgeführte Code aufgebläht und die Module sind sehr eng miteinander verbunden. Es gibt verschiedene Peripherietreiber im Linux-Kernel, und es ist fast unmöglich, sie logisch hintereinander auszuführen.

Der Kenrel-Code kann eine so große Menge an Code enthalten, er ist groß, aber nicht chaotisch, er trennt effektiv jede Ebene und jedes Modul, und eine große Menge an Code ist logisch zusammen organisiert, und dieser Initcall spielt eine entscheidende Rolle.

Durch die Nachahmung dieser Methode löschen wir endlich den Hauptfunktionscode im Bild, trennen diese Logik und erreichen dieselbe Funktion.

Wie man eine solche Funktion implementiert, erfordert einige Hintergrundkenntnisse:

1. Organisation des Programmcodes

2. Kenntnisse im Zusammenhang mit Link-Skripten.

3. Anwendung von Funktionszeigern.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Code-Organisation, wie im Bild, Sie müssen wissen, in welchen Abschnitten des Programms die Variablen a, b und die Funktionszeiger f, f2 gespeichert sind. Sie können diese STM32-Startcode-Implementierung in der C-Sprache lesen. f werden im BSS-Segment gespeichert, b und f2 werden im Datensegment gespeichert, da der Anfangswert angegeben wurde. Durch die Implementierung dieses intcall werden die Daten, die automatisch initialisiert werden müssen, in ein benutzerdefiniertes Segment wie .initcall eingefügt.

Um es in einen bestimmten Abschnitt einzufügen, müssen Sie das Schlüsselwort attribute((section)) verwenden, um den Datenspeicherabschnitt zu ändern.

Das aktuelle Programm wird mit diesen Segmenten kompiliert, mit Ausnahme von .isr_vector, das ebenfalls hinzugefügt wird, werden die anderen vom Compiler standardmäßig verwendet.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Fügen Sie zuerst einen Code hinzu:

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Natürlich reicht das nicht aus, Sie müssen auch den Linker (LD) anweisen, den .initcall-Abschnitt in das Programm zu verknüpfen, daher muss auch dieser Abschnitt geändert werden.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Dieser Abschnitt ist um 8 Bytes ausgerichtet, definiert zwei globale Variablen und verknüpft diese Daten in der Reihenfolge 0-5. Schauen wir uns mit diesen beiden Modifikationen jeden Abschnitt des Programms an.

Als Bild:

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Es gibt ein zusätzliches rotes Kästchen für den Abschnitt „.initcalls“. Dieser Abschnitt umfasst insgesamt 8 Bytes, beginnend bei 0x80005a8.

Schauen wir uns die spezifische Situation dieses Absatzes mit dem Readelf-Tool an.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Es entspricht dem Größentool oben und die Adresse des grünen Felds lautet SystemInit (0x08000231, Little-Endian-Modus.)

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Durch Attribut und Änderung des Link-Skripts wird die Funktionszeigervariable im Abschnitt .initcall platziert.

Wie ruft man diese Funktion auf? Sie ähnelt den vorherigen Initialisierungsdatensegmentdaten. Sie durchläuft dieses Segment, nimmt dann die Funktionsadresse heraus, wandelt die Adresse im Segment dann zwangsweise in einen Funktionszeiger um und ruft sie dann direkt auf .

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Dieses Bild wird implementiert, indem die Funktionsadresse aus dem .initcall-Abschnitt entnommen und dann direkt aufgerufen wird. Es ist sehr leicht, die Adresse der Funktion mit der Adresse der Funktionszeigervariablen zu verwechseln.

Mit dem so geänderten Code kann die automatische Initialisierungsfunktion zwar angepasst werden, aber jedes Mal muss ich einen so langen Abschnitt von static initcall_t __ attribute__(( __ used__,__ section__(“.initcall.0.init“) schreiben )), das ist unbequem durch Makros im Linux-Kernel geändert.

Das Gleiche gilt für dieses.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Fügen Sie einige Makros hinzu, die in der logischen Reihenfolge des Programms ausgeführt werden

0, low_level_init Initialisiert beispielsweise die Grunduhr des Systems

1, arch_init Legen Sie beispielsweise die CPU-Architektur fest, z. B. die Initialisierung einiger NVIC-Initialisierungen.

2. dev_init initialisiert Peripheriemodule wie i2c, flash, spi usw.

3. board_init nimmt einige Einstellungen für bestimmte Hardware-Boards vor.

4. os_init Einige Einstellungen des Betriebssystems, wie Dateisystem, Netzwerkprotokollstapel usw.

5, app_init führt schließlich das Benutzerprogramm aus.

Ändern Sie Ihr eigenes Programm und verwenden Sie stattdessen Makros. Auf diese Weise wird der Aufruf von do_initcalls in der Reihenfolge 0, 1 bis 5 ausgeführt.

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Schauen wir uns zum Abschluss noch den Abschnitt „initcall“ an:

Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32Simulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32

Fügen Sie auf diese Weise einfach etwas wie dev_init(), app_init() zur automatischen Initialisierungsfunktion hinzu, und sie wird automatisch aufgerufen, ohne dass sie einzeln in der Hauptfunktion ausgeführt werden müssen.

Zum Beispiel wird die Initialisierung der i2c-Steuerung in dev_init platziert. Initialisieren Sie einfach jedes Slave-Gerät mit app_init. Es ist nicht erforderlich, es zu initialisieren um das Original zu ändern, ein hohes Maß an Kopplung zwischen getrennten Modulen.

Dies simuliert, dass die Linux-Kenerl-Initialisierung und -Überprüfung erfolgreich war und schließlich in die Bibliothek hochgeladen wurde.

Das obige ist der detaillierte Inhalt vonSimulieren Sie den automatischen Linux-Initialisierungsprozess auf STM32. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:lxlinux.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen