====== eine Grafikanwendung ohne µGL GUI erstellen ====== Es muss nicht immer gleich das komplette [[http://de.wikipedia.org/wiki/Grafische_Benutzeroberfl%C3%A4che|Grafical User Interface (GUI)]] genutzt werden. Es ist auch möglich, mit der Programmierung der einfachen [[http://de.wikipedia.org/wiki/Schnittstelle_(Programmierung)|Schnittstelle]] eines [[http://www.myugl.de/_referenz/v003/PecLcd.htm|Displays]] anzufangen. Diese bildet die Grundfunktionen für Ausgaben auf einem Grafikdisplay ab: * Text * Pixel * Linie * Rechteck * Kreis * usw. Es soll als Erstes die Grundstruktur einer einfachen µGL Anwendung ohne GUI-Komponenten besprochen werden. ===== Vorbereitung ===== Falls Sie noch das Projekt vom [[µGL Schnellstart|Schnellstart]] offen haben, können Sie diesen Punkt überspringen. Erstellen Sie eventuell ein neues Projekt. Wählen Sie das Projekt-Profil ARM-Vorgehensmodell. Das Grafik-Framework, Vorlagen und Beispiele werden aus dem SiSy LibStore online bezogen. Sobald Sie das Projekt erstellt haben, bietet Ihnen SiSy geeignete Vorlagen aus dem LibStore an. >>>>{{:libstoreugl.png?nolink&600|}} Grenzen Sie die Liste ggf. mit dem Suchbegriff //"UGL"// ein. >>>>{{::ugl-vgm.png?direct&600|}} Wählen Sie die Vorlage //microGL Framework//. Nach dem Laden der Projektvorlage für das µGL-Framework erhalten Sie eine Darstellung im Diagrammfenster, die folgende Elemente enthält: >>>>>{{::projektvorlageneu.png?nolink&500|}} Die Pakete enthalten im Wesentlichen zwei Bibliotheken. Das ist das //SiSy ARM C++ Framework// für den STM32 und das //µGL Framework//. Des Weiteren erhalten Sie zwei Klassendiagramme mit Grundgerüsten für Grafikanwendungen als Vorlage. Dabei wird zwischen Anwendungen mit und ohne GUI Komponenten der µGL unterschieden. Schauen Sie sich ruhig ein bisschen in den Paketen um //(rechte Maustaste... "nach unten")//. ===== Ein neues Klassendiagramm (Programm) anlegen ===== Gehen Sie in Ihrem Projekt auf die oberste Hierarchieebene //(rechte Maustaste... "nach oben", bis zum Vorgehensmodell)//. Ziehen Sie ein Element vom Typ Klassendiagramm per Drag & Drop in das Diagrammfenster des Vorgehensmodells. Geben Sie dem Diagramm einen möglichst sinnvollen Namen. >>>{{::kdanlegenugl.png?direct&600|}} Legen Sie die Hardware für die Zielplattform fest. Mit den empfohlenen Boards kommen dabei folgende Varianten infrage: * STM32F4 Discovery mit ST-Link V2 * STM32F429 Disco mit ST-Link V2 >{{::target.png?direct&400|}}{{::targets2.png?direct&250|}} Nachdem Sie die korrekte Zielhardware eingestellt haben, öffnen Sie das neue Klassendiagramm //(rechte Maustaste "nach unten")//. Es wird Ihnen aus dem LibStore eine Auswahl von Diagrammvorlagen angeboten. Schränken Sie die Anzahl der Vorlagen zum Beispiele mit dem Suchbegriff UGL ein. Wählen Sie die Vorlage "Grundgerüst einfache µGL Anwednung für STM32F4xx". Achten sie auf die Bezeichnung der Zielhardware. >>{{::ggauswahl.png?direct&600|}} Importieren Sie die gewählte Diagrammvorlage aus dem LibStore. ===== Das Grundgerüst ohne µGL GUI ===== Das Grundgerüst für eine einfache Grafikanwendung ist recht übersichtlich. Es umfasst folgende Elemente: * die Anwendungsklasse //Application// * dessen Instanz //app// * das Basis-Template //ArmAppKernel// (Application ist ein ArmAppKernel) * die Klasse //Display// als Realisierung des/der Templates //Lcd320x240_SSD1289_F407_Conection_Version_4// * die Application besitzt eine sichtbare Instanz vom Typ //Display// mit dem Namen //display// (Aggregation) * nötige Pakete >>{{:ggohnegl.png?direct&750|}} Die Applikationsklasse enthält die Operationen: * //onStart//, diese wird einmalig nach dem Einschalten oder einem Reset des Controllers ausgeführt * //onWork//, diese wird wiederholt aus der //Hauptschleife (main loop)// des Frameworks aufgerufen (Polling) Die notwendige Initialisierung des Displays wurde durch die Zuweisung des/der korrekten Templates zum Display erledingt. Wir können sofort mit den ersten Grafikausgaben beginnen. Sollte die Operation //onStart// bereits Beispielcode enthalten, löschen Sie diesen bitte. Wir möchten den Code Stück für Stück erstellen und möglichst verstehen ;-) Wen die Hintergründe nicht so interessieren der macht weiter mit dem [[http://www.myugl.de/_wiki/doku.php?id=grundsruktur_einer_einfachen_anwendung_mit_grafikdisplay#das_erste_programm_erstellen_und_uebertragen|Erstellen und Flashen der Anwendung]]. ==== Die benötigten Pakete ==== Auch eine einfache Grafikanwendung besteht nicht nur aus zwei oder drei Klassen. Es ist der Rückgriff auf eine Reihe von Paketen (Bibliotheken) erforderlich, um den Aufwand für den Anwendungsentwickler erträglich zu halten. Die benötigten Pakete umfassen zum einen die Basispakete für den Controller selbst und zum anderen die Gerätetreiber und Unterstützungspakete für das Display. >>>{{::usedpackages.png?direct&600|}} ==== Das AppKernel-Template ==== Die Anwendungsklasse (Hauptklasse) realisiert einen //ArmAppKernel//. Um herauszufinden welche Eigenschaften unsere Anwedung durch die Zuweisung besitzt, folgen wir dem Template. Mit //rechte Maustaste, Quelldiagramm öffnen// navigiert SiSy den Anwendungsentwickler zum originalen "Standort" einer verknüpften Klasse oder eines Templates. >>>{{::armappkernel.png?direct&500|}} Das Template //ArmAppKernel// enthält offensichtlich die Hauptfunktion //main// mit der Initialisierungssequenz und der Hauptschleife //(mainloop)// sowie den //SysTickHandler//. Bei näherer Betrachtung der Operationen scheint der //AppKernel// noch die Rolle eines //Nachrichtenverteilers// und //Scedulers// zu spielen. Folgen wir der Realisierungslinie weiter. >>>{{::pecappkernel.png?direct&300|}} Jetzt wird der Umfang unserer Anwendung klarer. Die Klasse //Application// ist ein //AppKernel// und gleichzeitig ein //AppModul//. Damit verfügt die //Application// über folgende Eigenschaften: * Hauptfunktion mit Initialsierungssequenz, Nachrichtenverteiler, Hauptschleife, einfacher kooperativer Sceduler * vorbereitete Events/Nachrichten: * **onPower**, für low level Inititalisierungen bevor SysTick initialisiert wird * **onStart**, für Initialisierung der Softwarekomponenten (SyStick läuft) * **onWork**, Ereignis aus der Hauptschleife (Polling) * **SysTick**, 10ms ApplicationTimer (Interrupt) * **onTimer10ms**, aus dem SysTick generiertes Event (Interrupt) * **onTimer100ms**, aus dem SysTick generiertes Event (Interrupt) * **onTimer1s**, aus dem SysTick generiertes Event (Interrupt) * die //Application// ist das erste Element einer Liste von //AppModulen// * alle //AppModule// erhalten die oben aufgeführten Nachrichten >{{::seqarmapp.png?direct&350|}}{{::seqsystick.png?direct&350|}} ==== Das DisplayDriver-Template ==== Wie bereits erwähnt, navigiert SiSy mit //rechte Maustaste, Quelldiagramm öffnen// den Anwendungsentwickler zum originalen "Standort" einer verknüpften Klasse oder eines Templates. In SiSy erfolgt die Zuweisung von konkreten Ressourcen an ein abstraktes Interface oft über das Tempos-Konzept. Dabei handelt es sich um abstrakte generische Strukturen, aus denen baukastenartig konkrete Klassen zusammengesetzt werden (generische Klassen). Der SiSy-Codegenerator fügt die einzelnen Templates und Interfaces sowie Parameter zu einer kompletten Klasse, in diesem Fall einer Display-Treiberklasse, zusammen. >{{::drivertemplate407v4.png?direct&750|}} Wählt man das betreffende Template aus, sind die konkreten Realisierungsparameter sichtbar. >>> Schaltung: STM32F407-Discovery mit LCD-Adapter + LCD-Modul ohne Latch LCD Bus STM32F407 21 = DB00 01 D8 22 = DB01 02 D9 23 = DB02 03 D10 24 = DB03 04 D2 ... ... ... 28 = DB03 04 D11 07 = DB04 05 E4 ... ... ... 14 = DB15 E15 04 = RS 19 B1 05 = WR 20 B0 Der Anwendungsentwickler muss //"nur noch"// das bzw. die geeigneten Templates an seine Realisierungsklasse //"anhängen"// und den Rest erledigen der Codegenerator und der Compiler. ==== Das erste Programm erstellen und übertragen ==== Das Display verfügt über einen eigenen Speicher ([[http://de.wikipedia.org/wiki/Framebuffer|Framebuffer]]). Dieser Speicher enthält das aktuell darzustellende Bild. Nach einem Reset des Controllers ist dieser Speicher noch mit den zuletzt dargestellten Inhalten gefüllt. Es ist somit empfehlenswert, sichereitshalber am Anfang das Display immer aufzuräumen. Das geschieht, indem wir dem Display die Nachricht //[[http://www.myugl.de/_referenz/v003/PecLcd.htm#285_Details|clearScreen]]// senden. Sollte aus dem Schnellstart oder aus der Vorlage noch Beispielcode in der Operation //onStart// enthalten sein, löschen Sie diesen bitte. Tragen Sie folgende Codezeilen in die Operation //OnStart// ein: >>>**onStart():** >>><code cpp> // das Display löschen display.clearScreen(); </code> >>>{{::seqclearscreen.png?direct&300|}} Wählen sie im Aktionsmenü (grüner Mann) //Erstellen, Brennen und Ausführen//. >>>{{:7_erstellen_und_uebertragen.png?600|}} Auf dem Display zeigt sich nach dem erfolgreichen Erstellen und Übertragen folgendendes Bild: >>>{{:6_clearscreen.jpg?300|}} ====== Videozusammenfassung ====== Somit haben wir auch schon unsere erste Grafik-Anwendung erstellt und auf den Controller übertragen. Als Zusammenfassung dieses kurzen Abschnittes das Ganze nochmal als Video. >>><flashplayer width="600" height="475" position="0">file=http://youtu.be/MrHcS6mntUI</flashplayer> >>>[[http://youtu.be/MrHcS6mntUI|besser auf youTube]] ====== nächster Abschnitt ====== Naja, Bild ist für das was jetzt auf dem Display zu sehen ist vielleicht etwas übertrieben ;-)\\ Wir sollten als Nächstes ein kleines //"Hallo <del>Welt</del> Display"// ausgeben. * [[hallo_welt_ohne_ugl|Hallo Grafik-Welt ohne µGL GUI]] * [[start|zurück zur Übersicht]]