200 lines
5.0 KiB
Markdown
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?
|
|
|