Forum: Compiler & IDEs Anleitung: Atmel Studio stdout auf Output umleiten


von Christian S. (christian_s593)


Angehängte Dateien:

Lesenswert?

Ich wollte kurz eine Möglichkeit präsentieren, wie man stdout und stderr 
auf das Debug-Fenster in Atmel Studio umleiten kann. Damit kann man 
prima im Simulator aber auch mithilfe einer JTAG oder Debug-Wire 
Verbindung sich nützliche Sachen anzeigen lassen, ohne eine 
UART-Schnittstelle zu blockieren.

Hier mein Programmcode für die Ausgabe:
1
#include <avr/io.h>
2
#include <stdio.h>
3
4
#ifndef __ASSERT_USE_STDERR
5
#define __ASSERT_USE_STDERR
6
#endif
7
#include <assert.h>
8
9
#define  DEBUG_SIZE 100
10
int debug_putchar(char c, FILE *stream)
11
{
12
  (void) stream; //unused
13
  volatile static char debug[DEBUG_SIZE];
14
  static uint8_t ptr = 0;
15
  debug[ptr++] = c;
16
  if (c < 32 || ptr == DEBUG_SIZE) {
17
    ptr = 0;
18
    (void) debug;
19
  }
20
  return 0;
21
}
22
23
#define TEST_ERROR 0
24
int main(void)
25
{
26
  static FILE debug_out = FDEV_SETUP_STREAM(debug_putchar, NULL, _FDEV_SETUP_WRITE);
27
  stdout = &debug_out;
28
  stderr = &debug_out;
29
  for (;;) {
30
    printf("test\r");
31
    assert(TEST_ERROR);
32
  }
33
}

Hinzu muss ein Breakpoint bei:
1
ptr = 0;
 gesetzt werden. In den Einstellungen des Breakpoints muss ein Haken 
unter „Aktionen“ gesetzt und unter „Meldung in Ausgabefenster 
protokollieren“ der Wert:
1
{debug,s}
 eingetragen werden. Hinzu macht es Sinn den Haken bei „Ausführung 
fortsetzen“ zu setzen, damit nicht bei jeder Ausgabe das Programm stehen 
bleibt.
In den Screenshot ist nochmal der Breakpoint und die resultierende 
Ausgabe dargestellt.

Vor allem finde ich es in Kombination mit asserts sehr praktisch da man 
so einen Fehler schnell ausfindig machen kann, ohne sein Programmcode 
dafür groß zu ändern.

von Karl (Gast)


Lesenswert?

Feine Sache :)

Kleiner Wermutstropfen: 2 KBytes vom kostbaren Flash.

Die Ausgabe 2 mit Newline ('\n') ist putzig.


Simulator(AS7, ATTiny85):

Ausgabe 1: printf("Broterwerb\r");
1
"Broterwerb
2
"
3
"Assertion failed: (TEST_ERROR), function main, file .././main.c, line 38.
4
"

Ausgabe 2: printf("Broterwerb\r\n");
1
"Broterwerb
2
"
3
"
4
roterwerb
5
"
6
"Assertion failed: (TEST_ERROR), function main, file .././main.c, line 38.
7
"

von Karl (Gast)


Lesenswert?

"putzig" hat sich erledigt.

von Leo (Gast)


Lesenswert?

Hallo Christian (ThreadOpener)

ich finde es gut, dass du deine Lösung mit (uns) anderen teilen 
möchtest. Um deine Lösung jedoch besser zu finden, wäre es prima, wenn 
du diese in einem Artikel oder Snippet hinterlegen könntest.

Gruß Leo

von Christian S. (christian_s593)


Lesenswert?

Karl schrieb:
> Kleiner Wermutstropfen: 2 KBytes vom kostbaren Flash.

Wenn man auf assert() und printf() verzichten kann, dann kann man auch 
viel Flash sparen. Stattdessen kann man zu puts() oder puts_P() greifen.
Den benötigten RAM bei assert darf man natürlich nicht außer Acht 
lassen.
Wenn es kritisch wird kann man natürlich auch "DEBUG_SIZE 100" 
verkleinern. Dadurch werden Ausgaben über mehrere Zeilen angezeigt, wenn 
die Ausgabe größer ist.

Karl schrieb:
> Die Ausgabe 2 mit Newline ('\n') ist putzig.

Ja stimmt, kleiner Schönheitsfehler, wenn man damit nicht leben kann 
einfach:
1
(void) debug;
durch:
1
memset((char *)debug, 0, sizeof(debug));
ersetzen. Jedoch wird auch dann noch jedes Steuerzeichen als Enter 
interpretiert. Wer das ändern will muss noch die Abfrage (c < 32) in (c 
== '\n') ändern, dann sollte es eigentlich passen.

Leo schrieb:
> Hallo Christian (ThreadOpener)
>
> ich finde es gut, dass du deine Lösung mit (uns) anderen teilen
> möchtest. Um deine Lösung jedoch besser zu finden, wäre es prima, wenn
> du diese in einem Artikel oder Snippet hinterlegen könntest.
>
> Gruß Leo

Ich hab den Link zu diesen Thread mal bei Atmel Studio unter Tipps 
und Tricks aufgenommen.

von Karl (Gast)


Lesenswert?

@  Christian

Vielen Dank für deine Erläuterungen :)

von Upgrade (Gast)


Lesenswert?

Vielen Dank für Deine Lösung. Ich plage mich seit Tagen damit rum. Danke 
Danke vielmals

von Pernilla Stromberg (Gast)


Lesenswert?

Vielen Dank fuer die Info, ist wirklich sehr nuetzlich. Warum muss man 
unter "Meldung in Ausgabefenster protokollieren" der Wert {debug,s} 
eingeben, bzw. wofuer is das "s" am Ende? Ich verstehe dass "debug" der 
Name der Variable ist, die angezeigt werden soll, daher dachte ich dass 
es auch ohne dem "s" funktionieren wuerde, tut es aber nicht.

von Tarif A. (tarifarbeiter)


Lesenswert?

S steht für string. Es wird alles bis zum ersten null terminierung 
rausgeschrieben.

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.