Spielekonsole stm32

Ein paar Schützen für stm32; wie, warum, was ist passiert.



Vorwort


Als Fan der "alten" Schule der Schützen einerseits und des Embedded-Entwicklers andererseits habe ich mich immer gefragt, wie und warum es den Autoren dieser Zeit gelungen ist, ein neues Genre zu implementieren, das völlig neue Ansätze auf einer sehr "bescheidenen" Hardware erfordert. Und ich habe mich entschlossen, etwas Ähnliches mit Lösungen zu starten, die auf modernem MK basieren - hier gibt es Bare-Metal- und "bescheidene" Ressourcen und ein ziemlich leistungsfähiges Debugging-Tool (stm32, IMHO). Und so fiel meine Wahl auf das Discovery Development Board stm32f769i.

Anmerkungen


Derzeit ist die Montage nur in der Keil MDK-Umgebung (Bootloader, Spiele) oder mit arm-gcc + make (nur Bootloader) möglich. Derzeit verfügbare Ports für - Quake I (+ Mods), Doom (+ Mods), Duke Nukem (+ Mods), Hexen, Heretic. Mit allen Änderungen kann die Liste erheblich erweitert werden.

Lasst uns beginnen


In diesem Artikel werde ich versuchen, kurz die wichtigsten Ideen und Prinzipien ihrer Implementierung auf dem Weg zur Erstellung einer Spielekonsole speziell für die Erkennung von stm32f769i zu skizzieren. Außerdem werde ich versuchen, detaillierte technische Details zu vermeiden. Ich verfolge eher das Ziel, dem Leser eine andere Option für die Verwendung moderner MK vorzustellen. Mit "Spielekonsole" meine ich ein unabhängiges Gerät mit der Fähigkeit, "Benutzer" -Anwendungen auszuführen, ohne die Hauptsoftware zu aktualisieren.

Die Architektur


Da für die endgültige Implementierung die Möglichkeit erforderlich ist, verschiedene Spiele unabhängig voneinander auszuführen, ohne die MK-Firmware zu aktualisieren, wurde eine Version des „Bootloaders“ benötigt.

  1. Lader; Arbeit mit Speicher - "Installation" einer Anwendung (Spiel), starten.
  2. Treiber; Service HAL-Systemebene und zugehörige Funktionen, API an die Anwendung übertragen.
  3. Anwendung; Das endgültige Programm gibt die Steuerung nicht an den Bootloader zurück.

1. Bootloader


Es basiert auf dem IAP-Modell (In-Application-Programming) - Treiber am Beispiel der ST-Mikroelektronik.

Die Besonderheit dieses Ansatzes besteht darin, dass die Konfiguration des MK-Boot-Vorgangs nicht geändert werden muss. Der
gesamte „Körper“ des Bootloaders befindet sich im Hauptspeicher, und dies ermöglicht wiederum die Verwendung der stm32f769i-Erkennung „out of the box“.

Die Hauptfunktionalität dieser Ebene besteht darin, die .bin-Datei zu lesen, ihren Inhalt in den MK-Speicher zu schreiben und die Steuerung zu übertragen. In diesem Stadium besteht der Schlüsselpunkt darin, die Adresse des Einstiegspunkts und die Adresse des Stapelzeigers zu lesen, der zweite ist nicht erforderlich, da Anwendung gibt keine Kontrolle zurück -
Der Stapel wird gemeinsam genutzt und der Zeiger muss nicht neu geschrieben werden. Ein Aufruf kann auch über einen Zeiger auf eine Funktion erfolgen. Das Ergebnis ist also ein "Hybrid" -Lader - sein "Treiber" -Teil dient weiterhin der Anwendung, während die Ressourcen des Laders selbst entladen werden.

2. Fahrer


Der Treiber wird in Form eines „Wrappers“ über der HAL-Ebene erstellt, der Zugriff auf die erforderlichen Ressourcen bietet - Dateisystem, Anzeige \ Monitor, Sound, Gamecontroller \ Anzeigesensor. Zur weiteren Verwendung wird die Treiber-API in Form einer Zeigerstruktur über "Shared Memory" übertragen - ein Speicher, der sowohl für den Bootloader als auch für die Rückgabeseite reserviert ist. Eine solche Manipulation erfordert Speicherkosten, und vielleicht wäre die beste Lösung die Verwendung von SWI (Soft-Interrupt, SVC-Aufruf), aber dafür müssen Sie wiederum in der Lage sein, den Kontext zu ändern - weil Nicht alle Anrufe können in einem Interrupt bearbeitet werden. Außerdem wird "gemeinsam genutzter" Speicher verwendet, um Benutzerargumente zu übergeben (z. B. über die Konsole). Voraussetzung ist das Hinzufügen des Attributs no-init für diesen Abschnitt.Dadurch wird vermieden, dass es zum Zeitpunkt der Initialisierung der Benutzeranwendung mit der Laufzeitbibliothek überschrieben wird.

3. Anwendung


Das einzige, was Sie zum Zeitpunkt der Erstellung der Anwendung wissen müssen, ist die Architektur des Prozessorkerns. Es gibt keine Abhängigkeiten von der HAL. Es gibt auch keine Tabelle mit Interruptvektoren. Alle Interrupts werden vom Loader verarbeitet. Die Anwendung benötigt daher viel weniger Speicherplatz im Programmspeicher - da ein Teil der Funktionalität zusammen mit dem Bootloader / Treiber „geschützt“ ist, sodass Sie ihn im SRAM-Datenbereich (interner RAM) installieren können. Dies kann wiederum die Anzahl der Schreibzyklen des Flash-Speichers erheblich reduzieren und auch den Debugging- und Ausführungsprozess im Allgemeinen beschleunigen. Von den Minuspunkten: Zum Zeitpunkt des Debuggens ist es möglich, die Anwendung nur von außen aufzurufen, beispielsweise mit einem Befehl von der Konsole (COM-Port über ST-Link, VCOM). Hierfür wird eine sehr vereinfachte Version der Befehlszeile verwendet.

Ressourcen:

Lader , hal , Fahrer

Entwicklungsfunktionen


Erinnerung


Das erste, mit dem ich mich befassen musste, war das Problem der Zuweisung einer externen Speicherressource (SDRAM). Dies liegt an der Tatsache, dass einige Spiele mehr Speicher für den .bss-Abschnitt benötigen (duke nukem ~ 5.5mbytes). Ein solches Volume zu platzieren ist nur in sdram möglich, aber weil Der gleiche Speicher wird vom Bootloader zum Speichern temporärer Daten verwendet - Bilder, Ton, Dateiinhalte usw. -, die nur vor dem Start der Anwendung erforderlich sind. Es wurde beschlossen, die Verwaltung dieses Teils des Speichers aufzuteilen. Auf jeder Seite befindet sich ein Malloc / Free. Nach dem Start verwendet der Treiber Zeiger auf die Funktionen malloc \ free, die bei Bedarf als Parameter an die Aufruffunktion übergeben werden. Das heißt, nach dem Start des Spiels kann der Treiber die Zuweisung von sdram nicht direkt durchführen.Eine interessante Tatsache über D-Cache und I-Cache - aufgrund der Besonderheiten des Umgangs mit externem Speicher - müssen Sie beide Zeilen vor dem Start ausschalten, weil sdram wird neu initialisiert, alles wäre in Ordnung, aber es gibt ein "aber" - Sie müssen den Cache immer ungültig machen, andernfalls wird standardmäßig der gültige Status aller Zeilen beibehalten, während sie in dem Intervall überschrieben wurden, in dem der Cache deaktiviert wurde.
Eine weitere Funktion: Alle Bootloader-Daten werden im DTCM-Bereich abgelegt. Dadurch kann der Cache beim Zugriff auf den Speicher nicht verwendet werden (die MPU erlaubt dies auch). Infolgedessen werden Kohärenzprobleme bei der Arbeit mit DMA gelöst.
In Verbindung - CPU -> D-Cache -> Speicher <- DMA

Grafik


Zum größten Teil sind dies mehrere Bildskalierungsfunktionen (2x2, 3x3),
die Initialisierungsfunktion und das Laden der Palette. Der entscheidende Punkt ist die korrekte Angabe der Attribute des Frame-Speichers (durchgeführt über die MPU-Konfiguration). Für den Bootloader ist dies "Zurückschreiben, kein Schreiben zuweisen", um den Flickereffekt zu beseitigen Der Einzelpuffermodus wird verwendet, während die Anwendung "Durchschreiben, kein Schreiben zuweisen" verwendet, wodurch die höchsten FPS erzielt werden (Doom ~ 28-40).

Alle vorhandenen Spieleports arbeiten mit 8-Bit-Grafiken, es ist jedoch auch möglich, in den 16-Bit-Echtfarbenmodus zu wechseln (Änderungen seitens des Spiels erforderlich).
Es ist möglich, ein 8-Bit-Bild mit DMA2D zu skalieren, aber dieser Ansatz hat sich nicht ausgezahlt. Die Verarbeitung eines Bildes mit einer endgültigen Auflösung von 640 x 480 Pixel kostet ~ 1000 Unterbrechungen. Außerdem werden in Spielen viele Artefakte erzeugt - einzelne Bilder (Sprites, Polygone) werden nicht vollständig gerendert, weil In diesem Fall wird der gesamte Rendervorgang im Spiel parallel zur Bildschirmskizze ausgeführt.

Klang


Dieser Teil besteht aus einem einfachen 16-Bit-16-Kanal-Mixer, der auf Beispielen aus der ST-Mikroelektronik basiert. Außerdem wird ein I2S-Controller verwendet. Im Moment gibt es keine Möglichkeit, Audioformate untereinander zu konvertieren - dieser Teil wird je nach Anforderung auf Spielebene implementiert. Meiner Meinung nach verfügt Duke Nukem über die umfangreichsten Dienstprogramme für die Arbeit mit Sound, einschließlich und Hall.

Eingeben


Der Joystick-Treiber wird auch mit der USB-Hid-Klasse erstellt (tatsächlich wird das Gamepad als Computermaus definiert.). Der Anzeigesensor verwendet - wie ein Gamepad - denselben Kanal zum Übertragen von Ereignissen und ist äußerst unpraktisch.

Spiele


Untergang


Der stm32doom- Port wurde als Grundlage genommen , Soundunterstützung
hinzugefügt, mit den neuesten Änderungen im Schokoladen-Doom gepatcht , einige Korrekturen aufgrund von Killough von prBoom wurden hinzugefügt. Das Spiel ermöglicht es Ihnen, alle Modifikationen und Karten zu verwenden, die für Chocolate Doom verfügbar sind, einschließlich Szenerie und Sound von 3DO- und PS1-Versionen des Spiels hinzugefügt. Die Grafikoptimierung wurde hinzugefügt - die Auflösung des Textur-Renderings hängt von der Entfernung ab, die Lösung ist an verschiedenen Stellen mittelmäßig - ein Gewinn von + 3-7 Bildern pro Sekunde. verfügbar. Die neueste Version bietet auch Unterstützung für "transparente" Sprites - alles basiert auf der generierten Tabelle mit Kombinationen von Palettenelementen - etwas Ähnliches wird in Quake II und Spielen verwendet, die auf der Build-Engine basieren. Spiel inkl. Änderungen können vollständig abgeschlossen werden.

Ressourcen:

stm32doom , 3DO Doom , Chocolate Doom , Aktuelle Version

Duke Nukem


Basierend auf dem Schokoladenherzog Port . Es war keine Zeit, den Quellcode des Spiels vollständig zu verstehen, daher blieb alles "wie es ist", nur geringfügige Mängel wurden behoben. Über den Port können Sie auch offizielle und nicht ganz Änderungen vornehmen - Atomic Edition, Nuclear Winter usw. ...
Hinweis: Derzeit kann keine der Episoden des Spiels aufgrund vorhandener Mängel vollständig abgeschlossen werden.

Ressourcen:

Schokoladenherzog , Aktuelle Version

Beben i


Leider wurde der Link zum ursprünglichen Repository nicht beibehalten und ich kann ihn nicht finden, der
Port wurde unter dem Namen sdl quake ausgeführt. Von den Funktionen ist das Vorhandensein einer Client-Server-Architektur zu erwähnen, eines sehr „gefräßigen“ Stacks (~ 700 KB), aufgrund dessen zum ersten Mal viele interessante Situationen auftraten (armcc überwacht seine Verwendung nicht wirklich), weit verbreitete Probleme bei der Ausrichtung - möglicherweise sind dies Bedenken Nur der Armcc des Compilers, aber fast überall dort, wo ein Element der Struktur angesprochen wird, das größer als ein Byte ist. Andernfalls müssen Sie die Wrapper-Funktion verwenden, um Bytes zu lesen / schreiben. Das Spiel läuft ziemlich gut, mit durchschnittlichen fps ~ 15. Es können auch mehrere Episoden abgeschlossen werden, die nur im ersten Schwierigkeitsgrad mehr oder weniger komfortabel sind :)

Ressourcen:

Aktuelle Version

Hexen, Ketzer


Zum größten Teil erben sie die Doom-Engine, so dass sie aus Sicht der Portierung nahezu identisch sind (IMHO). In Hexen wurde die Möglichkeit hinzugefügt, das Spiel am ausgewählten Ort zu starten. Spiele können nicht vollständig abgeschlossen werden.

Ressourcen:

hexen stm32 , ketzerisches stm32

Ergebnis


Untergang , Herzog Nukem , Beben

Vielen Dank für Ihre Aufmerksamkeit.

All Articles