Erste Schritte

Die erste praktische Übung soll darin bestehen, dass ein ARM-Projekt angelegt und ein einfaches Programmgerüst erstellt wird. Danach schauen wir uns den Quellcode etwas näher an, übersetzen diesen und übertragen ihn in den Programmspeicher des ARM. Dazu muss SiSy ARM gestartet werden und die Experimentierhardware angeschlossen sein. Legen Sie ein neues Projekt mit dem Namen ARM_Tutorial an.

Wählen Sie das ARM Vorgehensmodell aus. Damit sind alle wichtigen Einstellungen für das Projekt und die darin enthaltenen Übungen als Default-Werte gesetzt. Nach Auswahl des Vorgehensmodells öffnet SiSy LibStore und bietet vorhandene Vorlagen für die weitere Arbeit an.

Wir brauchen für die ersten Schritte noch keine UML Bibliotheken. Damit können wir die Frage nach den Projektvorlagen mit „keine Vorlage verwenden“ beantworten oder den Dialog einfach mit der Schaltfläche Abbrechen beenden. Sie erhalten somit ein leeres Projekt. Die typische Aufteilung der SiSy-Oberfläche besteht aus Navigator, Assistent, Diagrammfenster und Editor. Die Aufteilung zwischen Diagrammfenster und Editor können Sie sich je nach Bedarf anpassen.

Legen Sie Ihr erstes kleines Programm an, indem Sie das entsprechende Objekt aus der Objektbibliothek per Drag & Drop in das Diagrammfenster ziehen. Geben Sie dem Programm den Namen Beispiel1 und überprüfen Sie, ob die Zielsprache auf ARM C++ eingestellt ist.

Im nächsten Schritt wird die Hardware ausgewählt:

  • Wenn Sie das STM32F4 Discovery benutzen wählen Sie STM32F407-Discovery und den Programmer ST-Link V2. Achten Sie auf die Seriennummer Ihres ST-Discovery. Es ist bei der Auswahl wichtig um welche Revisionsnummer es sich handelt (A-D).
  • Als Nutzer des mySTM32 Board light wählen Sie STM34F042 mySTM32 Board light und als Programmer mySTM32 Board light.

Falls Sie eine neuere SiSy Version ab 3.69 verwenden, achten Sie bitte darauf, dass Sie für diese Übungen die klassischen STM32 Bibliotheken nutzen und nicht die HAL.

Bevor wir uns dem Stress aussetzen und fast 40 Zeilen Programmcode abtippen, benutzen wir lieber eines der Features von SiSy, die Programmgerüste. Selektieren Sie das Grundgerüst für ein ARM C++ Programm und laden die Struktur über die Schaltfläche Struktur laden. SiSy fügt die ausgewählten Programmstrukturen jeweils an das Ende des bestehenden Quellcodes an.

Das nächste Dialogfeld mit Code-Wizzard überspringen wir und wählen die Schaltfläche Fertig stellen. Wir gelangen wieder in das Diagrammfenster von SiSy, im Editorfenster wird der geladene Quellcode angezeigt.

Zur Sicherheit können die vorgenommenen Einstellungen kontrolliert und ggf. geändert werden. Markieren Sie dafür im Diagrammfenster das Objekt kleines Progemm und wählen aus dem Kontextmenü (rechte Maustaste) Definieren. Überprüfen Sie die Einstellungen der Zielplattform unter Options(ARM). Wir benutzen ein Evaluierungsboard von ST, das STM32F407-Discovery.

Grundstruktur einer einfachen ARM Anwendung

Schauen wir uns den geladenen Quellcode etwas genauer an. Dieser lässt sich in mehrere Bereiche unterteilen. Zum einen ist da der Programmkopf mit Dokumentation und Deklarationen. Hier werden unter anderem die Deklarationen, zum Beispiel die Registernamen und die Funktionsdeklarationen des CMSIS und der Peripherietreiber für den STM32F4, aus externen Dateien in den Programmcode eingefügt (#include). Die stddef und stdlib sind exemplarisch eingefügte C-Standardbibliotheken.

//----------------------------------------------------------------------
// Titel     : Grundgerüst einer einfachen ARM C Anwendung in SiSy
//----------------------------------------------------------------------
// Funktion  : ...
// Schaltung : ...
//----------------------------------------------------------------------
// Hardware  : STM32Fxxx 
// Takt      : xxx MHz
// Sprache   : ARM C++
// Datum     : ...
// Version   : ...
// Autor     : ...
//----------------------------------------------------------------------
#include <stddef.h>
#include <stdlib.h>
#include "hardware.h"

Die Dokumentation sollte immer gewissenhaft ausgefüllt werden. Vor allem die Beschreibungen von Funktion und Hardware sind sehr wichtig. Das richtige Programm zur falschen Schaltung oder umgekehrt kann verheerende Folgen haben. Es folgt der Definitionsteil. Hier finden sich globale Variablen oder eben Unterprogramme, besser gesagt Funktionen. Diese müssen vor dem ersten Benutzen deklariert sein. Das bedeutet in unserem Fall, dass die Funktion initApplication noch vor dem Hauptprogramm der Funktion main steht. Es gibt durchaus die Möglichkeit, dies auch anders zu tun, aber das ist dann doch eher Bestandteil eines reinen C/C++ Tutorials. Besonders der C-Neuling beachte den Funktionskopf, in dem Fall mit ohne Typ und Parametern sowie den Funktionskörper, begrenzt durch die geschweiften Klammern.

void initApplication()
{
	SysTick_Config(SystemCoreClock/100);
	// weitere Initialisierungen durchführen
}

Als vorgegebenen Funktionsaufruf finden wir dort die Initialisierung des SysTick-Timers. Dieser liefert uns schon mal ein regelmäßiges Timerereignis. In den Übungen werden wir dies recht schnell benötigen. An dieser Stelle können noch weitere Funktionen eingefügt werden. Es folgt jetzt das Hauptprogramm. Dies ist durch das Schlüsselwort main gekennzeichnet. Auch hier sehen wir wieder die Begrenzung des Funktionskörpers durch die geschweiften Klammern. Innerhalb des Hauptprogramms findet sich zuerst die Initialisierungssequenz. Dabei sollte als erstes die Funktion SystemInit aufgerufen werden. Diese ist im Treiberfundus von ST enthalten und übernimmt die Grundinitialisierungen des ARM Kerns. Die Funktion ist quellcodeoffen und kann bei Bedarf durch den Entwickler für ein Projekt angepasst werden. Als Einsteiger nehmen wir diese, wie sie vorgefertigt ist. Danach initialisieren wir die Pheripherie. Das erfolgt durch Aufruf der bereits besprochenen Funktion initApplication.

int main(void)
{
	SystemInit();
	initApplication();
	do{
		// Eingabe
		// Verarbeitung
		// Ausgabe
	} while (true);
	return 0;
}

Zum Schluss folgen die Interrupt Service Routinen und Ereignishandler. Da diese nicht explizit zum Beispiel aus der main aufgerufen werden sondern in der Regel an für unser Anwendungsprogramm quasi externe Hardwareereignisse gebunden sind und automatisch auslösen können, stehen sie hinter dem Hauptprogramm als Letztes .

extern "C" void SysTick_Handler(void)
{
	// Application SysTick			
}

Bilden und Übertragen des Programms

Rekapitulieren wir kurz, was bisher getan wurde. Wir haben ein neues Projekt, ohne Vorlagen zu importieren, angelegt, ein kleines Programm in das Diagrammfenster gezogen und für die Zielsprache ARM C++ ein Grundgerüst geladen. Diesen Quellcode können wir jetzt übersetzen (kompilieren, linken) und in den Programmspeicher des Controllers (FLASH) übertragen (brennen).


Während der Übertragung sind Protokollausgaben in einem Konsolenfenster zu sehen. Nach der Übertragung wird das Programm automatisch gestartet. Der ARM „arbeitet“ jetzt. Da unser Programm selbst aber nur ein leeres Grundgerüst ist läuft der Controller faktisch im Leerlauf. Es sind keine Bausteine bzw. keine Peripherie aktiv.

Videozusammenfassung

Geschaft, wir haben erfolgreich unser erstes ARM-Projekt angelegt ein kleines Programm „geschrieben“, übersetzt und auf den Controller übertragen. Unsere Entwicklungsumgebung, bestehend aus Software und Hardware, funktioniert. Und hier diesen Abschnitt als Videozusammenfassung zum nochmal drüberschauen.

<

Nächstes Thema