Files
sdes_lab/sdes_skipt_mkdocs/docs/11_aufgabe7.md

4.0 KiB

11. Aufgabe 7 - Integration

11.1. Aufgabenteil 1

In dieser Aufgabe sollen die zuvor erstellten Programmodule zusammengesetzt werden. Es soll ein balancierender Roboter entstehen. Erstellen Sie auf Basis des in Aufgabe 6 genutzten Taskset-Simulators ein Taskset, dass ihre Tasks periodisch ausführt. Denken Sie daran ihre Init-Funktionen einzutragen. Nachfolgend werden die Anforderungen an die bisherigen Programme aufgelistet:

11.1.1. PID

Eingänge:

  • Aktueller Winkel der IMU
  • Sample Time

Funktion

  • PID Wert erstellen

Ausgänge

  • PID Wert zwischen -1000 und 1000

Hinweis: Der PID Regler mittelt für die ersten 10 Sekunden nach Start den Nullpunkt zur Kalibrierung

11.1.2. IMU

Funktion

  • IMU initialisieren
  • Werte über I2C auslesen

Ausgänge

  • IMU Winkel

11.1.3. Motortreiber

Eingänge

  • PID Wert

Funktion

  • Ansteuern der Richtung der Motoren für vorwärts und rückwärts
  • Regeln der Frequenz der Steps: Frequenz: min. 800us/step, max 100us/step

11.2 Aufgabenteil 2

Sie finden sich nun in einem Szenario der Wirtschaft: Ihr Vorgesetzter schränkt ihre Ressourcen auf dem genutzten Steuergerät ein, weil diese anderweitig genutzt werden. Verändern Sie dazu in der Datei gt_tasks.c das Struct GT_AllTasks wie folgt und fügen Sie die Zeile

{50, 0, 0, {3, 5}};

Quellcode 11.1: Ergänzung Task Timing Struct

hinzu. Außerdem sollen Sie in dem Struct GT_Tasks die Zeile

{ GT_TASK_DEF, GT_ACT_INT, 4, 29, NULL, NULL, NULL, GT_RUNABLE_NULL,
  GT_INTERNAL_NULL, (void *)&GT_AllTasks[4]},

Quellcode 11.2: Ergänzung Task Struct

hinzufügen. Achten Sie darauf die Konstante GT_NUM_OF_TASKS anzupassen. Ihre Aufgabe ist es nun, die Funktionalität des Roboters wiederherzustellen. Untersuchen Sie dafür, wo im Programm CPU Zeit eingespart werden kann.

Um die in diesem Bereich genutzte CPU-Zeit zu reduzieren bietet es sich an die Kommunikation mit der inertialen Messeinheit zu verändern. Die Hardwareeinheit des Xynq- 7000 macht es möglich nach jeder abgeschlossenen Kommunikation einen Interrupt auszulösen. Wir können die Kontrolle somit während des Senden an andere Tasks abgeben. Orientieren Sie sich für das Erstellen und Verknüpfen des Interrupts an dem des Timers. Suchen Sie nach geeigneten Funktionen vergleichbar zu denen, die bei der Einrichtung des Timer-Interrupts genutzt wurden. Grundsätzlich sollten Sie wie folgt vorgehen:

  • Erstellen Sie einen Interrupt und suchen Sie die korrekte Interrupt-ID heraus, geben Sie als Interrupt-Handler MasterInterruptHandler an.
  • Die I2C Instanz hat einen Statushandler der angegeben werden kann, er bietet sich an um die Semaphore zu pushen
  • Die Funktionen XIicPs_MasterSendPolled und XIicPs_MasterRcvPolled haben passende Gegenstücke zur Nutzung mit Interrupts der I2C Hardware. Nach dem Aufrufen der Funktion muss auf die Fertigstellung gewartet werden. Dies wird über den Semaphore realisiert.

Zunächst muss eine Interrupt-Service-Routine (ISR) erstellt und im Setup dem Iic-StatusHandler übergeben werden.
Erstellen Sie zudem ein globales Semaphor. Nutzen Sie hierfür die Funktion

OS_SemCreate(...);

Tipp: Überlegen Sie sich was ein sinnvoller initial-Wert für das Semaphor in diesen Anwendungsfall ist.

Wir erstellen einen Interrupt welcher ausgelöst wird, wenn die I2C Kommunikation abgeschlossen ist. Die Interrupt ID ist XPS_I2C1_INT_ID. Dazu können die folgenden Methoden genutzt werden.

UCOS_IntVectSet(...);
UCOS_IntSrcEn(...);

Zuletzt müssen Sie noch die I2C Kommunikation überarbeiten. Während der Übertragung soll dem System nun erlaubt werden andere Tasks zu schedulen. Überlegen Sie hierfür wann das von Ihnen erstelle Semaphor dafür Ressourcen freigeben und wann wieder blockieren soll.
Hierfür können folgende Methoden genutzt werden:

OSSemPend(...);
OSSemPost(...);

**Hinweis:** Sie müssen zudem die Funktionen
XIicPs_MasterSendPolled(...);
// und
XIicPs_MasterRecvPolled(...);

durch folgende Funktionen ersetzen:

XIicPs_MasterSend(...);
XIicPs_MasterRecv(...);