Forum: Mikrocontroller und Digitale Elektronik STM32F4 sprintf Problem


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich möchte über die UART Schnittstelle ein paar Daten ausgeben, doch 
leider scheint das Programm bei sprintf(str, "Acceleration X: %d",5) zu 
hängen, alles andere wird nicht mehr ausgeführt. Anscheinend 
funktioniert das mit dem %d nicht, kennt das Problem Jemand? Strings 
kann ich sonst problemlos ausgeben. Ich habe das mit dem Debugger 
getestet, der Wert von i existiert und es crasht nicht vor sprintf.


1
int main(void)
2
{
3
  TM_MPU6050_t MPU6050_Data;
4
  char str[120];
5
  /* Initialize system */
6
  SystemInit();
7
8
9
10
  /* Initialize USART, PB6, PB7*/
11
  TM_USART_Init(USART1, TM_USART_PinsPack_2, 57600);
12
13
  /* Initialize MPU6050 sensor SCL: PA8, SDA: PC9 */
14
  if (TM_MPU6050_Init(&MPU6050_Data, TM_MPU6050_Device_0, TM_MPU6050_Accelerometer_2G, TM_MPU6050_Gyroscope_2000s) != TM_MPU6050_Result_Ok) {
15
    /* Display error to user */
16
    TM_USART_Puts(USART1, "MPU6050 Error\n");
17
18
    /* Infinite loop */
19
    while (1);
20
  }
21
22
  while (1) {
23
    sprintf(str,"Test");
24
    TM_USART_Puts(USART1, str);
25
    for(int i=0;i<8000000;i++); //delay
26
27
    TM_MPU6050_ReadAll(&MPU6050_Data);
28
    int i=MPU6050_Data.Accelerometer_X;
29
    sprintf(str, "Acceleration X: %d",5);
30
31
    TM_USART_Puts(USART1, str);
32
33
    for(int i=0;i<8000000;i++); //delay
34
  }
35
}

: Bearbeitet durch User
von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Welcher Compiler, welche C-Library? Falls GCC&newlib, wie _sbrk_r 
implementiert?

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Ich verwende OpenSTM32, ich glaube das verwendet den GCC Compiler.

Dr. Sommer schrieb:
> _sbrk_r

Da bin ich überfragt.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian T. schrieb:
> Da bin ich überfragt.

Dann such doch mal in deinem Projekt danach, in den von der IDE 
angelegten Dateien...

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Ich vermute du meinst diese da, wurde in einem Header mit #define als 
_sbrk_r angegeben.
1
caddr_t _sbrk(int incr)
2
{
3
  extern char end asm("end");
4
  static char *heap_end;
5
  char *prev_heap_end;
6
7
  if (heap_end == 0)
8
    heap_end = &end;
9
10
  prev_heap_end = heap_end;
11
  if (heap_end + incr > stack_ptr)
12
  {
13
//    write(1, "Heap and stack collision\n", 25);
14
//    abort();
15
    errno = ENOMEM;
16
    return (caddr_t) -1;
17
  }
18
19
  heap_end += incr;
20
21
  return (caddr_t) prev_heap_end;
22
}

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sieht ganz sinnvoll aus. Finde mal heraus, in welcher Funktion es genau 
stehen bleibt.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Naja, ich komme mit dem Debugger gar nicht erst in sprintf(..%d..) 
hinein.

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das Problem kann also auch schon eine Zeile drüber liegen?
Kommentiere die mal aus.

Heap/Stack Grösse passen?

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Die zwei Zeilen drüber meinte ich...

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Das habe ich schon probiert, wenn ich in der while(1) Schleife nur z.B 
ein sprintf("..%d..",5) habe, hangt sich der debugger bei sprintf auf.

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
sprintf(str,"Test");

Funktioniert?

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nicht das einfach nur deine Delay Zählschleifen wegoptimiert werden.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
hp-freund schrieb:
> sprintf(str,"Test");
>
> Funktioniert?

Ja das geht, da kann ich auch die schleife laufen lassen und ich bekomme 
etwa alle halbe Sekunde ein Test im Terminal.

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Also vielleicht doch Speicherprobleme?
Gib mal deinem Linker ein:

 -specs=nano.specs

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sobald das Programm stehen bleibt halte es an, und schaue dir im 
Backtrace an welche Funktion es war...

von Nop (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Ich nehme mal an, itoa wäre zu einfach als Lösung, ne?

Falls nicht vorhanden, geht auch das hier:
https://www.mikrocontroller.net/articles/FAQ#Eigene_Umwandlungsfunktionen

von Stromverdichter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian,
du musst lernen, das Problem auf das Wesentliche zu reduzieren. Isoliere 
dein Problem und analysiere es dann. All die Schleifen die so manchmal 
nicht funktionieren(int ist oft nur 2 Byte lang, dann besser uint32_t 
nutzen, das stimmt immer) verschleiern doch nur die Problemchen. Ist 
deine Senderoutine Interrupt-basierend? Sind die Puffer richtig gesetzt? 
Sende am besten erst mal ein Byte und bastle dir dann den String selbst 
zusammen. Das hilft beim Verständnis ungemein.

Sebastian T. schrieb:
> int i=MPU6050_Data.Accelerometer_X;
>     sprintf(str, "Acceleration X: %d",5)

was soll das bewirken? Das funktioniert doch nicht. wo kommt den da die 
5 her, wofür ist die gut? Wo ist die Variable?

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
Stromverdichter schrieb:
> Das funktioniert doch nicht. wo kommt den da die 5 her, wofür ist die
> gut? Wo ist die Variable?

Vielleicht geht es um die Reduzierung auf das wesentliche?

Würde auch auf zu kleinen Stack tippen, printf ist da sehr hungrig.

Oder falsches/fehlendes include? Wird alles ohne Warnings übersetzt?

: Bearbeitet durch User
von Vorname N. (felixx)


Bewertung
0 lesenswert
nicht lesenswert
Klingt für mich spontan auch nach einem Stack-Überlauf.
Da die STMF4xx Derivate mehrere KB RAM bereitstellen, einfach mal mit 
"großzügigen" Werten
_Min_Heap_Size = 0x1000;
_Min_Stack_Size = 0x1000;
in der Linker-Steuerdatei testen. Die Datei ist an der Endung .ld 
erkennbar.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Stromverdichter schrieb:
> was soll das bewirken? Das funktioniert doch nicht. wo kommt den da die
> 5 her, wofür ist die gut?

Das war nur zum testen, ich habe das Programm nun mal auf das 
wesentliche reduziert, das Versenden von Integer Variablen.

Ich habe die _Min_Heap_Size auf 0x1000 gesetzt, doch leider ohne Erfolg.

Nop schrieb:
> Ich nehme mal an, itoa wäre zu einfach als Lösung, ne?

itoa funktioniert, es wird nur ein bisschen mühsamer alle Sensordaten zu 
senden. Mich laust es aber, warum das mit sprintf nicht geht.
1
#include "stm32f4xx.h"
2
#include "stm32f4_discovery.h"
3
#include "tm_stm32f4_usart.h"
4
#include <stdio.h>
5
#include <stdlib.h>
6
7
int main(void)
8
{
9
  SystemInit();
10
11
  char str[120];
12
13
  TM_USART_Init(USART1, TM_USART_PinsPack_2, 57600);
14
15
  while (1) {
16
17
    sprintf(str,"Start");
18
    TM_USART_Puts(USART1, str);
19
    for(int i=0;i<8000000;i++);
20
21
    sprintf(str, "Test Number: %d",5);
22
    TM_USART_Puts(USART1, str);
23
    for(int i=0;i<8000000;i++);
24
  }
25
}

: Bearbeitet durch User
von Jannyboy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian T. schrieb:
> sprintf(str, "Test Number: %d",5);

So kann das nicht funktionieren 5 ist keine Integer Variable.

So sollte es gehen:
1
int var = 5;
2
sprintf(str, "Test Number: %d",var);

von Christian D. (burning_legend)


Bewertung
0 lesenswert
nicht lesenswert
Gab es bei dem STM32 mit GCC nicht Alignment Probleme im Demo-Code? Ich 
hab es jetzt nicht genau im Kopf, aber die linker files hatten afair 
eine falsche Stack-Adresse drin stehen. Welches Linker Script benutzt 
du?

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moin,
was ist mit

-specs=nano.specs

?

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jannyboy schrieb:
> Sebastian T. schrieb:
>> sprintf(str, "Test Number: %d",5);
>
> So kann das nicht funktionieren 5 ist keine Integer Variable.

Unsinn, natürlich funktioniert das (gerade getestet). Es muß ein Integer 
übergeben werden, und selbstverständlich kann das auch eine Zahl sein.

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
vielleicht mal das map file posten?

von Stromverdichter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Zum testen könntest du mal
char str[16];
kleiner machen und alternativ das array außerhalb der main global 
deklarieren, dann sollte es doch nicht auf dem Stack liegen.
Hoffentlich findest du bald den Fehler, ich bin echt gespannt, wo er 
liegt. Den Stack kannst du dir nicht einfach mal mit dem Debugger 
anschauen?

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian T. schrieb:
> TM_USART_Puts(USART1, str);

Und Du bist sicher, dass TM_USART_Puts blockierend arbeitet und den 
Inhalt von str nicht vorher umkopiert?

von Sebastian T. (sebastian_tsch)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe alles mögliche probiert, leider immer noch kein Erfolg. Ich 
kann auch nicht mit dem Debugger in sprintf rein um zu sehen, was genau 
passiert. Auf den Mikrocontrollern ist ja meist eine gekürzte Version 
von printf drauf, doch wo kann ich die einsehen/ändern? Es liegt ganz 
klar an sprintf und nicht an einer anderen Codezeile, es crasht mir 
sogar wenn ich nur ein sprintf in der Hauptschleife habe, aber eben nur 
wenn ich noch Werte dem String hinzufügen will.
1
sprintf("test"); //geht wunderbar
2
sprintf("test %d",1); //crash

Im Anhang habe ich das Mapfile.

Grüsse Sebastian

: Bearbeitet durch User
von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
>
>
1
> sprintf("test"); //geht wunderbar
2
> sprintf("test %d",1); //crash
3
>
>

a) Schau Dir an, ob Du printf oder sprintf verwenden wolltest
b) schalte die Warnmeldungen ein. Alle.
c) RTFM für sprintf. Egal wo, die ersten 2 Absätze reichen, notfalls nur 
die Declaration.

wenn nach 2 Minuten noch etwas unklar sein sollte, melde Dich.

: Bearbeitet durch User
von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian T. schrieb:
> sprintf(str,"Test");

Da wird aber auch kein sprintf aufgerufen. Der gcc ist mittlerweile so 
schlau zu merken, dass dafür ein strcpy(str,"Test"); reicht und sprintf 
hier "mit Kanonen nach Spatzen" wäre.

Ich denke das liegt an _sbrk. Das wird bei "sprintf(str,"Test");" nicht 
aufgerufen, nur bei "sprintf("test %d",1);"

Was heißt crasht? Was passiert denn wenn du im gecrashten Zustand im 
Debugger das Programm unterbrichst? Landest du da im Hardfault oder wo?

Ansonsten die _sbrk mal aus dem Header nehmen und normal mit in das 
c-File packen ohne #define. Dann kannst du auch da mal einen Breakpoint 
setzen.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
Achim S. schrieb:
>>
>>
1
>> sprintf("test"); //geht wunderbar
2
>> sprintf("test %d",1); //crash
3
>>
>>
>
> a) Schau Dir an, ob Du printf oder sprintf verwenden wolltest
> b) schalte die Warnmeldungen ein. Alle.
> c) RTFM für sprintf. Egal wo, die ersten 2 Absätze reichen, notfalls nur
> die Declaration.
>
> wenn nach 2 Minuten noch etwas unklar sein sollte, melde Dich.

Ich habe das hier im Forum nur falsch geschrieben, ich meinte natürlich:
1
sprintf(str,"test:"); //geht wunderbar
2
sprintf(str,"test: %d",100); //crash

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
laut deinem mapfile gibt es eine src/syscalls.c. Da stehen normalerweise 
diese Sachen drin die für sprintf noch interessant sind. Poste die doch 
mal.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
temp schrieb:
> Was heißt crasht? Was passiert denn wenn du im gecrashten Zustand im
> Debugger das Programm unterbrichst? Landest du da im Hardfault oder wo?

Wenn ich den Debugger verwende und in die Funktion gehen will, passiert 
einfach nichts und es scheint in einer loop zu hängen.

temp schrieb:
> Ansonsten die _sbrk mal aus dem Header nehmen und normal mit in das
> c-File packen ohne #define. Dann kannst du auch da mal einen Breakpoint
> setzen.

Werde ich mal probieren, danke.

von Sebastian T. (sebastian_tsch)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
temp schrieb:
> laut deinem mapfile gibt es eine src/syscalls.c. Da stehen normalerweise
> diese Sachen drin die für sprintf noch interessant sind. Poste die doch
> mal.

Ok, habe das syscalls.c im Anhang. Dort ist ja auch _sbrk definiert.

: Bearbeitet durch User
von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
mach doch mal einen Breakpoint da drauf. Da siehst du wenigstens was 
passiert.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
temp schrieb:
> mach doch mal einen Breakpoint da drauf. Da siehst du wenigstens was
> passiert.

Das habe ich probiert, doch ich komme gar nie in _sbrk hinein. Auch wenn 
ich "step in" klicke im debugger für sprintf(...), dann passiert nichts. 
Ich komme auch nicht in sprintf(str,"test"); hinein, obwohl dies 
funktioniert.

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Kannst du denn den Debugger nicht anhalten und dann sehen wo er steht? 
Wenn nicht, dann denk mal über ne vernünftige Entwicklungsumgebung nach.

passt den deine Implementierung der syscall.c zum Linkerscript?

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian T. schrieb:
> Ich komme auch nicht in sprintf(str,"test"); hinein, obwohl dies
> funktioniert.

Das habe ich eben schon versucht zu erklären. Da steht zwar sprintf aber 
der Compiler merkt das da keine Parameter übergeben werden und macht ein 
strcpy draus. Deshalb brauchst du da auch nicht weiter forschen.

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hier noch ein Auszug aus deinem map-File:

LOAD 
c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1 
.7.0.201602121829/tools/compiler/bin/../lib/gcc/arm-none-eabi/5.2.1/armv 
7e-m/fpu/crtn.o
                0x20020000                _estack = 0x20020000
                0x00000000                _Min_Heap_Size = 0x0
                0x00000400                _Min_Stack_Size = 0x400

.isr_vector     0x08000000      0x188


ohne Heap wird das halt nichts. Bau mal ein malloc in deinen Code ein. 
Das wird dann auch crashen.

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
temp schrieb:
> c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1
> .7.0.201602121829/tools/compiler/bin/../lib/gcc/arm-none-eabi/5.2.1/armv
> 7e-m/fpu/crtn.o
>                 0x20020000                _estack = 0x20020000
>                 0x00000000                _Min_Heap_Size = 0x0
>                 0x00000400                _Min_Stack_Size = 0x400
>
> .isr_vector     0x08000000      0x188
>
> ohne Heap wird das halt nichts. Bau mal ein malloc in deinen Code ein.
> Das wird dann auch crashen.

Ich habe den Heap und Stack auch schon auf 0x1000 getan, leider kein 
Erfolg.

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sorry, aber das passt alles nicht zusammen. Wenn du in deiner IDE was an 
den Einstellungen drehst muss sich das auch im map-File wieder finden. 
Auch die Symbole im Code müssen zum Linkerscript passen. Ich vermute mal 
das wurde alles irgendwie zusammen kopiert ohne zu wissen wie es 
zusammenhängt. Deshalb nochmal die Frage: Wer hat dir den die syscalls.c 
ins src Verzeichnis gezaubert und wie passt die zum Linkerscript? Poste 
das Linkerscript oder ein mini-Projekt mal komplett. Im Moment stocherst 
du nur im trüben und bist meilenweit von einer systematischen 
Fehlersuche entfernt.

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
nimm die syscalls.c mal raus aus deinem Projekt und berichte die 
Linkerfehler. Vielleicht hat dir die IDE, das unbekannte Wesen, schon 
alles richtig zusammengebaut und du versuchst krampfhaft deine eigenen 
Versionen zu linken und gewinnst.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian T. schrieb:
> temp schrieb:
>> mach doch mal einen Breakpoint da drauf. Da siehst du wenigstens was
>> passiert.
>
> Das habe ich probiert, doch ich komme gar nie in _sbrk hinein. Auch wenn
> ich "step in" klicke im debugger für sprintf(...), dann passiert nichts.
> Ich komme auch nicht in sprintf(str,"test"); hinein, obwohl dies
> funktioniert.
Bei derart hartnäckigen Problemen hilft Assembler-Level Debugging. 
Benutze "stepi" im GDB um jede Instruktion einzeln auszuführen. 
Irgendwann wird es dann ja abstürzen/stehen bleiben/Im Fault Handler 
landen. Dann siehst du woran es gelegen hat.

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich tippe mal auf eine andere Baustelle. Fpu benutzt und nicht 
initialisiert.


Schreib das mal an den Anfang deines Codes:

volatile float f=1.123f;
f/=3.567f;

Wenn es dann schon abschmiert hast du die Ursache.

von temp (Gast)


Bewertung
0 lesenswert
nicht lesenswert
in OpenSTM32 muss da wenn ich das richtig sehe

__FPU_USED=1

definiert sein.
Hier ein Auszug aus der system_stm32f4xx.c

1
void SystemInit(void)
2
{
3
  /* FPU settings ------------------------------------------------------------*/
4
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
5
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
6
  #endif
7
  /* Reset the RCC clock configuration to the default reset state ------------*/
8
  /* Set HSION bit */
9
  RCC->CR |= (uint32_t)0x00000001;
10
11
  /* Reset CFGR register */
12
  RCC->CFGR = 0x00000000;
13
14
  /* Reset HSEON, CSSON and PLLON bits */
15
  RCC->CR &= (uint32_t)0xFEF6FFFF;
16
17
  /* Reset PLLCFGR register */
18
  RCC->PLLCFGR = 0x24003010;
19
20
  /* Reset HSEBYP bit */
21
  RCC->CR &= (uint32_t)0xFFFBFFFF;
22
23
  /* Disable all interrupts */
24
  RCC->CIR = 0x00000000;
25
26
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
27
  SystemInit_ExtMemCtl(); 
28
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
29
30
  /* Configure the Vector Table location add offset address ------------------*/
31
#ifdef VECT_TAB_SRAM
32
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
33
#else
34
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
35
#endif
36
}



__FPU_PRESENT wird an anderer Stelle automatisch gesetzt wenn 
__FPU_USED=1 definiert ist.

Oder kommentier das #if und #endif vor und nach

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 
Full Access */

aus. Bin mir zu 95% sicher dass das dein Problem ist!

von Sebastian T. (sebastian_tsch)


Bewertung
0 lesenswert
nicht lesenswert
temp schrieb:
> Bin mir zu 95% sicher dass das dein Problem ist!

Wow, vielen Dank, genau das war das Problem. Ich verwende Openstm32 und 
die syscalls.c sowie die system_stm32f4xx.c wurden automatisch erzeugt. 
In SystemInit() hat SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); 
komplett gefehlt.

Grüsse und Danke
Sebastian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.