www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega32 Absturz bei Zeicheneingang


Autor: Andreas B. (bitverdreher)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
nachdem ich mir schon länger den Wolf suche, warum mein ATMega32 immer 
abstürzt wenn ich Zeichen über den Uart (mit gtkterm unter Linux) 
einlaufen lasse, bin ich jetzt endlich mal systematisch vorgegangen und 
habe:

a) an der Hardware alles unnötige entfernt. Es handelt sich hier um eine 
3-Achsenmotorsteuerung mit Encoder usw. Der Max hat einen 100nF direkt 
am Versorgungspin. Am ATMega ebenfalls jeweils PIN 11/12 und 30/31 
100nF.
Die 24V Versorgung und die Motoren wurden entfernt.

b) die SW drastisch reduziert, bis der Absturz nicht auftaucht. Das 
Ergebnis steht hier:
/*******************************************************************
*
* Chip type           : ATmega32
* Clock frequency     : 14,745600 MHz
* lfuse e1 = 1110 0001 -> 0e = 0000 1110
* hfuse 99 = 1001 1001 -> d9 = 1101 1001
* avrdude -p atmega32 -P /dev/ttyS0 -b 115200 -c avr910 -U lfuse:w:0x0e:m
* avrdude -p atmega32 -P /dev/ttyS0 -b 115200 -c avr910 -U hfuse:w:0xd9:m
*
*    test.c
*
* To do:
*
********************************************************************/


#include "hardwaredef.h"

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdlib.h>
#include <util/delay.h>
#include "test.h"

char sCommandString[BUFFER_LENGHT];
char sOutString[BUFFER_LENGHT];

int8_t execute (const char *text);

int16_t lCommandPar1;
int16_t lCommandPar2;

// Status and Error Flags
volatile int8_t iUartFlags;
volatile char sInBuffer[BUFFER_LENGHT];
volatile uint8_t iBufferPtr;

void InitPorts(void) {
   // port inputs
   DDRA &= ~( (1<<SLID_ENC_1) | (1<<SLID_ENC_2) | (1<<SLID_REF) | (1<<TURN_H_END) );
   //   DDRB &= ~( (1<<PB6) );
   DDRC &= ~( (1<<VERT_REF) | (1<<VERT_H_END) | (1<<TURN_REF) | (1<<SDA) | (1<<SCL) );
   DDRD &= ~( (1<<VERT_ENC_1) | (1<<VERT_ENC_2) | (1<<TURN_ENC_1) | (1<<TURN_ENC_2));
   // port outputs
   DDRA |= (1 << GRIP) | (1 << RESERVE0) | (1 << RESERVE1);
   DDRB |= (1 << SLID_3A) | (1 << SLID_4A) | (1 << TURN_1A) |  (1 << TURN_PWM) | (1 << TURN_2A) | (1 << LASER);
   DDRC |= (1 << VERT_DIRECTION) | (1 << VERT_STOP);
   DDRD |= (1 << VERT_PWM) | (1 << SLID_PWM);
   // activate pullup resistors
   PORTA |= ((1<<SLID_ENC_1) | (1<<SLID_ENC_2) | (1<<SLID_REF) | (1<<GRIP));
   PORTC |= ((1<<SDA) | (1<<SCL));
}

// ------------------------------------------------------------ IRQ
ISR(__vector_default) { UsartPuts ("Undefined IRQ"); }


// ------------------------------------------------------------ USART

void InitUsart(void) {
   UBRRH = (uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);       // set baud rate
   UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_CPU);
   UCSRB = (1 << RXEN) | (1 << TXEN) ;                 // enable receiver and transmitter 
   UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0) | (1 << UPM1); // asynchronous 8N1, even Parity
   do UDR; while (UCSRA & (1 << RXC));                               // flush receiver               
}


char GetCommand (int16_t *lPar1, int16_t *lPar2, char *sComm) {
//int8_t iRecStrPtr;
int8_t iTmpBufferPtr;

   iTmpBufferPtr = 0;

    if (iUartFlags & FLAG_COMM_COMP ) {                                                       // Jetzt parsen bis EOS
       
// UsartPuts ("\n\nHier solls nicht hin\n");
//       iRecStrPtr = 0;
//       while ((sInBuffer[iTmpBufferPtr] != 0x00) && (sInBuffer[iTmpBufferPtr] != 0x20)) {     // Command, max. String Länge aus ISR gesichert
//          sComm[iRecStrPtr++] = sInBuffer[iTmpBufferPtr++];
//       }
//       sComm[iRecStrPtr++] = 0x00;

      return 1;
   } else {
      return 0;
   }

}

void UsartPutc(char c) {
int temp_Statusreg;
   temp_Statusreg = SREG;
   while(!(UCSRA & (1 << UDRE)));                              // wait until UDR ready
   UDR = c;                                                    // send character
   SREG = temp_Statusreg;
}

void UsartPuts (char *s) {                                    //  loop until *s != NULL
   while (*s) {
      UsartPutc(*s);
      s++;
   }
}

void PrintByteBinaer(char byte) {
uint8_t iPos;
   for (iPos=1; iPos<=8; iPos++) {
      if (byte & 0x80)
         UsartPutc(0x31);
      else
         UsartPutc(0x30);
      byte = byte << 1;
      if (!(iPos & 0x03)) UsartPutc(0x20);
   }
   UsartPuts("\n");
}

// ------------------------------------------------------------ Mainloop
 

int main(void) {

   InitUsart();
   InitPorts();


   // send init string
   UsartPuts ("\n\nVersion 1.00 Andys Testprogramm\n");

   if (MCUCSR & (1<<BORF))          // Brown-Out Reset
      UsartPuts("Brown-Out Reset");
   else if (MCUCSR & (1<<PORF))     // Power-On Reset
      UsartPuts("Power-On Reset");
   else if (MCUCSR & (1<<JTRF))     // JTAG Reset
      UsartPuts("JTAG Reset");
   else if (MCUCSR & (1<<EXTRF))    // External Reset
      UsartPuts("External Reset");
   else if (MCUCSR & (1<<WDRF))     // Watchdog Reset
      UsartPuts("Watchdog Reset");
   else
      UsartPuts("Manual Jump");
   UsartPuts ("\nMCUCSR: ");
   PrintByteBinaer(MCUCSR);
   MCUCSR &= 0xE0;                  // Clear Reset-Status
   UsartPuts ("\n");

   sei();                           // set global interrupts

   UsartPuts ("\n\nReady\n");
   
   while (1) {
     if (GetCommand(&lCommandPar1, &lCommandPar2, sCommandString) !=0) {
         UsartPuts("\n");
         UsartPuts (sCommandString);
         UsartPuts (" ");
         UsartPuts (ltoa(lCommandPar1, sOutString, 10));
         UsartPuts (" ");
         UsartPuts (ltoa(lCommandPar2, sOutString, 10));
         UsartPuts (" -> ");
         UsartPuts("\n>>");
      }
   }
   return 0;
}

Eigentlich funktioniert hier gar nichts. Das Ganze ist so ziemlich 
sinnfrei. Aber ich kann unter gtkterm eine Taste gedrückt halten und 
nichts passiert.
Aber wenn ich jetzt den auskommentierten Teil in GetCommand wieder 
einkommentiere und den Finger auf der Tatatur halte, stürzt der Atmel 
ab. Das erkennt man daran, daß er neugestartet wird (kein Watchdog) und 
das MCUCSR Register dann 0 ist.

Das ist die Ausgabe von gtkterm (mit echo):
Version 1.00 Andys Testprogramm
External Reset
MCUCSR: 0000 0010 



Ready
ggggggg

Version 1.00 Andys Testprogramm
Manual Jump
MCUCSR: 0000 0000 



Ready
ggggggggggggggggggggggggggggggggg

Version 1.00 Andys Testprogramm
Manual Jump
MCUCSR: 0000 0000 



Ready
gggggggggggggggggggggggggggg

Und so ohne Absturz:

Version 1.00 Andys Testprogramm
External Reset
MCUCSR: 0000 0010 



Ready
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
gggggggggggggggggg

Mit einem anderne ATmega das gleiche.

Hat jemand eine Idee ? Ich dreh noch langsam durch.
Die fuses sind so gesetzt, wie man es in der Kopfzeile sieht.

Gruß
Andy

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann das hier
       while ((sInBuffer[iTmpBufferPtr] != 0x00) && (sInBuffer[iTmpBufferPtr] != 0x20)) {     // Command, max. String Länge aus ISR gesichert
          sComm[iRecStrPtr++] = sInBuffer[iTmpBufferPtr++];
       }
       sComm[iRecStrPtr++] = 0x00;
einen Pufferüberlauf geben, da nie geprüft wird, ob iRecStrPtr die größe 
von sComm überschreitet? Irgendwann wird dann der Stack überschrieben, 
und es kracht...

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Bernhard,
gut daß Du mich daran erinnerst ;-). Das wollte ich noch reinmachen. 
Normalerweise sollen die Zeichen auch über ein Programm vom PC kommen. 
Hier wollte ich eigentlich dafür sorgen, daß die Zeichenkette in der 
Länge begrenzt bleibt.
Nur hier kommt er ja merkwürdigerwiese gar nicht immer hin.
Das "UsartPuts ("\n\nHier solls nicht hin\n");" wird ja gar nicht 
ausgegeben. iUartFlags bleibt hier durch die starke SW Reduzierung 0.

Gruß
Andy

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
'Absturz' bei Zeichenempfang hört sich so an wie fehlende oder falsche 
ISR, hat das richtige Programm einen Teil wie :

ISR(USART_RXC_vect)
{
  uint8_t ch;

  ch = UDR;    // read byte from data register
// ...
}

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Bernhard:
Ich habe es gerade mal geändert:
      while ((sInBuffer[iTmpBufferPtr] != 0x00) && (sInBuffer[iTmpBufferPtr] != 0x20 && (iTmpBufferPtr <= (BUFFER_LENGHT-2)))) {     // Command, max. String Länge aus ISR gesichert

-> Gleicher Effekt.

Johannes:
Die ISR hatte es. Das gepostete Programm ist vollständig. Der IRQ des 
Zeichenempfangs ist hier deaktiviert.
Als default steht hier: ISR(__vector_default) { UsartPuts ("Undefined 
IRQ"); }

Gruß
Andy

Ach ja, wem die hardwaredef.h noch interessiert (da wir gerade bei 
"vollständig" sind)

Autor: Andreas B. (bitverdreher)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal die hardwaredef.h

Gruß
Andy

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das sieht schon komisch aus. Es gibt aber noch Warnings weil UsartPuts() 
aufgerufen wird bevor es deklariert wird, damit kann es den Stack 
kaputtmachen. Aber eigentlich soll die Funktion ja garnicht aufgerufen 
werden.
Wenn die Zeilen auskommentiert bleiben wird der Call zu GetCommand() 
komplett wegoptimiert, wenn die Zeilen eingefügt werden läuft es im 
Simulator richtig ab. Da bliebe ja nur das der Reset durch einen 
Hardwarefehler ausgelöst wird.

Autor: Andreas B. (bitverdreher)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Johannes,
ja an einen Hardwarefehler dachte ich ja auch schon. Ehrlich gesagt, war 
ich schon so sicher, daß ich die Platine neu designen wollte. Merkwürdig 
ist ja nur, daß mit dem Auskommentieren dieser Zeilen der AVR nicht mehr 
abstürzt.
Vielleicht ist es auch beides HW und SW....:-(

Und sorry, die test.h habe ich vergessen. Da hätte er bei Dir eigentlich 
schon beim Versuch meckern müssen, sie zu includen.

Aber es wäre super, wenn jemand mit einem ATMega32 und Uart dies mit gcc 
mal compilieren und auf seiner Tastatur mal eine Taste festhalten würde.
Dem Simulator glaub ich da nicht. Ich  habe mir auch noch nie die Mühe 
gemacht, den gdb-avr oder so etwas einzurichten.

Gruß
Andy

Autor: Andreas B. (bitverdreher)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Und hier noch die Platine. Die Versorgung habe ich mal markiert.
Zusätzlich ist noch am Max232 zwischen Pin 15/16 und am AVR zwischen Pin 
10/11 ein 100n Kerko.

Gruß
Andy

Autor: Andreas B. (bitverdreher)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
jetzt wird es noch merkwürdiger:
schalte ich die Optimierung von s auf 3 dann wird der Code größer, 
schneller (Ich habe jetzt mal eine LED in der main blinken lassen) und 
stürzt nicht mehr ab. :-o
Mit optimierung 2 stürzt er am schnellsten ab.

neue Main:
int main(void) {

   InitUsart();
   InitPorts();


   // send init string
   UsartPuts ("\n\nVersion 1.00 Andys Testprogramm\n");

   if (MCUCSR & (1<<BORF))          // Brown-Out Reset
      UsartPuts("Brown-Out Reset");
   else if (MCUCSR & (1<<PORF))     // Power-On Reset
      UsartPuts("Power-On Reset");
   else if (MCUCSR & (1<<JTRF))     // JTAG Reset
      UsartPuts("JTAG Reset");
   else if (MCUCSR & (1<<EXTRF))    // External Reset
      UsartPuts("External Reset");
   else if (MCUCSR & (1<<WDRF))     // Watchdog Reset
      UsartPuts("Watchdog Reset");
   else
      UsartPuts("Manual Jump");
   UsartPuts ("\nMCUCSR: ");
   PrintByteBinaer(MCUCSR);
   MCUCSR &= 0xE0;                  // Clear Reset-Status

   UsartPuts ("\n\nReady\n");
   
   while (1) {
      
      iCounter++;
      if (iCounter == 0) {
         if (iLaserOn == 0) {
            LASER_OFF;
            iLaserOn = 1;
         } else {
            LASER_ON;
            iLaserOn = 0;
         }        
      }
        
     if (GetCommand(&lCommandPar1, &lCommandPar2, sCommandString) !=0) {
         UsartPuts("\n");
         UsartPuts (sCommandString);
         UsartPuts (" ");
         UsartPuts (ltoa(lCommandPar1, sOutString, 10));
         UsartPuts (" ");
         UsartPuts (ltoa(lCommandPar2, sOutString, 10));
         UsartPuts (" -> ");
         UsartPuts("\n>>");
      }
   }
   return 0;
}

langsam blick ich es wirklich nicht mehr.

Gruß
Andy

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was um alles in der Welt hat R11 fuer eine Funktion?
Und nicht soviel Code inline posten...

Autor: GagoSoft (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seltsame Abstürze ergeben sich bei AVRs auch wenn eine ISR doppelt 
ausgeführt wird. Also wenn währent einer Interruptbehandlung der selbe 
Interrupt nochmal ausgeführt wird....

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann aber faktisch nicht passieren, weil waehrend der ISR die 
Interrupts deaktiviert sind.

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Andreas B. (bitverdreher):

mal abgesehen von R11, den Michael schon gefunden hat:

Wenn Du wirklich Hilfe möchtest, dann poste uns doch mal den Schaltplan,
beispielsweise als Eagle File,
dann kann man auch die Fehler besser verfolgen.
Ich habe zb. keine Lust Carrera Bahn auf Deinem Layout zu fahren,
geschweige jetzt pdfs herunterzuladen um dann die Portpins mit Deinen 
angeschlossenen Pins zu vergleichen.

Ebenso solltest Du mal ein einfaches Programm zum einfachen
"echo" der UART-Schnittstelle erzeugen oder jemand der sich erbarmt.

Gruß Sven

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entschuldigung, im ersten Posting ist der Schaltplan. Sorry.

Gruß Sven

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas

Du solltest mal CKOPT in hfuse setzen.

Gruß, Volker

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael G. wrote:
> Was um alles in der Welt hat R11 fuer eine Funktion?

Das frag ich mich jetzt auch. Das muß ich wohl irgendwoher 
abgepinselt/abgeleitet haben. Und weg ist er (Leiterbahn direkt am AVR 
abgekratzt).
Aber das Problem besteht leider noch genauso.

Sven: Mein original Programm ist 60k groß und besteht aus mehreren 
Files. Was Du hier siehst ist die Reduktion auf das minimalste, um den 
Fehler einzugrenzen. Deswegen lasse ich auch nur eine LED blinken, um 
AVR Lebenszeichen nachzuweisen.

Gagosoft: Die IRQs wurden ausgeknipst (kein sei() mehr)

Gruß
Andy

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Andreas B. (bitverdreher):

Warum hat der RESET vom AVR nur einen Pullup und keinen C = 100nF ?

Gruß Sven

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe das Programm (die vorletzte Version ohne Blink LED) auf meiner 
Mega32 Hardware geladen, es läuft ohne Probleme. Die Ausgaben kommen und 
dann kann ich Daten schicken wie ich will, der AVR ignoriert sie und nix 
stürzt ab. Optimierungen -Os und -O2 probiert. Also ich würde sagen an 
der SW liegts definitiv nicht. Bricht die Versorgung vielleicht zusammen 
durch irgendeinen Schluss von Datenleitung nach Vcc oder Masse?

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal

Hast du das mit dem CKOPT mal ausprobiert? Geht doch schnell :-)

Ich hatte mal ein ähnliches Problem und es hat geholfen.

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Volker,
Ich glaube, das war der Tip des Monats. Ich danke Dir !!
Ins Datenblatt geguckt, Fuse gesetzt und es scheint zu funktionieren.

Was so ein kleines Bit docb ausmacht und für Effekte hevorruft. Ich 
betreibe dieses Ding schon die ganze Zeit problemlos als 3 
Achsensteuerung mit Encoder. Nur der Uart Eingang scheint davon 
betroffen zu sein.

Gruß
Andy

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sven,
den C habe ich später mal aus Sicherheitsgründen (Angstkondensator nennt 
man das jetzt ja wohl) direkt auf die Platine gelötet. Die sieht auch 
nicht mehr so aus, wie auf dem Bild. Aber wenn es daran gelegen hätte, 
hätte man das vermutlich am Register MCUCSR gesehen oder ?

Johannes: Danke fürs Testen. Das bestätigt mir noch einmal daß das mit 
dem nun funktionierenden AVR mit CKOPT fuse kein Zufall ist.

Gruß
Andy

Jetzt werde ich mal wieder alles zusammenbauen und den AVR wieder voll 
machen.....

Vielleicht sollte ich meine Probleme mal öfter hier hineinstellen ;-)

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wg. MCUCSR Register: da gabs hier mal einen kleinen Thread:
Beitrag "Bekomme keine gültigen MCUSR Werte"
in deinem Code wird das Register relativ spät ausgelesen, da kann ja 
schon wieder einiges passiert sein. In dem angebegenen Thread wird das 
Register dann in dem init Code vom Compiler ausgelesen.
Und der Simulator im AVRStudio ist schon genial, wenn es ein 
Compilerfehler gewesen wäre hätte man das beim Steppen schon gesehen. 
Was dem Simulator fehlt ist so Hardware zu simulieren und z.B. Zeichen 
in einem Terminal auszugeben wenn das USART Register beschrieben wird. 
Oder gibt es dafür ein Plugin?

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Johannes,
das stimmt, ich habe das Register erst recht spät ausgelesen. Man sollte 
dies als 1.Befehl zwischenspeichern.
Ich glaube aber kaum, daß Du einen Hardwaresimulator finden wirst, der 
einen Quarzoszillator mit zu geringem Pegel an einem AVR simuliert ;-)
Du kannst ja mal versuchen, Spice ins AVRStudio zu integrieren. Da 
träumen hier glaube ich, viele davon.

Wenn ich etwas debuggen muß, lasse ich mir den Kram übers UART ausgeben. 
Und wenn man da zuviel ausgeben muß, liegt der Verdacht nahe, daß man 
sich vorher über das Programm zu wenig Gedanken gemacht hat.
Aber es stimmt schon, in diesem Fall hätte ich die SW schneller 
ausschließenm können.
Meist sind es aber zeitkritische Dinge, wo man das Bedürfnis hat zu 
simulieren. Und gerade da zeigen sich ja die Schwächen der Simulation.

Allerdings habe ich mich noch nicht mit Jtag beschäftigt. Das scheint 
diesbezüglich schon interessanter zu sein.

Gruß
Andy

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.