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
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
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
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.
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
Mühsam nährt sich das Eichhörnchen: gdb_breakpoints_override hard
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.
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
Mir ist nichts bekannt, auch zickt der Controller bei mir gerne mal herum. Ich mache den Controller dann stromlos und starte alles neu.
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
"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.
:) 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.
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!
Im Thum Mode werden nur 16bit verwendet, damit wird der Code meistens kleiner. Willst du wirklich Floats verwenden? Mir haben Integer bisher immer gereicht.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.