Ich habe mir für OpenOCD einen "Olimex ARM-USB-OCD-H" JTAG-Adapter
zugelegt und brauche für die ersten Schritte etwas Hilfe.
Die für Windows compilierte Version 0.10.0 von OpenOCD habe ich mir hier
besorgt: http://www.freddiechopin.info/en/download/category/4-openocd
Als Treiber nutze ich den ZADIG Universal USB. Ging unter Windows 10
problemlos (was bei Windows 10 ja schon echt was bedeutet ;-))
Liegt eine Datei namens "openocd.cfg" im gleichen Ordner in dem man die
EXE startet, wird diese standardmäßig eingelesen und abgearbeitet. Die
Syntax ist "abgespecktes" TCL. Hier habe ich zunächst das
Interface-Script für den Olimex-Adapter geladen: 1 | source [find ../scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg]
|
Als nächstes geht es an das zu untersuchende Ziel. In meinem Fall soll
es ein OMAP5948 sein (vom Aufbau her wohl ähnlich wie ein OMAP5912). Das
ist ja ein SOC, also nicht bloß eine CPU. Daher stellt sich mir hier
schon die Frage ob ich dafür nun ein "board-script" oder ein
"target-script" erstellen sollte?
Das Board an das ich mich per JTAG verbinde hat an dem JTAG-Port nur
diesen OMAP, sonst nichts. Aus meiner sicht ist das eher ein Target.
Unterm Strich sollte es für die Funktion egal sein, geht mir mehr darum
das Prinzip zu verinnerlichen. Jedenfalls habe ich für den OMAP ein
Script erstellt und in die openocd.cfg eingefügt:
1 | source [find ../scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg]
| 2 | source [find ../scripts/target/omap5948.cfg]
|
Das "omap5948.cfg" script enthält bislang lediglich "newtap" Befehle für
die einzelnen Komponenten des Ziels, sowie den Targetnamen:
1 | jtag newtap omap5948 dsp -irlen 34 -expected-id 0x031f3d81
| 2 | jtag newtap omap5948 arm -irlen 4 -expected-id 0x0692602F
| 3 | # Hier bin ich mir unsicher:
| 4 | #jtag newtap omap5948 ice -irlen 12 -expected-id 0x00000001
| 5 | jtag newtap omap5948 ice -irlen 12 -expected-id 0x2008f02f
| 6 |
| 7 | set _TARGETNAME omap5948.arm
| 8 | target create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME
|
Ob das alles so stimmt weiss ich nicht... das habe ich mir aufgrund
anderer Beispielskripte zusammengereimt. "Arbeiten" will ich ja
eigentlich nur mit der CPU, sprich diese anhalten, Watchdogs stoppen und
auf Register bzw. das externe RAM/Flash zugreifen. Daher dachte ich ist
es ausreichend nur die CPU als Target zu erstellen.
Nun muss ich wohl auch noch irgendwie sagen mit welcher Taktfrequenz
über JTAG kommuniziert werden kann und wie OpenOCD die Statemachine des
TAP resettet. Bei dem Teil komm ich grad nicht mehr klar... wo und wie
mache ich das? Woher weiss ich wie schnell es der TAP mag?
Welche Fehlermeldung spuckt denn OpenOCD aus? OpenOCD ist zu Anfang mit
einigem Trail&Error verbunden.
Hint: "-d3" Parameter beim Start übergeben. Dann erschlägt es einen zwar
mit Log Meldungen, aber man findet so Fehler schneller. Per Default
teilt OpenOCD nicht wirklich mit was schief ging.
Hier mal mein aktuelles openocd.cfg Skript. Ich habe zunächst die
Targetspezifischen Befehle einfach mit dort reingepackt. Wenn das mal
alles läuft würde ich das dann in ein Target-Scriptfile überführen.
Ich kommentiere mal über der jeweiligen Codezeile was ich denke was es
tun soll. Einige Daten die ich verwende habe ich "geklaut" bzw. geraten.
Sicher gibt es bei OpenOCD, ähnlich wie beim J-Link von Segger, auch
eine Möglichkeit des Autodetect. Die habe ich aber noch nicht
gefunden...
openocd.cfg: 1 | # Adapter Skript für den Olimex laden
| 2 | source [find scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg]
| 3 |
| 4 | # Ob es das braucht weiss ich nicht, hab ich so aus anderen Skripten übernommen
| 5 | adapter_nsrst_delay 100
| 6 |
| 7 | # Laut TAP-Detect vom Segger (siehe unten) so hoffentlich richtig übernommen. Hier wird jeweils ein TAP definiert, mit Namen ("omap5948"), Typ ("arm"), länge des IR-Registers in der Scanchain und erwartetem ID-Code bei Abfrage. Die Reihenfolge muss der Reihenfolge der TAPs in der Scanchain entsprechen
| 8 | jtag newtap omap5948 dsp -irlen 34 -expected-id 0x031f3d81
| 9 | jtag newtap omap5948 arm -irlen 4 -expected-id 0x0692602F
| 10 | jtag newtap omap5948 ice -irlen 12 -expected-id 0x2008f02f
| 11 |
| 12 | # Nun definiere ich eine Variable namens _TARGETNAME die bestimmt womit der OpenOCD arbeiten soll, wenn mehrere TAPs vorhanden sind. Ich entscheide mich für die ARM9-CPU
| 13 | set _TARGETNAME omap5948.arm
| 14 |
| 15 | # Das Target wird erstellt und ist vom Typ "arm926ejs". Little-Endian muss man wohl nicht angeben, mache ich nur sicherheitshalber. Die Position in der Chain wird ebenfalls angegeben
| 16 | target create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME
| 17 | # Theoretisch müsste man das auch so schreiben können, ohne Variable:
| 18 | # target create omap5948.arm arm926ejs -endian little -chain-position omap5948.arm
| 19 |
| 20 | # Hier wähle ich explizit das JTAG-Protokoll für die Schnittstelle des Adapters, denn er kennt auch SWD
| 21 | transport select jtag
| 22 |
| 23 | # Ich weiss das das RTCK-Signal vom OMAP unterstützt wird, daher habe ich es angegeben. Die "4" (steht für 4 MHz Takt) wird wohl nur verwendet, wenn RTCK doch nicht funktioniert und ein statischer Takt benötigt wird
| 24 | jtag_rclk 4
| 25 |
| 26 | # Das muss ich wohl so machen, keine Ahnung warum
| 27 | init
| 28 | reset_config trst_only
| 29 | reset
|
So, dabei kommt zunächst mal dieses Ergebnis beim Aufruf von openocd.exe
ohne weitere Parameter: 1 | C:\Program Files (x86)\openocd>openocd
| 2 | Open On-Chip Debugger 0.10.0-rc2
| 3 | Licensed under GNU GPL v2
| 4 | For bug reports, read
| 5 | http://openocd.org/doc/doxygen/bugs.html
| 6 | adapter_nsrst_delay: 100
| 7 | Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
| 8 | Warn : omap5948.dsp: huge IR length 34
| 9 | Warn : Transport "jtag" was already selected
| 10 | RCLK - adaptive
| 11 | Info : RCLK (adaptive clock speed)
| 12 | Info : JTAG tap: omap5948.dsp tap/device found: 0x031f3d81 (mfg: 0x6c0 (<unknown>), part: 0x31f3, ver: 0x0)
| 13 | Info : JTAG tap: omap5948.arm tap/device found: 0x0692602f (mfg: 0x017 (Texas Instruments), part: 0x6926, ver: 0x0)
| 14 | Info : TAP omap5948.ice does not have IDCODE
| 15 | Info : Embedded ICE version 0
| 16 | Error: unknown EmbeddedICE version (comms ctrl: 0x018e9ec0)
| 17 | Info : omap5948.arm: hardware has 2 breakpoint/watchpoint units
| 18 | trst_only separate trst_push_pull
| 19 | Info : JTAG tap: omap5948.dsp tap/device found: 0x031f3d81 (mfg: 0x6c0 (<unknown>), part: 0x31f3, ver: 0x0)
| 20 | Info : JTAG tap: omap5948.arm tap/device found: 0x0692602f (mfg: 0x017 (Texas Instruments), part: 0x6926, ver: 0x0)
| 21 | Info : JTAG tap: omap5948.ice tap/device found: 0x2008f02f (mfg: 0x017 (Texas Instruments), part: 0x008f, ver: 0x2)
| 22 | Error: omap5948.arm: how to reset?
| 23 | in procedure 'reset' called at file "openocd.cfg", line 17
| 24 | in procedure 'ocd_bouncer'
|
Das ausführliche Log (-d3) habe ich angehangen, damit es nicht zu lang
wird im Text.
Sieht ja anfänglich nicht sooo schlecht aus, oder? Warum er die 34 Bit
IR-Länge vom DSP anmostert ist mir etwas unklar, scheint aber nur ein
Hinweis zu sein.
JTAG und Adaptive Taktung hat er wohl soweit erkannt. Dann findet er
auch den DSP (C55x) und die CPU (ARM9).
Beim ICE (Debug-Controller?!) tut er sich etwas schwer, keine Ahnung
warum. Für mich sieht es so aus als würde er von diesem TAP keinen
IDCODE erhalten, so wie er es für den DSP und die CPU konnte. Woran
könnte das liegen? Stimmt evtl. die IR-Len nicht? Oder muss der ICE
durch irgendein Hardware-Wunder (Pin) erst aktiviert werden?
Warum er dann etwas später den ICE scheinbar doch noch erkennt ist mir
ein Rätsel! Womöglich erfolgt diese Ausgabe auch nur aufgrund meiner
Vorgabe beim definieren des TAP-Device?
"trst_only separate trst_push_pull" bedeutet doch wohl, das ich durch
das Kommando "reset_config trst_only" dafür sorge, das der
TAP-Controller-RESET rein über das Pin-Signal /TRST erfolgt und nicht
über "Software" (die berühmte 5 '1'en Folge), richtig?
Und "push_pull" das er sowohl das HIGH als auch das LOW-Signal aktiv
treibt. Manche TAPs benötigen einen externen Pullup auf dem Pin. Beim
OMAP glaube ich, ist der intern. Kann aber wohl auch nicht schaden?
So und dann kommt das große Problem "Error: omap5948.arm: how to
reset?". Tja, wie soll er das denn machen? Und warum überhaupt? Er soll
die CPU doch garnicht resetten, höchstens initialisieren und später dann
auch mal anhalten oder sowas.
Hmm... wer weiß Rat?
+ + + Nachtrag + + +
Ich habe mir mal das beim openocd beiligende Skript "omap5912.cfg"
angeschaut. Dort werden die TAPs wie folgt definiert:
1 | # NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for
| 2 | # its standalone siblings (like TMS320VC5502) of the same era
| 3 |
| 4 | jtag newtap $_CHIPNAME dsp -irlen 38 -expected-id 0x03df1d81
| 5 | jtag newtap $_CHIPNAME arm -irlen 4 -expected-id $_CPUTAPID
| 6 | jtag newtap $_CHIPNAME unknown -irlen 8
|
Der OMAP5948 soll nahezu identisch mit dem OMAP5912 sein, also habe ich
einfach mal diese IR-Len Werte übernommen und siehe da, plötzlich findet
er auch den ICE:
1 | C:\Program Files (x86)\openocd>openocd
| 2 | Open On-Chip Debugger 0.10.0-rc2
| 3 | Licensed under GNU GPL v2
| 4 | For bug reports, read
| 5 | http://openocd.org/doc/doxygen/bugs.html
| 6 | adapter_nsrst_delay: 100
| 7 | Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
| 8 | Warn : omap5948.dsp: huge IR length 38
| 9 | Warn : Transport "jtag" was already selected
| 10 | RCLK - adaptive
| 11 | Info : RCLK (adaptive clock speed)
| 12 | Info : JTAG tap: omap5948.dsp tap/device found: 0x031f3d81 (mfg: 0x6c0 (<unknown>), part: 0x31f3, ver: 0x0)
| 13 | Info : JTAG tap: omap5948.arm tap/device found: 0x0692602f (mfg: 0x017 (Texas Instruments), part: 0x6926, ver: 0x0)
| 14 | Info : JTAG tap: omap5948.ice tap/device found: 0x2008f02f (mfg: 0x017 (Texas Instruments), part: 0x008f, ver: 0x2)
| 15 | Info : Embedded ICE version 6
| 16 | Info : omap5948.arm: hardware has 2 breakpoint/watchpoint units
| 17 | trst_only separate trst_push_pull
| 18 | Info : JTAG tap: omap5948.dsp tap/device found: 0x031f3d81 (mfg: 0x6c0 (<unknown>), part: 0x31f3, ver: 0x0)
| 19 | Info : JTAG tap: omap5948.arm tap/device found: 0x0692602f (mfg: 0x017 (Texas Instruments), part: 0x6926, ver: 0x0)
| 20 | Info : JTAG tap: omap5948.ice tap/device found: 0x2008f02f (mfg: 0x017 (Texas Instruments), part: 0x008f, ver: 0x2)
| 21 | Error: omap5948.arm: how to reset?
| 22 | in procedure 'reset' called at file "openocd.cfg", line 22
| 23 | in procedure 'ocd_bouncer'
|
Was mich wundert ist, das der Segger J-Link über seine
Autodetect-Funktion folgendes erkannt hat: 1 | TotalIRLen = 50, IRPrint = 0x001444031F3D81
| 2 | JTAG chain detection found 3 devices:
| 3 | #0 Id: 0x031F3D81, IRLen: 34, Unknown device
| 4 | #1 Id: 0x0692602F, IRLen: 04, ARM9TDMI Core
| 5 | #2 Id: 0x00000001, IRLen: 12, Unknown device
|
Dann liegt der Segger hier wohl einfach falsch, nicht wahr? Und ich habe
diesen Fehler einfach übernommen ("geklaut") und jetzt stimmt es wohl.
+ + + NACHTRAG 2 + + +
Wenn ich es richtig verstanden hab, funktioniert das Autoprobing so, das
man eben nur ein Interface-Script aber kein Target/Board-Script angibt.
Dann versucht OpenOCD die TAPs selbst zu identifizieren. Das habe ich
mit folgendem Inhalt des openocd.cfg ausprobiert: 1 | # load the interface script for the Olimex ARM-USB-OCD-H probe, connected to USB
| 2 | source [find scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg]
| 3 |
| 4 | reset_config trst_and_srst
| 5 | jtag_rclk 8
|
Heraus kam dies hier: 1 | C:\Program Files (x86)\openocd>openocd -f openocd_autoprobe.cfg
| 2 | Open On-Chip Debugger 0.10.0-rc2
| 3 | Licensed under GNU GPL v2
| 4 | For bug reports, read
| 5 | http://openocd.org/doc/doxygen/bugs.html
| 6 | trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain connect_deassert_srst
| 7 | Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
| 8 | RCLK - adaptive
| 9 | Info : RCLK (adaptive clock speed)
| 10 | Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!
| 11 | Info : JTAG tap: auto0.tap tap/device found: 0x031f3d81 (mfg: 0x6c0 (<unknown>), part: 0x31f3, ver: 0x0)
| 12 | Info : JTAG tap: auto1.tap tap/device found: 0x0692602f (mfg: 0x017 (Texas Instruments), part: 0x6926, ver: 0x0)
| 13 | Info : JTAG tap: auto2.tap tap/device found: 0x2008f02f (mfg: 0x017 (Texas Instruments), part: 0x008f, ver: 0x2)
| 14 | Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 7 -expected-id 0x031f3d81"
| 15 | Warn : AUTO auto1.tap - use "jtag newtap auto1 tap -irlen 2 -expected-id 0x0692602f"
| 16 | Error: auto1.tap: IR capture error; saw 0x0003 not 0x0001
| 17 | Warn : Bypassing JTAG setup events due to errors
| 18 | Warn : gdb services need one or more targets defined
|
Die gefundenen TAPs entsprechen denen die ich einen Post zuvor auch
ermittelt hab. Lediglich die IR-Lens kann er nicht richtig bestimmen,
wodurch auch der nachfolgende Error produziert wird.
Aber anscheinend liege ich mit den ID-Codes und IR-Lens oben doch schon
ziehmlich richtig.
Als nächstes müsste ich dann einen Weg finden dieses INIT und RESET
richtig hin zu bekommen...
Mach mal aus dem "reset" ein "reset init".
Außerdem:
Hast Du das TRST Signal verbunden? Ansonsten nehme ich gerne zum Testen:
.. allerdings auf Cortex-M. RCLK würde ich auch erstmal weglassen und so
100kHz Frequenz zwecks Test einstellen. Kann man später hochdrehen.
Jim M. schrieb:
> RCLK würde ich auch erstmal weglassen und so
> 100kHz Frequenz zwecks Test einstellen. Kann man später hochdrehen.
Also anstelle "jtag_rclk 8" dann "adapter_khz 100". Kann ich ja anfangs
so machen.
> Mach mal aus dem "reset" ein "reset init".
Ich glaube hier gibt es folgende Optionen: "reset", "reset halt", "reset
init". Diese beeinflussen das Verhalten und die Verwendung der Signale
SRST und TRST.
Das SRST-Signal soll doch, sofern verfügbar, das ganze Board resetten.
Somit könnte ich dann via OpenOCD für einen definierten Ausgangszustand
sorgen. Verstehe ich das so richtig?
Das JTAG-Resetsignal TRST setzt ja via Hardware (Pin) den Zustand des
JTAG-TAP zurück.
Wenn ich "reset init" richtig verstanden habe, dann würde OpenOCD
zunächst SRST auf low halten um die CPU oder das Board in einem
RESET-Zustand zu halten und dann kurz mit TRST den JTAG-TAP
initialisieren und nachfolgend alles tun um eine "saubere und schnelle"
Kommunikation mit z.B. einem Debugger vorzubereiten. Nachdem er dann
SRST wieder hochnimmt könnte man quasi vor dem ersten Reset-Vector
bereits debuggen.
So gesehen hatte ich meinen "reset" und kein "reset init" oder "reset
halt" genommen. Probiere es aber gern mal aus. Auch würde ich schauen ob
ich SRST nutzen kann, wär schon eine sinnvolle Sache.
Das Timing und die Dauer der Reset-Signale ist wohl ebenfalls von
Bedeutung. Dies wird wohl über "adapter_nsrst_*" und "jtag_ntrst_*"
Befehle gesteuert.
> 1 | > reset_config trst_only
| 2 | >
|
> Hast Du das TRST Signal verbunden?
Ja, wie ich schrieb ist das Signal am OMAP-TAP vorhanden und verbunden.
> Ansonsten nehme ich gerne zum Testen:
>
Probiere ich mal. Das bedeutet dann ja, das weder SRST noch TRST per
Hardware genutzt werden, richtig?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|