Forum: Compiler & IDEs JTAG-Debugging mit AduC7020 im ROM


von Patric v. Loewis (Gast)


Lesenswert?

Hi,
ich quäle mich jetzt seit einigen Tagen mit dem Aduc7020 und openocd 
herum.
Was sehr gut funktioniert:

-Serielle Ein-/Ausgabe Interruptgesteuert & buffered
-Debuggen im RAM (meinen Dank an Tilo Lutz für das tolle Tutorial)
-Programmieren mit Yagarto

Seitdem ich die newlib eingefügt habe hakt es jedoch ein wenig. Mal 
geht's mal nicht. Leider ist das Programm durch die newlib zu groß zum 
debuggen im RAM geworden. Es fängt damit an, dass der Code nicht 
geflasht wird - was sich durch das flashen mit ARMWSD umgehen lässt - 
und scheitert letztlich daran, dass sich keine Breakpoints setzen 
lassen.

Meine openocd .cfg Datei:

set _CHIPNAME aduc702x
set _ENDIAN little
set _CPUTAPID 0x3f0f0f0f

jtag_nsrst_delay 200
jtag_ntrst_delay 200

# This is for the case that TRST/SRST is not wired on your JTAG adaptor.
# Don't really need them anyways.
reset_config none

## JTAG scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf 
-expected-id $_CPUTAPID

##
## Target configuration
##
set _TARGETNAME [format "%s.cpu" $_CHIPNAME]
target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position 
$_TARGETNAME

# allocate the entire SRAM as working area
$_TARGETNAME configure -work-area-phys 0x10000 -work-area-size 0x2000

## flash configuration
# only target number is needed
flash bank aduc702x 0x80000 0xf800 0 0

## If you use the watchdog, the following code makes sure that the board
## doesn't reboot when halted via JTAG.  Yes, on the older generation
## AdUC702x, timer3 continues running even when the CPU is halted.

#proc watchdog_service {} {
#    global watchdog_hdl
#    mww 0xffff036c 0
##    puts "watchdog!!"
#    set watchdog_hdl [after 500 watchdog_service]
#}

#$_TARGETNAME configure -event reset-halt-post {  watchdog_service }
#$_TARGETNAME configure -event old-pre_resume { global watchdog_hdl; 
after cancel $watchdog_hdl }
gdb_memory_map enable
gdb_flash_program enable

Eclipse GDB Initialisierung:
target remote localhost:3333
# halt core
monitor wait_halt
# set core state to arm
#monitor armv4_5 core_state arm
#monitor armv7_9 core_state arm
# allow flash write
monitor mwh 0xFFFFF804 0x08
# reset
monitor reset

Eclipse GDB 'Run':

#connect to openocd
target remote localhost:3333
# stop mcu
monitor soft_reset_halt
# disable irq
monitor mww 0xFFFF000C 0x00FFFFFF
# disable fiq
monitor mww 0xFFFF010C 0x00FFFFFF
# map SRam to 0x0
#monitor mww 0xFFFF0220 0x1
# map Rom to 0x0
#monitor mww 0xFFFF0220 0x0
# Set program pointer to 0x0
monitor reg pc 0x00000000
# Activate breakpoints
#monitor arm7_9 force_hw_bkpts enable
#monitor arm4_5 force_hw_bkpts enable
# load code
load
symbol-file main.elf
# set breakpoint to main-function
break main
#continue execution of code
continue

Lasse ich den Debugger laufen erhalte ich folgende Meldungen (um ein 
paar Zeilen gekürzt):

target remote localhost:3333
warning: while parsing target memory map (at line 5): Flash block size 
is not set
0x00000018 in ?? ()
monitor soft_reset_halt
requesting target halt and executing a soft reset
target state: halted
target halted in ARM state due to debug-request, current mode: 
Supervisor
cpsr: 0x600000d3 pc: 0x00000000
monitor mww 0xFFFF000C 0x00FFFFFF
monitor mww 0xFFFF010C 0x00FFFFFF
monitor mww 0xFFFF0220 0x1
monitor reg pc 0x00000000
pc (/32): 0x00000000
monitor arm7_9 force_hw_bkpts enable
invalid command name "arm7_9_force_hw_bkpts"
monitor armv4_5 force_hw_bkpts enable
invalid command name "arm4_5_force_hw_bkpts"
load
Loading section .text, size 0x1578 lma 0x80000
Load failed
symbol-file main.elf
break main
Breakpoint 7 at 0x81198: file main.c, line 21.
continue
memory write caused data abort (address: 0x00081198, size: 0x4, count: 
0x1)
memory write caused data abort (address: 0x00081250, size: 0x4, count: 
0x1)

Ich kann jetzt zwar den Code steppen, aber nur um jeweils einen 
Maschinenbefehl (da ist die Medizin schlimmer als die Krankheit).
Ein absolutes Mysterium ist für mich dir Warnung bzgl. der target memory 
map. Die armXX Kommandos sind gemäß einem Posting nicht (mehr) 
notwendig.

Also wenn mir da jemand weiterhelfen könnte wäre ich echt dankbar.

Ansonsten:
Wie geht das mit den Breakpoints eigentlich? Wird da ein spezieller 
Befehl an die entsprechende Stelle im Programm geschrieben? Wenn ja, 
dann wäre das wohl ziemlich mühselig: 512 Bytes kopieren, 4 Bytes 
ändern, 512 Bytes löschen und wieder schreiben.
Oder: es heisst überall man könne maximal zwei Hardware Breakpoints 
setzen. Gibt es da spezielle Register, die die CPU unterbrechen, wenn PC 
== Register?

Wie gesagt für Hinweise bin ich dankbar.

Gruß Patric

von Tilo (Gast)


Lesenswert?

Hallo

Das Flash lässt sich direkt über openocd beschreiben. Ich habe im Moment 
noch recht viel zu tun. Mitte der Woche sollte ich Zeit haben, 
nachzusehen, ob meine Skripte mit den neueren Versionen von Openocd 
arbeiten.
Deshalb passt bei dir einiges leider nicht so ganz.

> memory write caused data abort (address: 0x00081198, size: 0x4, count:
Das hier ist das Problem. Der Debugger arbeitet irgend wo herum und 
versucht die einzelnen Befehle abzuarbeiten. Das geht schief und der 
debugger bricht ab.


Hardware Breakpoints werden genauso wie Software Breakpoints gesetzt. 
Man muss nur aufpassen, nie mehr als 2 zu setzen.

Technisch läuft das so, dass die Programmadresse des Breakpoint in einen 
Comperator geladen wird. So bald der Programmcounter den selben Wert 
hat, wird das Programm angehalten.

Viele Grüsse, Tilo

von Patric v. Loewis (Gast)


Lesenswert?

Hallo Tilo,
danke für die Antwort. Ich werde dann mal die Woche abwarten. Es scheint 
mir so zu sein, dass bei sich bei openocd eine Menge geändert hat. Wäre 
es vielleicht sinnvoll eine ältere Version zu installieren? Wenn ja, wo 
bekomme ich die? Wenn ich bei openocd nach schaue, kann ich nur die 
0.1.0-Version bekommen und ich brauche die for_dummies win 
installation.

Es gibt demnach tatsächlich 2 separate Comparatorregister in der CPU?
Nun da werde ich mich in der nächsten Zeit mal etwas tiefer eingraben 
müssen.

Viele Grüße, Patric

von Tilo (Gast)


Lesenswert?

Hallo

Die Konfiguration hat sich geändert, Funktion und Anwendung nicht.
Das mit den Komperatoren ist nur die interne Realisierung. Wenn du per 
JTAG debuggst, interessiert sich so etwas normalerweise weniger. Fast 
alles lässt sich über die IDE direkt steuern.

von Patric v. Loewis (Gast)


Lesenswert?

Hallo,

hier mal der Zwischenstand meiner Experimente mit Telnet:
#Den Flash-Speicher zum schreiben freigeben (bereits bekannt)
mwh 0xfffff804 0x0008
#Den Flash-Speicher löschen, braucht bis zu 4s (Bank 0, Page 0-124 == 
alle Pages)
flash erase_sector 0 0 124
#Die Programmdatei laden (braucht bei mir bis zu 133s !!! Nicht so toll)
flash write_image main.elf elf
#Der Befehl "flash write_image erase main.elf elf" funktioniert bei mir 
#_nicht_
#Es gibt den Befehl arm7_9 dbgrq enable/disable dessen Relevanz mir 
#vollkommen unklar ist
#CPU anhalten, wenn nicht angehalten gibt's beim setzen von Breakpoints 
#mecker
halt
#Einen Breakpoint setzen
bp 0x81230 0x04 hw
#Noch einen Breakpoint setzen
bp 0x812b8 0x04 hw
#Noch einen Breakpoint setzen ist böse (wie erwartet)
#Programm laufen lassen
resume
#Das Programm wird beim ersten durchlaufenen BP gestoppt

Überraschenderweise "verbrauchen" sich einmal benutzte Breakpoints. Ein 
verbrauchter Breakpoint führt beim neuen Anlauf mittels "resume" zu zwei 
Fehlermeldungen der Art:
"BUG: no hardware comparator available"
Zwei verbrauchte Breakpoints führen zu drei der o.g. Meldungen.

Schlussendlich läuft es darauf hinaus, dass der Befehl "monitor arm7_9 
force_hw_bkpts" gestrichen wurde und man als Ersatz ein " hw" beim 
Setzen der Breakpoints anhängen muss.
Wie bringt man das Ganze jetzt GDB bei?

Gruß Patric

von Patric v. (vloewis)


Lesenswert?

Mühsam nährt sich das Eichhörnchen:
gdb_breakpoints_override hard

von Tilo (Gast)


Lesenswert?

So, hier sind meine Dateien. Ich habe es nicht geschafft, das Flash 
direkt über OpenOCD zu beschreiben. Ich mache es immer noch über GDB 
Kommandos. Ich verwende die Vorgegebene OpenOCD Konfiguratation und als 
"target" aduc702x.

initilaize commands:
# Set addresssize
set remoteaddresssize 32
#Increase Timeouts
set remotetimeout 999999
# connect to openocd
target remote localhost:3333
# stop mcu
monitor wait_halt
# set arm mode
monitor armv4_5 core_state arm
# mass erase flash
monitor mwh 0xFFFFF804 0x08
monitor mwb 0xFFFFF808 0x09
# wait 3sec until flash has been erased
monitor sleep 5000
# Speed up flash writing
set remote memory-write-packet-size 1024
set remote memory-write-packet-size fixed
set remote memory-read-packet-size 1024
set remote memory-read-packet-size fixed
# map Flash to 0x0
monitor mww 0xFFFF0220 0x0
# load code into flash
load
# reset mcu
monitor reset

Run Commands:
#connect to openocd
target remote localhost:3333
# stop mcu
monitor soft_reset_halt
# disable irq
monitor mww 0xFFFF000C 0x00FFFFFF
# disable frq
monitor mww 0xFFFF010C 0x00FFFFFF
# Set program pointer to 0x3c
monitor reg pc 0x00000000
#activate hardware breakpoints
monitor gdb_breakpoint_override hard
# Set hardware breakpoint at begin of main programm
thbreak main
#continue execution of code
continue




Ja, das mit den Hardware Breakpoints ist so eine Sache. Eclsipe weiß 
nicht, dass nur 2 gesetzt werden dürfen und verhindert nicht, dass mehr 
sktiviert werden können. Zum "steppen" werden beide Breakpoints 
benötigt. Ich mache das immer so, dass ich zwar mehrere Breakpoints 
habe, allerdings nur einen aktiviert habe.

von Patric v. (vloewis)


Lesenswert?

Danke, ich werde das mal ausprobieren.
Gibt es bei Eclipse irgendwo die Möglichkeit im laufenden Debugger ein
weiches Reset auszuführen? Der Restart-Button ist bei mir grau 
hinterlegt.

Gruß Patric

von Tilo (Gast)


Lesenswert?

Mir ist nichts bekannt, auch zickt der Controller bei mir gerne mal 
herum. Ich mache den Controller dann stromlos und starte alles neu.

von Patric v. (vloewis)


Lesenswert?

Es scheint jetzt zumindest bei mir zu funktionieren. Die 
Debuggingmöglichkeiten sind doch ... spartanisch, aber immer noch besser 
als nichts und dafür in situ! Im Vergleich zu meinem 8051-Simulator ist 
die Möglichkeit im System zu debuggen schon eine Menge wert.
Erstmal herzlichen Dank für Deine Hilfe.

Dann auch gleich die nächste Frage:
Ich verwende die newlib, die bei yagarto mitgeliefert wird. Die stubs 
habe ich implementiert. Sobald ich auch nur ein printf verwende, wird 
die Hälfe des Roms belegt, kommt ein scanf dazu ist es voll. Gibt es da 
Möglichkeiten die Codegröße etwas einzuschränken? Oder vielleicht eine 
andere lib?

Gruß Patric

von mthomas (Gast)


Lesenswert?

"Gleich die nächste Frage" besser in einem eigenen Thread unterbringen.

Falls keine FP-Ausgaben benötigt werden, kann man statt printf iprintf 
verwenden. Ähnliche integer-only Funktionen gibt es auf für "scan", vgl. 
stdio.h und newlib Dokumentation. Dennoch wird einiges an Flash-Speicher 
benötigt.

Alternative ist die Ausgabeformatierung ohne newlib mit 'eigenem' Code. 
Ein ganz nettes Beispiel dafür findet sich in den Software-Packages für 
AT91 bei atmel.com (stdio.c und dbgu.c, ist leicht portierbar, Lizenz 
liberal).

"Andere Lib" wäre z.B. die dietlibc, nie selbst ausprobiert, sollte sich 
aber nach Papierform ohne großen Aufwand für ARM-cross-toolchain bauen 
lassen, Lizenz beachten. Falls man etwas Geld ausgeben kann: mit 
Crossworks kommt eine von Rowley implementierte libc, soll in Sachen 
stdio deutlich kompakter sein als newlib aber auch nie selbst 
ausprobiert.

von Tilo (Gast)


Lesenswert?

:) Ja, die Probleme mit der Newlib kenne ich, da kann man nicht viel 
machen. Die "normale" Yagarto newlib wird vermutlich sowieso nicht 
sinnvoll nutzbar sein, da für den dynamischen Speicher 4kb Blöcke 
verwendet werden, siehe auch: 
Beitrag "Problem mit malloc() und -O2"

Nur: Wozu brauchst du die Newlib überhaupt? Ascii-Zeichen lassen sich 
wesentlihc kompakter mit eigenem Code per Uart versenden.

von Patric v. (vloewis)


Lesenswert?

ASCII schon, aber ich arbeite sehr viel mit floats und da ist eine 
komplett fertige Lösung natürlich praktischer und lässt mehr meiner 
(beschränkten) Hirnkapazität frei für die "eigentlichen" Probleme. Meine 
Probleme teilen sich in zwei Gebiete: 1. Mess-/Regelungstechnik 2. 
Endverbraucher/Kollegen. Wenn 1. läuft lässt sich 2. mit Änderungen an 
Format-Strings nervenschonender bewerkstelligen ;)

Was malloc angeht (Artikel noch nicht gelesen): ich habe (dank Debugger) 
mal _sbrk_r quasi unter die Röcke geschaut. Nur für printf 1. 
Anforderung 1048 Bytes 2. 776 Bytes. Bei scanf habe ich schon gar nicht 
mehr nachgeschaut...

Ich habe im makefile alles, bis auf die Interruptroutinen auf Thumb 
umgestellt und damit ein drittel Code eingespart, was mich überrascht 
hat. Mein Code war minimal. Liegt die newlib in zwei Varianten vor?

Als letztes: zum Debuggen schaltet man wohl besser alle Optimierungen 
aus, weil sonst Breakpoints am Anfang von Schleifen nur einmal (eben 
beim ersten mal) getroffen werden, Iteration aber -vermutlich ganz 
effizient- ein paar Instruktionen auslassen.

Jetzt werde ich erstmal wieder zurück in meine (heile) Keil/8051 Welt 
gehen um mir wieder Platz für ARM7 Experimente zu schaffen. Der ADuC7020 
muss und wird fallen!

von Tilo (Gast)


Lesenswert?

Im Thum Mode werden nur 16bit verwendet, damit wird der Code meistens 
kleiner.

Willst du wirklich Floats verwenden? Mir haben Integer bisher immer 
gereicht.

von Patric v. (vloewis)


Lesenswert?

Zum Thema floats: Ja ich will floats verwenden. In meinen 
Anwendungsfällen steht die Geschwindigkeit, mit der Lösungen verfügbar 
sind an erster Stelle. Die Geschwindigkeit der Applikation ist meist 
eher sekundär. Diverse Tricksereien mit Ints haben das Problem, dass man 
sehr viel Zeit aufwenden muss um die Allgemeingültigkeit der Lösung zu 
belegen. Floats laufen halt nicht so schnell über. Meine lieben Kollegen 
--freiwillige selbstzensur--

Zum Thema Thumb: Die newlib liegt ja bereits in kompilierter Form vor. 
Ich nehme mal an, dass die Version von Yagarto in ARM kompiliert ist. 
Daher wundert mich die doch rechts drastische Platzeinsparung bei der 
Kompilation meines Codes mit Thumb schon. Ich habe unter Win im 
Schnellschussverfahren versucht die newlib selbst neu zu kompilieren, es 
kam keine Freude auf. Letztlich wird es darauf hinauslaufen die mlib zu 
übernehmen, atof und Konsorten ebenfalls und printf und ähnliche ggf. 
selbst zu stricken. Die anderen libs, auf die Du hingewiesen hast sind 
ja z.T. sehr gut lesbar.

Gruß Patric

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Patric V. löwis schrieb:
>...
> Zum Thema Thumb: Die newlib liegt ja bereits in kompilierter Form vor.
> Ich nehme mal an, dass die Version von Yagarto in ARM kompiliert ist.
> Daher wundert mich die doch rechts drastische Platzeinsparung bei der
> Kompilation meines Codes mit Thumb schon.
>...

Bin nicht auf aktuellstem Stand betr. Yagarto configuration/build, aber 
üblicherweise gibt es je einen Library-Object-Code für die verschiedenen 
Konfigurationen, also z.B. auch ARM, thumb, thumb-iw. Nähere dazu unter 
dem Stichwort multilib in u.a. der gcc Dokumentation.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.