Files
sdes_lab/sdes_skipt_mkdocs/docs/9_aufgabe5.md

5.0 KiB

Aufgabe 5 - JTAG-Debugging

9.1. Wissen

In dieser Aufgabe soll das Wissen in Bezug auf betriebssystemeigene Funktionen erweitert werden. Zur Erinnerung um im Zweifelsfall den richtigen Pfad zu finden: Der Zynq-7000 arbeitet mit Cortex A9 Cores. Wir nutzen die GNU Toolchain.

Alle Ergebnisse dieser Aufgabe werden im Post-Kolloquium besprochen.

9.1.1. Bedienung des Lauterbach-Debuggers

Die Trace32-Software enthält viele Komfort-Funktionen, die das Debugging aber auch die Bedienung der Software erleichtern sollen.

Window

Die vielen Fenster können schnell unübersichtlich werden und überfordern Einsteiger häufig. Daher können die Fenster automatisch angeordnet werden: Window->Cascade oder Window->Tile

Anpassungen die während des Betriebs an den Fenstern vorgenommen wurden sind, können in verschiedenen Konfigurationen gespeichert und geladen werden: Window->Store Windows to... oder Window->Load Windows from...

Weitere Fenster können über die Lauterbach-Befehlszeile geöffnet werden, indem die Caption des Fensters eingegeben wird. Viele der unter der Befehlszeile gelisteten Befehle sind auch Fenster und sind je nach Anwendungszweck unterschiedlich nützlich.

So kann sich der Befehlsverlauf mit

History

angezeigt werden lassen und eine Übersicht aller Tasks findet sich mit

Task.task

Diese ist insbesondere dann hilfreich, wenn man sich mit Kontext-Wechsel beschäftigt. Dies setzt aber voraus, dass die Tasks benannt wurden sind. Dazu benutzt man:

OSTaskNameSet(TASK_PRIORITY, TASK_NAME, &ERROR_CODE)

Break- und Watchpoints

Wie schon bei den Fenster-Einstellungen kann Trace32 auch Breakpoints permanent speichern, sodass eine Debug-Session unterbrochen und am nächsten Arbeitstag fortgesetzt werden kann. Das Speichern erreicht man mit:

STORE <filename>.cmm BREAK

Zum Laden benutzt man:

do <filename>.cmm

Um Watchpoints auf eine Variable zu setzen gibt es den Befehl

Var.Break.Set <variable_name>; /<access> /VarCONDition <condition>
  • <variable_name> ist mit der Variable zu ersetzen, die man überwachen möchte
  • ist der Zugriff: ReadWrite, Read, Write
  • ist eine Bedingung in C-Style; zum Beispiel: (a == 3). Kann aber auch weggelassen werden, falls bei jedem Zugriff getriggered werden soll.

Damit lassen sich auch schwer erreichbare Stellen debuggen. So kann man in den Kontext-Wechsel eines bestimmten Tasks springen, indem man auf OSPrioHighRdy triggered und als Bedingung die Priorität des aktuellen Tasks angibt:

Var.Break.Set OSPrioHighRdy; /Write /VarCONDition (OSPrioCur==<priority>)

Auch interessant ist es am Ende einer Funktion anzuhalten, zum Beispiel dann wenn der Rücksprung nicht mehr funktioniert.

break. set Symbol.end(<function_name>)

Ergebnisse speichern

Die Software besitzt auch Funktionen, die die Dokumentation der Ergebnisse erleichtert. So können Screenshots des übergeordneten Parent-Window gemacht werden: Window->Screenshot to file...

Genauso wie Screenshots eines einzelner, untergeordneter Fensters gemacht werden können. Dazu klickt man in die obere, linke Ecke des Fensters auf sein Icon und wählt Window Screenshot to file...

In diesem Menü kann der Fenster-Inhalt auch mit To Clipboard in Textform gespeichert werden.

9.2. Aufgabe

  • Ziel soll es zunächst sein, die Methode
UCOSStartup()

zu untersuchen.

  • Warum wird diese Methode noch vor dem Code aus der Main aufgerufen?
  • Welchen Sinn hat diese Methode?

Was macht die Methode:

CPU_Init()

Welche Aufgabe hat die Funktion:

Mem_Init()
  • Muss diese Funktion aufgerufen werden?

Betrachten Sie die Funktion:

OSInit ()
  • Was ist in diesem Kontext ein Hook?
  • Warum werden die Methoden:
OS_InitMisc()
OS_InitRdyList()
OS_InitTCBList()

benötigt? Was würde passieren, würden sie nicht ausgeführt werden.

  • inwiefern wird in dieser Methode Multitasking vorbereitet?
  • Was ist ein idle-Task und wofür wird er benötigt? Wo wird er erstellt? Welche Priorität sollte er haben?
  • Was ist ein Startup-Task? Was passiert dort?
  • Erklären Sie den Sinn der Methode
OSStart ()
  • Was passiert in der Funktion
OSTaskCreateExt()
  • Was macht die Funktion
OSTaskStackInit()
  • Was macht folgende Methode
OS_TCBInit()
  • Wie funktioniert die Methode
OStimeDly()
  • Untersuchen Sie die Methoden, warum wird eine kritische Sektion betreten?
OS_Sched() und OS_SchedNew()
  • Nachdem der Task erstellt wurde muss das Betriebssystem auch mit dem neuen Task arbeiten.
OSStartHighRdy()

Wofür sind in dieser Funktion die letzten 3 Anweisungen zuständig? Warum ist ein Ausrufezeichen in manchen Befehlen? Was macht das Zirkumflex hinter dem Befehl?
Tipp: Unser System arbeitet auf einer ARM-Cortex-A

  • Was passiert bei einem Kontextswitch? Schreiben Sie die Arbeitsschritte auf. Finden Sie heraus in welcher Methode der Kontextswitch ausgeführt wird. Welche wesentlichen Schritte werden abgearbeitet?