Files
sdes_lab/sdes_skipt_mkdocs/docs/9_aufgabe5.md

200 lines
5.0 KiB
Markdown

# 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
- <access> ist der Zugriff: ReadWrite, Read, Write
- <condition> 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? <br>
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?