stm32f103 RTC Interrupt öfter als erwartet

Gast #5757229
Es geht um folgendes Programm auf einem Nucleo-64 Board mit STM32F103RB 
(ohne HAL):
1
#include "stm32f1xx.h"
2

3
void initRtc()
4
{
5
    // Enable the backup domain
6
    SET_BIT(RCC->APB1ENR, RCC_APB1ENR_BKPEN + RCC_APB1ENR_PWREN);
7

8
    // Enable write access to the backup domain
9
    SET_BIT(PWR->CR, PWR_CR_DBP);
10

11
    // Enable LSE oscillator
12
    SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
13

14
    // Wait until LSE oscillator is ready
15
    while(!READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY)) {}
16

17
    // Select LSE as clock source for the RTC
18
    MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, RCC_BDCR_RTCSEL_LSE);
19

20
    // Enable the RTC
21
    SET_BIT(RCC->BDCR, RCC_BDCR_RTCEN);
22

23
    // Wait until RTC is synchronized
24
    while(!READ_BIT(RTC->CRL, RTC_CRL_RSF)) {}
25

26
    // Wait until last write operation is done
27
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
28

29
    // Enable second interrupt
30
    SET_BIT(RTC->CRH,RTC_CRH_SECIE);
31

32
    // Wait until last write operation is done
33
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
34

35
    // Enter configuration mode
36
    SET_BIT(RTC->CRL,RTC_CRL_CNF);
37

38
    // Divide oscillator frequency by 32767+1 to get seconds
39
    RTC->PRLL=32767;
40
    RTC->PRLH=0;
41

42
    // Leave configuration mode
43
    CLEAR_BIT(RTC->CRL,RTC_CRL_CNF);
44

45
    // Wait until last write operation is done
46
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
47

48
    // Enable interrupt in NVIC
49
    NVIC_EnableIRQ(3);
50
}
51

52
void init_io()
53
{
54
    // Enable Port A
55
    SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);
56

57
    // PA5 = Output
58
    MODIFY_REG(GPIOA->CRL, GPIO_CRL_CNF5 + GPIO_CRL_MODE5, GPIO_CRL_MODE5_0);
59
}
60

61
void RTC_IRQHandler(void)
62
{
63
    // If a second has elapsed, then ...
64
    if (READ_BIT(RTC->CRL,RTC_CRL_SECF))
65
    {
66
        // Toggle LED
67
        GPIOA->ODR ^= GPIO_ODR_ODR5;
68

69
        // Clear interrupt flag
70
        CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
71
    }
72
}
73

74
int main(void)
75
{
76
    init_io();
77
    initRtc();
78
    while(1){};
79
}

Das Programm funktioniert, die LED Blinkt im Sekundentakt. Aber wenn ich 
die Zeile
1
if (READ_BIT(RTC->CRL,RTC_CRL_SECF))

weg lasse, dann blitzt die LED jede Sekunde nur ganz kurz auf. Man kann 
es so gerade eben mit blossem Auge erkennen. Daraus schliesse ich, dass 
nach dem Sekunden-Interrupt immer noch ein zweiter Interrupt auftritt. 
Aber warum? Ich bin mir nicht dessen bewusst, eine andere 
Interrupt-Quelle aktiviert zu haben.
Gast
Auch mit dieser Zeile:
1
if (READ_BIT(RTC->CRL,RTC_CRL_SECF) || READ_BIT(RTC->CRL,RTC_CRL_ALRF) || READ_BIT(RTC->CRL,RTC_CRL_OWF))
blinkt die LED schön im Sekundentakt. Ich verstehe das nicht, es gibt 
doch nur diese drei Quellen für den IRQ, oder nicht?
Gast
Ich sehe nichts im Reference Manual, dass die Flags beim lesen 
automatisch gelöscht werden. Das muss per SW gemacht werden. Keine 
Ahnung was es ist, aber lass doch die IF Abfrage einfach drin, wenn es 
damit funktioniert...
Gast
Jörn schrieb:
> RTC_IRQHandler() scheint ein Sammelinterrupt zu sein. Mit deiner Zeile
> fragst du das Sekundenflag ab. Ist aber jetzt nur so geraten...

Ja schon, aber da ich nur den Sekunden-Interrupt aktiviert habe, sollte 
es keine Rolle spielen, ob ich das Flag teste, oder nicht.

Aus irgend einem Grund wird der IRH Handler scheinbar immer genau 
zweimal aufgerufen. Einmal wegen dem Sekunden-Flag und dann nochmal 
wegen <keine Ahnung>.
Gast
Auch wenn ich alle drei Flags lösche, wird der Interrupt doppelt 
aufgerufen:
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flags
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF + RTC_CRL_ALRF + RTC_CRL_OWF);
8
}

Es scheint noch eine vierte Quelle/Ursache für die Unterbrechungen zu 
geben.
Gast
noreply@noreply.com schrieb:
> Ich würde die Anzahl Interrupts mal vor dem if in einer globalen
> Variable zählen und ausgeben.

Guter Tipp. Habe ich gemacht:
1
void RTC_IRQHandler(void)
2
{
3
    static volatile uint8_t cnt=0;
4
    cnt++;
5

6
    // If the Interrupt came from the RTC
7
    if (READ_BIT(RTC->CRL,RTC_CRL_SECF + RTC_CRL_ALRF + RTC_CRL_OWF))
8
    {
9
        // Toggle LED
10
        GPIOA->ODR ^= GPIO_ODR_ODR5;
11

12
        // Clear interrupt flags
13
        CLEAR_BIT(RTC->CRL,RTC_CRL_SECF + RTC_CRL_ALRF + RTC_CRL_OWF);
14
    }
15
}

Das habe ich im Debugger ausgeführt, mit einem Watch auf die cnt 
Variable und einem Breakpoint auf der CLEAR_BIT Zeile. Sie wird so 
hochgezählt:

1,3,5,7,9,11,13,15,17, usw.
Gast
Ich mag es nicht, wenn ich ein Problem gelöst habe ohne die Lösung zu 
verstehen. Solche Sachen kommen oft irgendwann wieder hoch und bereiten 
dann ernsthafte Probleme.
Gast
Jetzt wird es interessant:

Das läuft gut:
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flags
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    // Toggle something else
10
    GPIOA->ODR ^= GPIO_ODR_ODR4;
11
}

Das läuft gut:
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle something else
4
    GPIOA->ODR ^= GPIO_ODR_ODR4;    
5

6
    // Clear interrupt flags
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    // Toggle LED
10
    GPIOA->ODR ^= GPIO_ODR_ODR5;
11
}

Das läuft gut:
1
void RTC_IRQHandler(void)
2
{
3
    // Clear interrupt flags
4
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
5

6
    // Toggle LED
7
    GPIOA->ODR ^= GPIO_ODR_ODR5;
8
}

Das funktioniert nicht (doppel-Interrupts):
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Toggle something else
7
    GPIOA->ODR ^= GPIO_ODR_ODR4;
8

9
    // Clear interrupt flags
10
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
11
}

Das funktioniert nicht (doppel-Interrupts):
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Toggle something else
7
    GPIOA->ODR ^= GPIO_ODR_ODR4;
8

9
    // Clear interrupt flags
10
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
11
}

Dann hat es in meinem Kopf "klick" gemacht. Die vermutlich saubere 
Lösung ist:
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flags
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    // Wait until last write operation is done
10
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
11
}
Gast
Einfaches Softwaredesign, das ich bei Interruptbearbeitung beachten 
würden.

Interrupt-Grund Abfragen
Interrupt-Grund Zurücksetzen
restliche Arbeit erledigen

Es gibt vielleicht auch noch Hinweise in der Dokumentation, wieviele 
Takte vergangen sein müssen, bis der Interrupt zuverlässig gelöscht 
wird. Aber man kann nur mit der Hardware arbeiten.
Gast
noreply@noreply.com schrieb:
> Interrupt-Grund Abfragen
> Interrupt-Grund Zurücksetzen
> restliche Arbeit erledigen

Meinst du so?:
1
void RTC_IRQHandler(void)
2
{
3
    // if a second has elapsed, then ...
4
    if (READ_BIT(RTC->CRL,RTC_CRL_SECF))
5
    {
6
        // Clear interrupt flag
7
        CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
        // Toggle LED
10
        GPIOA->ODR ^= GPIO_ODR_ODR5;
11
    }
12

13
    // Wait until last write operation is done
14
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
15
}
Gast
Hi, das Problem ist, dass nach dem Clear Interrupt direkt der return 
Befehl kommt. Da ist die Pipeline noch nicht fertig. Dann liegt der 
Request noch an und der Interrupt kommt nochmal. Wenn du sicher sein 
willst, schreibe ein ISB() dahinter. Dann ist es unabhängig von der 
Position.

Daran habe ich auch schon mal gerätselt.
Gast
Stefanus F. schrieb:
> // Wait until last write operation is done
>     while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}

Könnte sein, kann aber auch nur der Interruptverwaltung Zeit geben, sich 
ordentlich zurückzusetzen.

Man könnte auch eine statische Variable hochzählen.
Gast
Stefanus F. schrieb:
> noreply@noreply.com schrieb:
>
>
> Meinst du so?:
> void RTC_IRQHandler(void)
> {
 Interrupt-Grund Abfragen
>     // if a second has elapsed, then ...
>     if (READ_BIT(RTC->CRL,RTC_CRL_SECF))
>     {
 Interrupt-Grund Zurücksetzen
>         // Clear interrupt flag
>         CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
 restliche Arbeit erledigen
>         // Toggle LED
>         GPIOA->ODR ^= GPIO_ODR_ODR5;
>     }
nachfolgendes könnte nur zusätzliche Zyklen erzeugen,
die der Interrupt-Verwaltung Zeit geben, sich zurückzusetzen
siehe Beitrag von Martin. Der Einwand mit den Verarbeitungsstufen
der CPU hat was.
>     // Wait until last write operation is done
>     while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
> }

...
Gast
Meine Vorredner haben wohl recht, mit dem Zeitproblem.
Hier liegt das seltene Problem vor, dass im Interrupt keine Register 
gesichert und wieder restauriert werden müssen, weil die Hauptschleife 
leer ist, und der Compiler das wegoptimiert hat.
Lass mal irgendwas in der Hauptschleife machen, dann wird es sehr 
wahrscheinlich wie gewünscht laufen.
Gast
.                                                . schrieb im Beitrag 
#5757407:
> Hier liegt das seltene Problem vor, dass im Interrupt keine Register
> gesichert und wieder restauriert werden müssen, weil die Hauptschleife
> leer ist, und der Compiler das wegoptimiert hat.

Das klingt plausibel. Vor allem erklärt es, warum ich vorher noch nie 
auf den Fehler gestoßen bin. In den vorherigen Programmen hatten die ISR 
tatsächlich etwas mehr gemacht.

> Lass mal irgendwas in der Hauptschleife machen, dann wird es sehr
> wahrscheinlich wie gewünscht laufen.

Ich wüsste nicht, warum dadurch das Verhalten der ISR anders werden 
sollte.
Gast
Ok, das mit dem Zeitproblem habe ich schon mal gehört. Also bei 
Sammelinterrupts erst die Quelle abfragen, Flag löschen, dann was 
machen.
Aber warum klappt dann die Variante aus dem Eröffnungspost mit dem IF 
welches die Quelle ermittelt, aber ohne das IF geht es nicht? Obwohl 
danach jeweils die "ungünstige" Reihenfolge erst LED togglen dann Flag 
löschen kam...
Gast
Jörn schrieb:
> Aber warum klappt dann die Variante aus dem Eröffnungspost mit dem IF
> welches die Quelle ermittelt, aber ohne das IF geht es nicht?

Weil der if() Ausdruck sicher stellt, dass die LED nur getoggelt wird, 
wenn eine Sekunde verstrichen ist.

Der Fehler war zwar, dass die ISR doppelt aufgerufen wurde, bis dahin 
war das Sekunden-Flag aber asynchron zurück gesetzt.
Gast
Vielleicht 18.3.4@RM0008
1
In addition, writing to any RTC register is only enabled if the previous write operation is
2
finished. To enable the software to detect this situation, the RTOFF status bit is provided in
3
the RTC_CR register to indicate that an update of the registers is in progress. A new value
4
can be written to the RTC registers only when the RTOFF status bit value is ’1’.

Also mit
1
1. Poll RTOFF, wait until its value goes to ‘1’
2
...
verfahren?
Gast
Das Problem betrifft die Pipelines des Controllers, der Core ist 
schneller als der Speicher und die Peripherie. Ich habe mir pauschal 
angewöhnt erst die Flags zu löschen, dann etwas machen und danach ISR 
beenden.
(Firma: @home)
Stefanus F. schrieb:
> Hast du das obige Zitat aus dem Referenzhandbuch gesehen, wo genau dies
> empfohlen wird?

so, jetzt habe ich die details im reference hb nochmals gelesen und sehe 
keinen zusammenhang zu deinem mehrfach interrupt problem und

Beitrag "Re: stm32f103 RTC Interrupt öfter als erwartet"

da das interrupt flag reg nicht in der rtc domain liegt.

ich würde sogar eher ein isb() cmd setzen anstatt dsb/dsm?!

probier mal aus!

ich denke, dass while() funktioniert nur weil es als "delay" wirkt.


mt
Gast
Stefanus F. schrieb:
> Hast du das obige Zitat aus dem Referenzhandbuch gesehen, wo genau dies
> empfohlen wird?
>
>> Beitrag "Re: stm32f103 RTC Interrupt öfter als erwartet"

Ich würde mir nochmal das Referenzmanual genau durchlesen. Insbesondere 
18.3.4

Das Register RTC_CRH wurde hier nicht erwähnt.
Gast
Bei 8MHz reicht zo siemlich alles, was ein paar Takte verbraucht. Zum 
Beispiel zwei oder mehr NOP.
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flag
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    // Delay a little
10
    asm volatile ("NOP; NOP;");
11
}

Apollo M. schrieb:
> ich würde sogar eher ein isb() cmd setzen anstatt dsb/dsm?!
> probier mal aus!

isb(), dsb(), dsm() kennt der Compiler nicht, auch nicht in der 
Schreibweise __isb(). Ich habe es daher mit Assembler versucht:
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flag
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    // Flushes the pipeline
10
    asm volatile ("ISB");
11
}

Aber das klappt nur mit 8MHz Systemtakt. Bei 72MHz reicht das wieder 
nicht, da muss ich doch dies machen:
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flag
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    // Wait until last write operation is done
10
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
11
}

Ich denke, der Hinweis im Referenzhandbuch passt schon.
Gast
Stefanus F. schrieb:
> noreply@noreply.com schrieb:
>> Das Register RTC_CRH wurde hier nicht erwähnt.
>
> Doch, im Eröffnungspost. In diesem Register schalte ich den
> Sekunden-Interrupt ein.

Sorry. Ich meinte RTC_CRL

Verkürzt. RTOFF Abfragen macht nur Sinn in Verbindung der Register 
RTC_PRL, RTC_CNT und RTC_ALR. RTC_CRL ist normales Register im 
Addressbereich der CPU. Somit ist
    // Wait until last write operation is done
    while(!READ_BIT(RTC->CRL, RTC_CRL_RTOFF)) {}
nur eine Verzögerung.

18.3.4 Configuring RTC registers
To write in the RTC_PRL, RTC_CNT, RTC_ALR registers, the peripheral must 
enter
Configuration Mode. This is done by setting the CNF bit in the RTC_CRL 
register.
In addition, writing to any RTC register is only enabled if the previous 
write operation is
finished. To enable the software to detect this situation, the RTOFF 
status bit is provided in
the RTC_CR register to indicate that an update of the registers is in 
progress. A new value
can be written to the RTC registers only when the RTOFF status bit value 
is ’1’.
Configuration procedure
1. Poll RTOFF, wait until its value goes to ‘1’
2. Set the CNF bit to enter configuration mode
3. Write to one or more RTC registers
4. Clear the CNF bit to exit configuration mode
5. Poll RTOFF, wait until its value goes to ‘1’ to check the end of the 
write operation.
The write operation only executes when the CNF bit is cleared; it takes 
at least three
RTCCLK cycles to complete.
Gast
Warum pollen dann alle Tutorials RTC_CRL_RTOFF nach jedem Schreibzugriff 
auf RTC>CRL?

Die Beschreibung von RTOFF sagt:
If its value is ‘0’ then it is not possible to write to any
of the RTC registers.

Also nach meinem Verständnis ist RTC->CRL ein RTC Register, sonst würde 
es wohl kaum so heissen. Es ist auch Bestandteil der RTC Register Map.

Was mich ärgert: Es gibt für jeden Kack eine Application Note, nur dafür 
nicht. In den Quelltexten der HAL habe ich auch nichts passenden 
gefunden.
Beitrag #5758602 wurde von einem Moderator gelöscht.
Gast
Bei 72MHz brauche ich vier NOPs.
1
void RTC_IRQHandler(void)
2
{
3
    // Toggle LED
4
    GPIOA->ODR ^= GPIO_ODR_ODR5;
5

6
    // Clear interrupt flag
7
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
8

9
    asm volatile ("NOP; NOP; NOP; NOP;");
10
}

Oder zuerst das Flag löschen, geht auch.
1
void RTC_IRQHandler(void)
2
{
3
    // Clear interrupt flag
4
    CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
5

6
    // Toggle LED
7
    GPIOA->ODR ^= GPIO_ODR_ODR5;
8
}

Ich mache das jetzt so und schreibt noch einen kleinen Kommentar dazu, 
dass nach den Clear ein Paar Takte Verzögerung nötig sind.
Gast
Stefanus F. schrieb:
> Oder zuerst das Flag löschen, geht auch.void RTC_IRQHandler(void)
> {
>     // Clear interrupt flag
>     CLEAR_BIT(RTC->CRL,RTC_CRL_SECF);
>
>     // Toggle LED
>     GPIOA->ODR ^= GPIO_ODR_ODR5;
> }

Krass. Braucht das Togglen wirklich so lang, dass das schon reicht?
Togglen = 4 NOPS? Ich dachte der Registerzugriff fürs Togglen dauert 
einen Takt...
Gast
Jörn schrieb:
> Braucht das Togglen wirklich so lang, dass das schon reicht?
> Togglen = 4 NOPS? Ich dachte der Registerzugriff fürs Togglen dauert
> einen Takt...

Offensichtlich ja. Mit nur 3 NOPS funktioniert es (bei 72MHz) nicht.

Das ist der Assembler-Code von der Variante, wo ich erst das Flag lösche 
und dann die LED toggle:
1
 188                RTC_IRQHandler:
2
 189                  @ args = 0, pretend = 0, frame = 0
3
 190                  @ frame_needed = 0, uses_anonymous_args = 0
4
 191                  @ link register save eliminated.
5
 192 0000 0549         ldr  r1, .L34
6
 193 0002 064A         ldr  r2, .L34+4
7
 194 0004 4B68         ldr  r3, [r1, #4]
8
 195 0006 23F00103     bic  r3, r3, #1
9
 196 000a 4B60         str  r3, [r1, #4]
10
 197 000c D368         ldr  r3, [r2, #12]   <---- 2 Cycles
11
 198 000e 83F02003     eor  r3, r3, #32     <---- 1 Cyle
12
 199 0012 D360         str  r3, [r2, #12]   <---- 2 Cycles
13
 200 0014 7047         bx  lr

Ich hoffe ich habe die Anzahl der Zyklen richtig ermittelt.

> Ich dachte der Registerzugriff fürs Togglen dauert einen Takt...

Vielleicht verwechselst du das mit dem Setzen/Löschen von I/O Pins über 
das GPIOx->BSRR Register.
Gast
Apollo M. schrieb:
> ... das hat irgendwie was esoterisches.
> ich glaube das alles nicht wirklich, weil das ist mir zu
> undeterministisch und damit nicht logisch.
>
> ich werde mal irendwann meine hw in stellung bringen und rumspielen.

Ich sehe da nichts undeterministisches.

Nach dem Clearen des Interrupts Flags RTC_CRL_SECF muss die ISR noch 
mindestens 4 CPU Takte warten, bevor sie zurück kehrt. Andernfalls steht 
das Interrupt-Signal danach noch an, so dass die ISR erneut ausgeführt 
wird. Bei 8MHz genügen zwei CPU Takte.

Das Einzige, was mir dazu fehlt, ist der entsprechende Hinweis in der 
Doku des Herstellers.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.