Forum: Compiler & IDEs Seltsames problem beim Debuggen


von Christian L. (chl)


Lesenswert?

Hallo,

ich hoffe Ihr könnt mir weiterhelfen, da ich ein recht mehrkwürdiges 
Problem beim Debuggen habe.

Ich bin erst kürzlich in die Mikrocontroller-Programmierung eingestiegen 
und habe ein Evalations-Board mit einem AT91SAM7X256 und einen JTAG 
J-Link für ARM. Als IDE verwende ich Eclipse unter Windows XP mit 
ZylinCDT und dem yagarto Toolchain, sowie den J-Link GDB-Server

Ich habe alles nach folgender Anleitung eingerichtet:
http://www.yagarto.de/howto/yagarto2/index.html


Ich habe ein einfaches Projekt geschrieben, mit einer Ausgabe über 
Seriell und einem blinkenden LED.

Das kuriose ist, dass ich es schon auf dem Board via JTAG debuggen 
konnte aber neuerdings geht es nicht mehr. Dabei bin ich mir nicht 
bewußt etwas verstellt zu haben. Auch ein Löschen von Eclipse und eine 
erneute Einrichtung schaffte keine Abhilfe.

Wenn ich das Projekt das erste mal aus Eclipse heraus debugge kommt 
folgende Meldung:
1
source D:\EclipseWorkspace\SAM7X256Test\prj\sam7x256_ram_jlink.gdb
2
0x00000000 in ?? ()
3
4
5
Breakpoint 1, main () at src/main.c:234
6
234      PIO_Configure(pPins, PIO_LISTSIZE(pPins));
7
info proc
8
Current language:  auto
9
The current source language is "auto; currently c".
10
Undefined info command: "proc".  Try "help info".
11
info program
12
Debugging a target over a serial line.
13
Program stopped at 0x200828.
14
It stopped at breakpoint 1.
15
Type "info stack" or "info registers" for more information.

Wäre über jede Hilfe dankbar.

von 900ss (900ss)


Lesenswert?

Soweit ich das bewerten kann ist deine Debug-Configuration in Eclipse 
verbogen.
Hast du unter GDB- commandline eine Datei angegeben die ein Kommando 
'info proc' enthält? Oder unter dem Tab. Commands solch ein Kommando 
eingegeben?
Da grabe mal.

von Christian L. (chl)


Lesenswert?

Unter Command File habe ich wie im HowTo beschriben die Datei
sam7x256_ram_jlink.gdb angegeben.

Inhalt ist:
1
#
2
# This config file was tested with J-Link GDB Server v4.04
3
#
4
5
# Listening for commands on this PC's tcp port 2331
6
target remote localhost:2331
7
8
# Set gdb server to little endian
9
monitor endian little
10
11
# Set JTAG speed to 30 kHz
12
monitor speed 30
13
14
# Reset the chip to get to a known state.
15
monitor reset 8
16
monitor sleep 10
17
18
#
19
# Disable the watchdog and setup the PLL
20
#
21
22
# WDT_MR, disable watchdog 
23
monitor writeu32 0xFFFFFD44 = 0x00008000
24
25
# CKGR_MOR
26
monitor writeu32 0xFFFFFC20 = 0x00000601
27
monitor sleep 10
28
29
# CKGR_PLLR
30
monitor writeu32 0xFFFFFC2C = 0x00480a0e
31
monitor sleep 10
32
33
# PMC_MCKR
34
monitor writeu32 0xFFFFFC30 = 0x00000007
35
monitor sleep 10
36
37
# PMC_IER
38
monitor writeu32 0xFFFFFF60 = 0x00480100
39
monitor sleep 100
40
41
# Set JTAG speed in khz
42
monitor speed 12000
43
44
load
45
break main
46
continue

Wenn ich im Debugger einzeln durchsteppe. Bekomme ich bei der 
Konfiguration der Debugschnittstelle die meldung, dass er eine 
lib1funcs.asm nicht finden könne.

von 900ss (Gast)


Lesenswert?

Du mußt das Ganze etwas präziser beschreiben.
Wann machst du genau was und was sind die Ausgaben Konsolenfenster in 
Eclipse dazu.
Wenn er Datei Namens lib1funcs.asm nicht findet ist die Lage doch 
eindeutig. Er versucht nach einem Step oder Breakpoint den Source dieser 
Stelle anzuzeigen. Dazu benötigt er die Datei, die er aber nicht findet. 
Warum steht auf einem anderen Blatt.

von Christian L. (chl)


Lesenswert?

Das sagt der GDB.
1
Breakpoint 1, main () at src/main.c:76
2
76              DBGU_Configure(DBGU_STANDARD, 115200, MCK);
3
Current language:  auto
4
The current source language is "auto; currently c".

Ich habe mir jetzt mal ein ganz simples Programm gebastelt, was einfach 
nur eine Ausgabe auf der Debug-Schnittstelle machen soll.
1
#include "typedefs.h"
2
#include "dbgu.h"
3
#include "board.h"
4
#include <stdio.h>
5
6
7
int main (void)
8
{
9
  DBGU_Configure(DBGU_STANDARD, 115200, MCK);
10
  printf("test");
11
12
  return(0);
13
}

Es kommt nur obige meldung vom GDB und nix auf der Debugschnitstelle 
raus.

von Christian L. (chl)


Lesenswert?

Also diese Meldung kommt beim DBGU_Configure
1
Can't find a source file at "../../../gcc-4.4.2/libgcc/../gcc/config/arm/lib1funcs.asm" 
2
Locate the file or edit the source lookup path to include its location.

Diese Meldung kommt beim printf
1
Can't find a source file at "../../../../../newlib-1.18.0/newlib/libc/stdio/printf.c" 
2
Locate the file or edit the source lookup path to include its location.

Beide Dateien sind nicht auf meinem Rechner. Auch eine Neuinstallation 
des Yagarto-Toolchains brachte keine Abhilfe.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die Frage ist ja, ob du die Applikation oder deine Systembibliotheken
debuggen willst.

von Christian L. (chl)


Lesenswert?

Die Applikation natürlich.

von Karl H. (kbuchegg)


Lesenswert?

Christian L. schrieb:
> Die Applikation natürlich.

Was interessiert dich dann, ob der Debugger den Source Code für printf 
findet oder nicht?

von Christian L. (chl)


Lesenswert?

Mich interessiert, dass auf der Debug-Schnittstelle das printf 
rauskommt. Tut es aber nicht. Ich versuche gerade den grund dafür zu 
finden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dann willst du aber doch die Bibliothek debuggen.  Damit wiederum
musst du aber (damit das Sinn hat) auch den Sourcecode der
Bibliothek in Reichweite haben.  Was erwartest du, wie der Debugger
dich durch die einzelnen Stufen von printf() hindurch geleiten
könnte (bis zur Ausgabe des Zeichens "ganz unten"), wenn er den
entsprechenden Sourcecode nicht finden kann?

Nein, der Sourcecode ist kein Bestandteil der Debug-Informationen
in der Objektdatei.  Dort stehen lediglich Zeiger (Dateiname und
Zeilennummer) auf die Quelle.

von Christian L. (chl)


Lesenswert?

Also ich bin noch nicht so lange dabei und Einsteiger in der Materie.
Was müsste ich denn tun, um das Projekt aus Eclipse raus auf dem AT91 zu 
testen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, wenn dein printf() nicht geht, hast du zwei Varianten:

. Du installierst in der Tat den Sourcecode für die Bibliothek und
  hangelst dich mit dem Debugger durch.  Der Sourcecode muss natürlich
  zum Objektcode passen, am sinnvollsten, indem man die Bibliothek
  gleich selbst compiliert.

. Du liest die Dokumentation und versuchst herauszufinden, was du
  falsch gemacht hast. ;-)  Irgendwo muss ja dokumentiert sein, wie
  das backend für stdio beschaffen sein muss, damit die Ausgaben
  auch am gewünschten Gerät ankommen.

von Karl H. (kbuchegg)


Lesenswert?

Jörg Wunsch schrieb:

> . Du liest die Dokumentation und versuchst herauszufinden, was du
>   falsch gemacht hast. ;-)  Irgendwo muss ja dokumentiert sein, wie
>   das backend für stdio beschaffen sein muss, damit die Ausgaben
>   auch am gewünschten Gerät ankommen.

Wahrscheinlich würde es auch vernünftig, erst mal herauszufinden, wie 
dieser printf Unterbau beschaffen sein muss und diesen erst mal in den 
vorhandenen Sourcen zu identifizeren und sich anzusehen, was da 
eigentlich abgeht.
1
#include "typedefs.h"
2
#include "dbgu.h"
3
#include "board.h"
4
#include <stdio.h>
5
6
7
int main (void)
8
{
9
  DBGU_Configure(DBGU_STANDARD, 115200, MCK);
10
  printf("test");
11
12
  return(0);
13
}

ich tippe mal auf "board.h"
Eventuell wäre es auch schlau, zuerst die System Header zu inkludieren 
und erst dann die spezifischen. So nach dem Muster: gib den spezifischen 
Teilen die Chance, die allgemein gültigen aus den Systemheadern zu 
überschreiben. (Das kann, muss aber nicht Abhilfe sein)
1
#include <stdio.h>
2
#include "typedefs.h"
3
#include "dbgu.h"
4
#include "board.h"
5
6
...

von Christian L. (chl)


Lesenswert?

Das taschen der Includes hat leider keine Abhilfe geschafft.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Was hast du denn als Backend für das printf implementiert?

von 900ss (900ss)


Lesenswert?

Unter YAGARTO wird die newlib verwendet. Die erfordert auch eine 
syscalls.c für die low-level Funktionen. printf() nutzt diese dann z.B. 
um eine Ausgabe zu machen.
In deinem YAGARTO-Verzeichnis in der Datei yagarto_newlib.txt solltest 
du einen Hinweis darauf finden. Dort wird dann auf die syscalls.c 
verwiesen mittels diesem Link:
http://www.yagarto.de/download/yagarto/syscalls.c

Dort gibt es z.B. einen Routine write_r(...) die eine Ausgabe auf den 
uart schicken sollte (ist dort mit '#if 0' ausgeklammert.

Diese Datei (syscalls.c) müßtest du eigentlich irgendwie dazulinken, 
weil sonst dein Linker über fehlende Symbole meckert. Und die Datei 
müßtest du so ändern dass die Stubs in dieser Datei eine sinnvolle 
Funktion ergeben.
Auf der YAGARTO-Seite ist sehr schön beschrieben, was man alles machen 
muß.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Falls es sich um ein Beispiel aus der AT91-Library handelt: Atmel nutzt, 
zumindest in der evtl. nicht ganz aktuellen Version, die ich mir zuletzt 
angeschaut habe, eigene Implementierungen von printf. Der Quellcode dazu 
findet sich in den Beispielenprojeketen (utils/stdio.c o.ä.). Diese 
nutzt putc, dass ebenfalls in projektspezifischem Code implementiert 
ist, und das leitet die Zeichen an den DBGU-"UART". Langer Rede: wurden 
die Atmel-Beispiel-Makefiles unverändert genutzt oder selbst etwas 
zusammengebastelt? Es sieht so aus, als würden newlib-stdio und AT91LIB 
stdio irgendwie gemixt, wenn ja, kann das die Ursache für die Probleme 
sein. Die Linker-Optionen und -Reihenfolge müssen sorgfältig gesetzt 
werden.

von Christian L. (chl)


Lesenswert?

@Martin Thomas

Das Mischen ist in der Tat wohl das Problem, wie ich festgestellt habe.
Das erste Beispielprogramm was ich hatte war das von der Yagarto-Seite. 
Darauf aufbauend wollte ich nun ein Atmel-Beispiel implementieren.

Im util-Ordner von Atmel gibt es allerdings keine stdio.c. Allerdings 
eine trace.c in der folgendes vermerkt ist.
1
//------------------------------------------------------------------------------
2
/// \exclude
3
/// Implementation of fputc using the DBGU as the standard output. Required
4
/// for printf().
5
/// \param c  Character to write.
6
/// \param pStream  Output stream.
7
/// \param The character written if successful, or -1 if the output stream is
8
/// not stdout or stderr.
9
//------------------------------------------------------------------------------

Ich habe jetzt statt DBGU_CONFIGURE TRACE_CONFIGURE aus der trace.h 
verwendet und kann nun zumindest mit DBGU_PutChar was auf der 
Debug-Schnittstelle ausgeben.
Printf will aber immer noch nicht.

Vielleicht bin ich blind aber ich finde keine Infos zu der syscalls.c 
auf der yagarto-Seite. Die Datei selbst habe ich aber schon im Projekt.

von 900ss (Gast)


Lesenswert?

Christian L. schrieb:
> Vielleicht bin ich blind aber ich finde keine Infos zu der syscalls.c
> auf der yagarto-Seite.

Hmmm.... ich find das auch grad nicht wieder. :-/
Sonst lies dir auch die Datei "yagarto_newlib.txt" in deiner 
YAGARTO-Installation.

von Christian L. (chl)


Lesenswert?

Ich formuliere die Frage mal um. Wie bekomme ich printf zum Debuggen 
über die Debugschnittstelle ans laufen? Ich habe nun mal im Detail 
geguckt und die Atmel-Beispiele sind ja alle für IAR und dort sind die 
Bibliotheken doch recht anders als die von yagarto.

von 900ss (900ss)


Lesenswert?

Falls es Beispiele von YAGARTO gibt, versuche die. Ansonsten hat Martin 
Thomas auf seiner Webseite sehr viele funktionierende Beispiele auch für 
ARM. Den Link hab ich gerade nicht.

von 900ss (Gast)


Lesenswert?

So den Link hab ich auch:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html

Das sind jede Menge Beispiele. Weches davon jetzt gerade die syscalls.c
mit nutzt, das muß er selber hier mal mitteilen. Das brauchst du für die 
printf() Funktion. Jedenfalls weiß ich keinen anderen weg.
Ich hoffe er liest noch mit :-)

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Soweit erinnert, ist das "gamma"-Beispiel mit syscalls und newlib-stdios 
(i)printf. Grade nicht sicher, ob write an die DGBU oder einen 
"normalen" UART gebunden ist. Wenn nicht ersichtlich, nochmal fragen, 
ich schaue dann in den Code.
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html#at91_gamma

Die Atmel AT91LIB-Methode printf komplett selbst zu implementieren 
findet man in deren Quellcode. Zumindest in der Version der des 
AT91-Software-Packages für AT91SAM7S-EK und AT91SAM7X-EK, in die ich 
zuletzt reingeschaut habe, werden sehr wohl GNU-Tools unterstützt (nicht 
nur IAR EWARM). (Nochmal) Wenn richtig erinnert, habe ich den 
betreffenden Atmel-Code auch in meinem AT91-SD-Card-Bespiel verwendet. 
Habe auch da jetzt nicht reingeschaut, kann ich aber bei Bedarf machen.
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html#chanfat_at91sam7

von Christian L. (chl)


Lesenswert?

Danke ich schaue mal rein.

von Christian L. (chl)


Lesenswert?

Ich habe mal versucht mit Hilde Deines Gamma-Beispieles ein 
minimalistisches Programm zu schreiben, welches nur etwas auf der 
Debug-Schnittstelle ausgibt.
1
#include <stdint.h>
2
#include <stdio.h>
3
4
#include "board.h"
5
#include "dbgu.h"
6
7
8
int main(void) {
9
  // Set-up DBGU Usart ("UART2")
10
11
  AT91F_DBGU_Init();
12
  iprintf("1234567890");
13
  AT91F_DBGU_Printk("\r\n\r\ntest\r\n");
14
}

mit iprintf kommt auf der Schnittstelle gar nichts an und mit 
AT91_DBGU_Printk nur Müll.

dbgu.c und h sowie die syscalls.c sind aus dem Gamma-Projekt.

Es gab einen Error bezüglich isatty. Dieser war nach folgender Änderung 
der syscalls.c verschwunden.
1
int _isatty(int file); /* avoid warning */
2
3
int _isatty(int file)
4
{
5
  return 1;
6
}
Wobei ich nicht weiß, ob man da ohne weiteres einen Unterstrich 
vorschreiben kann.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Wobei ich nicht weiß, ob man da ohne weiteres einen Unterstrich
> vorschreiben kann.

Kann man, aber man sollte wissen, warum man ihn davor schreibt :)

Bei _funktionen ist die Übereinkunft, dass die zum System 
(Systemlibrary) gehören also dass es keine übliche Anwenderfunktion ist. 
Das Einhalten der Übereinkunft erleichtert den Eingeweihten die 
Codelesbarkeit und das Codeverständnis.

wenn im System allerdings die Funktion fehlt, andere Teile des Systems 
sie aber referenzieren, dann kann der Anwender als Bugfix oder 
Workaround die Funktion nachträglich implementieren. Das scheint hier zu 
passieren.

Eine ähnliche Übereinkunft gibt es bei Makros mit  oder _. Makros mit 
diesen Namen "gehören" dem Compiler.

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.