2010-08-03 8 views
10

Ich arbeite mit einer eingebetteten Platine, aber ich kenne den Ablauf des Startup-Codes (C/Assembly) nicht.Ablauf des Startup-Codes in einem Embedded-System, Konzept des Bootloaders?

Können wir die allgemeinen Module/Schritte diskutieren, die bei einem Embedded System von der Startup-Aktion betroffen sind.

Nur ein Überblick auf hohem Niveau (algorithmisch) ist genug. Alle Beispiele sind willkommen.

/Kanu__

+1

Die Definition von 'Platform Independent' ... – zdav

+0

Was ist Ihre Anwendung soll und was ist yo Auf der Zielplattform kann ich vielleicht einige Bibliotheken vorschlagen oder ein paar Beispielprojekte anbieten. – marr75

+0

Meine Zielplattform ist Freescale MSC 8144 (SC 3400 X 4 Kerne) und Anwendung ist einige Multimedia bezogene –

Antwort

1

Die große Frage ist, ob Ihr Embedded-System ein Betriebssystem ausgeführt werden. Im Allgemeinen möchten Sie entweder Ihr Betriebssystem ausführen, eine Art Inversion der Kontrolle starten (ein Beispiel, das ich aus einem Schulprojekt kannte, war ein Telnet, das auf Anfragen mit RL-ARM oder einem Open Source TCP/IP lauschte) stack und hatte dann Callbacks, die es ausführen würde, wenn Verbindungen hergestellt wurden/Daten empfangen wurden, oder geben Sie Ihren eigenen Regelkreis ein (vielleicht ein Menü anzeigen und dann eine Schleife machen, bis eine Taste gedrückt wurde).

+0

hier läuft jetzt ohne Betriebssystem. In Zukunft nach der Integration aller Anwendungen kann ich gezwungen sein, das auch hinzuzufügen .. :-) –

22
  1. CPU erhält eine Einschaltrücksetzung, und springt zu einem definierten Punkt: der Rücksetzvektor des Flash beginnend, ROM usw.
  2. der Startcode (CRT - C Laufzeit) ausgeführt wird. Dies ist ein wichtiger Code, der von Ihrem Compiler/libc generiert wird:
    1. Konfigurieren und aktivieren Sie jeden externen Speicher (falls unbedingt erforderlich, andernfalls für späteren Benutzercode).
    2. Einrichten eines Stapelzeigers
    3. Löschen Sie das .bss-Segment (normalerweise). .bss ist der Name für die nicht initialisierte (oder auf Null gesetzte) globale Speicherregion. Globale Variablen, Arrays usw., die keinen Initialisierungswert (jenseits von 0) haben, befinden sich hier. Die allgemeine Praxis eines Mikrocontrollers besteht darin, diese Region zu durchlaufen und alle Bytes beim Start auf 0 zu setzen.
    4. Kopieren Sie vom Ende von .text die nicht-const .data. Da die meisten Mikrocontroller über Flash laufen, können sie dort keine variablen Daten speichern. Für Anweisungen wie int thisGlobal = 5; muss der Wert thisGlobal aus einem persistenten Bereich (normalerweise nach dem Programm in Flash, wie von Ihrem Linker generiert) in den Arbeitsspeicher kopiert werden. Dies gilt für statische Werte und statische Werte in Funktionen. Werte, die nicht definiert sind, werden nicht kopiert, sondern als Teil von Schritt 2 gelöscht.
    5. Andere statische Initialisierer ausführen.
    6. Anruf main()

Von hier wird der Code ausgeführt werden. Im Allgemeinen verbleibt die CPU in einem Interrupt-Aus-Zustand (plattformabhängig).

+0

Können Sie bitte den 3. Unterpunkt im 2. Hauptpunkt klären? –

+1

Ich würde den Stapelzeiger zuerst setzen, ARM Cortex-M speichert sogar den anfänglichen Stapelzeiger neben dem Rücksetzvektor. Mit einem Stack können Sie mit der Programmierung in C beginnen. Als nächstes wäre eine boardspezifische Subroutine (vorausgesetzt, der Stack befindet sich im internen RAM) für die Hardware-Initialisierung, z. B. Einrichten des Zugriffs auf externen Speicher und Einrichten einer schnelleren Systemuhr. Viele Mikrocontroller starten mit einem sehr langsamen Low-Power-Takt, der schnellere Takt beschleunigt dann die Initialisierung der .data- und .bss-Segmente. – starblue

3

Ziemlich offene Frage, aber hier sind ein paar Dinge, die ich abgeholt habe.

Für super simple processor s gibt es keinen echten Startcode. Die CPU erhält die Stromversorgung und startet dann die erste Anweisung in ihrem Speicher: Kein unnötiger Aufwand.

Ein wenig weiter oben haben wir MCUs wie AVRs und Bilder. Diese haben sehr wenig Startcode. Das einzige, was wirklich getan werden muss, ist die interrupt jump table mit entsprechenden Adressen einzurichten. Danach liegt es an dem Anwendungscode (dem einzigen Programm), sein Ding zu machen. Die gute Nachricht ist, dass Sie als Entwickler im Allgemeinen nicht über diese Dinge besorgt sein müssen: that's was libc is for.

Danach haben wir Dinge wie einfache armbasierte Chips; komplizierter als die avrs und pic's, aber immer noch ziemlich einfach. Diese müssen auch die Interrupt-Tabelle einrichten, sicherstellen, dass die Uhr korrekt eingestellt ist, und alle benötigten On-Chip-Komponenten starten (grundlegende Interrupts usw.). Werfen Sie einen Blick auf this pdf from Atmel, es beschreibt die Start-up-Prozedur für einen ARM 7-Chip.

Weiter oben in der Nahrungskette haben wir volle PCs (x86, amd64, etc.). Der Startcode für diese ist wirklich das BIOS, which are horrendously complicated.

+1

AVRs, PICs und einige Mikrocontroller-ARMs haben alle ihre Interrupt-Tabellen in Flash (die Interrupt-Prioritäten müssen normalerweise definiert werden). Ein vollständig verknüpftes C-Programm enthält Code zum Einrichten des Stapels, Löschen von .bss, Kopieren.Daten und dann springen zu main() –

+0

Ich denke, viele "einfache" CPUs (mindestens 8086) tatsächlich eine der letzten Anweisungen im Speicher ausführen, in der Regel ein Sprungbefehl, wo immer Sie Ihren Start-Code haben (was theatrus hat in seiner Antwort beschrieben). Wenn ich embedded höre, denke ich sofort an uController, nicht, dass es die einzige Möglichkeit ist, es ist nur dominant in diesem Bereich. – marr75

+1

@theatrus und @ marr75 Das wesentliche Problem bei dieser Frage ist, ob man nach dem "Hardware-Startup" oder dem "Code, den du schreibst, der zuerst läuft" fragt. Ich entschied mich für Letzteres zu gehen, da es mehr Programmierer-orientierte vs Compiler-Writer/Architekt orientiert ist. – zdav

0

Wo wird dann "BOOT LOADER" platziert? Es sollte vor dem Start-Code rechts liegen? Nach meinem Verständnis geht das Steuerelement vom Reset-Vektor zum Bootloader. Dort wartet der Code für eine kurze Zeitspanne, während der er erwartet, dass Daten auf den Controller/Prozessor geladen/heruntergeladen werden. Wenn es keine Daten erkennt, wird das Steuerelement zum nächsten Schritt übertragen, wie von theatrus spezifiziert. Aber mein Zweifel ist, ob der BOOT LOADER-Code neu geschrieben werden kann. Beispiel: Kann ein UART-Bootloader in einen ETHERNET/CAN-Bootloader geändert werden oder werden Daten, die mit einem beliebigen Protokoll gesendet werden, mithilfe eines Gateways in UART konvertiert und dann geblinkt.

+0

Willkommen zu SO, zusätzliche Fragen sollten wahrscheinlich in den Kommentaren gestellt werden oder eine andere spezifische Frage zu Ihrer Anfrage öffnen. Sie könnten diese spezielle Frage klären, oder eine einfachere Frage stellen, es scheint nicht wie Sie haben sich etwas Beantwortbares einfallen lassen. – marr75

1

Funktionen des Startup-Code für C/C++

  1. deaktiviert alle Interrupts
  2. Copies initialisiertes Daten aus ROM
  3. Uninitialized Datenbereich wird auf Null gesetzt rammen.
  4. Ordnet Raum und initialisiert den Stapel
  5. initialisiert die Stapelzeiger des Prozessors
  6. Erzeugt und initialisiert den Heap
  7. die Konstruktoren und Initialisierungen für alle globalen Variablen (C++ nur) Führt
  8. Aktiviert Interrupts
  9. Anrufe Haupt