C Strukturen

avr_newbie

Mitglied
13. Apr. 2013
127
0
16
Bayern
Sprachen
  1. ANSI C
hallo,

hab derzeit ein kleines Problem mit meiner Struktur.

Und zwar, wenn ich in die Struktur noch ein char[16] - Array pack, dann steigt der Controller aus.

Da die Struktur ziemlich groß ist - ist jetzt meine Frage, ist die Größe von einer Struktur begrenzt??

EDIT:

Bisher sind in der Struktur 11 floats und 16 uint16_t Variablen enthalten.
und ein array[8]

Es wird dann eine Stuktur array angelegt, , also

mein_struct meine_varaible[8] ;
 
Was hast Du für eine MCU? Reicht Dir der Speicher überhaupt aus?

Brauchst Du feste Länge vom char[]? Wenn nein, leg doch einfach ein Pointer an und allokiere erst dann den Speicher.

Brauchst Du so eine fette Struktur? Was willst Du überhaupt machen?
 
Was hast Du für eine MCU? Reicht Dir der Speicher überhaupt aus?

Brauchst Du feste Länge vom char[]? Wenn nein, leg doch einfach ein Pointer an und allokiere erst dann den Speicher.

Brauchst Du so eine fette Struktur? Was willst Du überhaupt machen?

ATmega2560

ich hab eine Struktur für den ADC angelegt.

also da werden sämtlich Variablen in der Struktur behandelt. von ADC-Wert, Kalibrierwert, name für ADC-Kanal usw....
Und das eben für 8 ADC-kanäle


>> leg doch einfach ein Pointer an und allokiere erst dann den Speicher
äh.. ja, wie macht man sowas? hab ich bis jetzt noch nie gebraucht ^^


EDIT:

Ich hab gemerkt, wenn ich einfach eine neue Struktur anlege, mit char[16] drin, dann steigt er auch aus.
Ich habe so eine Struktur schon mal angelegt, da hats auch funktioniert.....
packt das die MCU dann nicht?
 
Hallo.
Da die Struktur ziemlich groß ist - ist jetzt meine Frage, ist die Größe von einer Struktur begrenzt??

... nicht dass mir bekannt ist.

Ich könnte mir zwei Ursachen vorstellen:
(1) Es wird insgesamt zu viel Speicher belegt, so dass sich hier Speicherbereiche überlagern (-> Stack).
(2) Ein Zugriff auf ein Element der Struktur ist nicht richtig (zum Beispiel ist der Index für das Array zu groß)

Gibt der Compiler Warnings aus?

Was hast Du für eine MCU? Reicht Dir der Speicher überhaupt aus?

Brauchst Du feste Länge vom char[]? Wenn nein, leg doch einfach ein Pointer an und allokiere erst dann den Speicher.

Wenn es an der Größe liegt, wird dies das Problem nicht lösen, da ja eventuell die Größe des Arrays benötigt wird ... und dann ändert sich nichts.
 
Wie kann ich das sehen, ob zu viel Speicher belegt ist? Ich geh davon aus, dass das die Ursache ist.

Mit Zugriff kann das nichts zu tun haben, da ich nur die Struktur angelegt habe, sonst nichts.

EDIT:

keine Compilerwarnung

Program Memory Usage : 52976 bytes 20,2 % Full
Data Memory Usage : 8337 bytes 12,8 % Full

Hallo.


... nicht dass mir bekannt ist.

Ich könnte mir zwei Ursachen vorstellen:
(1) Es wird insgesamt zu viel Speicher belegt, so dass sich hier Speicherbereiche überlagern (-> Stack).
(2) Ein Zugriff auf ein Element der Struktur ist nicht richtig (zum Beispiel ist der Index für das Array zu groß)

Gibt der Compiler Warnings aus?



Wenn es an der Größe liegt, wird dies das Problem nicht lösen, da ja eventuell die Größe des Arrays benötigt wird ... und dann ändert sich nichts.
 
Noch ne andere Frage:

wenn ich 2 Strukturen habe,

dann darf ich doch in jeder Struktur eine Variable haben, die z.B. "EE_adr_str_unit" heißt? oder?
 
wenn ich 2 Strukturen habe,

dann darf ich doch in jeder Struktur eine Variable haben, die z.B. "EE_adr_str_unit" heißt? oder?

Du meinst die Namen der Elemente, ja, die dürfen gleich sein.

Falls du das Array innerhalb einer Funktion/Routine erstellst, erstelle es mal global, zum Beispiel so ...

Code:
struct meine_struct_s {

  type name1;
  ...

} meine_struct[8];

Es gibt schon mit Hilfsfunktionen die Möglichkeit zu ermitteln, wo der Speicherbereich liegt und wie groß er Stack wird. Da müsstest du aber vielleicht nochmal im Internet suchen, leider habe ich hier nichts parat.
 
Du meinst die Namen der Elemente, ja, die dürfen gleich sein.


Falls du das Array innerhalb einer Funktion/Routine erstellst, erstelle es mal global, zum Beispiel so ...

Code:
struct meine_struct_s {

  type name1;
  ...

} meine_struct[8];

Es gibt schon mit Hilfsfunktionen die Möglichkeit zu ermitteln, wo der Speicherbereich liegt und wie groß er Stack wird. Da müsstest du aber vielleicht nochmal im Internet suchen, leider habe ich hier nichts parat.



meine Strukturen sind bereits alle global in header Dateien definiert.

--------------------------
EDIT:

zum Beispiel so:
Code:
typedef struct
{
	
	char str_unit[16];	//unit
	uint16_t EE_adr_str_unit;

} __attribute__ ((packed)) struct_DO;

struct_DO DO[8] ;



-------------------------
Wie kann ich denn verhindern, dass der Stack überläuft?

bzw. noch eine andere Frage:

Ich habe viele Konstanten so z.B. definiert wie nachfolgendes Beispiel
LANG_COUNT = Sprachauswahl

Jetzt habe ich zum test auch mal von dieser const ein paar dummy Konstanten erstellt, auch in dieser Größe wie folgend angehängt ....
kompiliert, und aufn Atmega ..... und dann hab ich schnell wieder ausgeschaltet, da ich dachte, mir schiessts gleich das Display weg ;)
:confused:



Code:
const char msg_ADC_cal_state[LANG_COUNT][17][35] =
{	{
	{"Eingang setzen                "},//1
	{"ADC Messung läuft             "},//2
	{"Kalibrierung überprüfen       "},//3
	{"ADC-Wert in Variable schreiben"},//4
	{"ADC-Wert in EEPROM schreiben  "},//5
	{"Berechnung m für Einheit      "},//6
	{"m-Einheit in EEPROM schreiben "},//7
	{"Berechnung t für Einheit      "},//8
	{"t-Einheit in EEPROM schreiben "},//9
	{"Berechnung m für mA/V         "},//10
	{"m-mA/V in EEPROM schreiben    "},//11
	{"Berechnung t für mA/V         "},//12
	{"t-mA/V in EEPROM schreiben    "},//13
	{"Kalibrierung beendet          "},//14
	{"Fehler bei der Kalibrierung   "},//failure 
	{"Kalibrierung Untergrenze      "},//failure underrange
	{"Kalibrierung Obergrenze       "}},//failure overrange
	
	{
	{"Set Input                     "},//1
	{"ADC measurement run           "},//2
	{"Check calibration             "},//3
	{"Write ADC value in variable   "},//4
	{"Write ADC value in EEPROM     "},//5
	{"Calculation m for unit        "},//6
	{"Write m of unit in EEPROM     "},//7
	{"Calculation t for unit        "},//8
	{"Write t of unit in EEPROM     "},//9
	{"Calculation m for mA/V        "},//10
	{"Write m of mA/V in EEPROM     "},//11
	{"Calculation t for mA/V        "},//12
	{"Write t of mA/V in EEPROM     "},//13
	{"Calibration finished          "},//14
	{"Failure at Calibration        "},//failure
	{"Calibration underrange        "},//failure underrange
	{"Calibration overrange         "}},//failure overrange
	
};
 
Das solltest du bei einem Mikrocontroller mit wenig SRAM nicht ins SRAM legen. :)

Lege diese Sachen in das Flash memory. Das geht mit "PROGMEM". Du kannst mal im Forum suchen, ich hatte hier schon mehrmals was dazu geschrieben. Im Moment habe ich leider keine Zeit, wenn du nicht klar kommst, kann ich ja vielleicht nochmal ein Beispiel dazu bringen.
 
Das solltest du bei einem Mikrocontroller mit wenig SRAM nicht ins SRAM legen. :)

Lege diese Sachen in das Flash memory. Das geht mit "PROGMEM". Du kannst mal im Forum suchen, ich hatte hier schon mehrmals was dazu geschrieben. Im Moment habe ich leider keine Zeit, wenn du nicht klar kommst, kann ich ja vielleicht nochmal ein Beispiel dazu bringen.

Also d. h. wenn ichs in flash lege, dann hab ich evtl. das Problem nicht mehr? ^^

EDIT:

Der Stack liegt auch im SRAM, oder?
 
Hi,

EDIT:

Der Stack liegt auch im SRAM, oder?
alles was sich verändern muß (Stack, Variablen, ...) liegen zwangsweise im SRAM.
Alles was konstant bleibt und nicht verändert werden muß sollte man auf jeden Fall ins Flash legen.
Das ist aber bei allen Sprachen so.

Gruß
Dino
 
Also d. h. wenn ichs in flash lege, dann hab ich evtl. das Problem nicht mehr? ^^

Der Stack liegt auch im SRAM, oder?

Ja, möglicherweise ist dann das Problem beseitigt. Solche Tabellen solltest du im Flash Memory anlegen. SRAM ist nicht so viel vorhanden und das kann dann schon mal eng im SRAM werden.


Der Stack liegt im SRAM (hat ja Dino schon geschrieben). Dieser baut sich vom Ram-Ende her auf. Wenn hier der Inhalt durch den Datenbereich überschrieben wird, geht das dann in der Regel nicht gut aus ;)
 
im header mit PROGMEM - das leuchtet ein....
Code:
extern const char msg_test[LANG_COUNT][35]	PROGMEM	;

in c-datei

ist das richtig, dass ich nur in der header datei das PROGMEM benutzen muss?
bei der definition ist es nicht mehr notwendig?

Code:
const char msg_test[LANG_COUNT][35]			= {"Menü 1 - Analog Digital Converter    "		, "Menu 1 - Analog Digital Converter"};






und ist das hier so richtig:

Oder belaste ich zwangsläufig so auch wieder den RAM ?


hier meine Funktion, damit automatisch die richtigen Sprachabhängigen Texte gewählt werden:
Code:
char* Display_msg_35_F(const char p[][35])
{
	return(( char *) p[user_Language]);
}


Displayausgabe:
Code:
Display_DisplayText_F(0,0,Display_msg_35_F(msg_test));
 
Schade, dass hier anscheinend sonst keiner helfen kann. :(

Du kannst es zum Beispiel so machen:


In einem .c File LanguageText.c
Code:
// ...
#include <avr/pgmspace.h>
#include "LanguageText.h"
// ...

#define LANG_COUNT    2

const char msg_ADC_cal_state[LANG_COUNT][17][35] PROGMEM =
{    {
    {"Eingang setzen                "},//1
    {"ADC Messung läuft             "},//2
    {"Kalibrierung überprüfen       "},//3
    {"ADC-Wert in Variable schreiben"},//4
    {"ADC-Wert in EEPROM schreiben  "},//5
    {"Berechnung m für Einheit      "},//6
    {"m-Einheit in EEPROM schreiben "},//7
    {"Berechnung t für Einheit      "},//8
    {"t-Einheit in EEPROM schreiben "},//9
    {"Berechnung m für mA/V         "},//10
    {"m-mA/V in EEPROM schreiben    "},//11
    {"Berechnung t für mA/V         "},//12
    {"t-mA/V in EEPROM schreiben    "},//13
    {"Kalibrierung beendet          "},//14
    {"Fehler bei der Kalibrierung   "},//failure
    {"Kalibrierung Untergrenze      "},//failure underrange
    {"Kalibrierung Obergrenze       "}},//failure overrange
    
    {
    {"Set Input                     "},//1
    {"ADC measurement run           "},//2
    {"Check calibration             "},//3
    {"Write ADC value in variable   "},//4
    {"Write ADC value in EEPROM     "},//5
    {"Calculation m for unit        "},//6
    {"Write m of unit in EEPROM     "},//7
    {"Calculation t for unit        "},//8
    {"Write t of unit in EEPROM     "},//9
    {"Calculation m for mA/V        "},//10
    {"Write m of mA/V in EEPROM     "},//11
    {"Calculation t for mA/V        "},//12
    {"Write t of mA/V in EEPROM     "},//13
    {"Calibration finished          "},//14
    {"Failure at Calibration        "},//failure
    {"Calibration underrange        "},//failure underrange
    {"Calibration overrange         "}},//failure overrange
        
    };

In das selbe .c File dann noch:
Code:
void DisplayLanguageText(uint16_t x, uint16_t y, uint8_t index, uint8_t language)
{
    
    char *ptr;
    
    ptr =  &msg_ADC_cal_state[language][index][0];  // language und index solltest du zuvor eingrenzen
    
    Display_DisplayText_F(x, y, ptr);
        
}

Das zugehörige Header-File LanguageText.h ...
Code:
#define EN            1
#define DE            0

void DisplayLanguageText(uint16_t x, uint16_t y, uint8_t index, uint8_t language);


Aufruf dann so:

Code:
//...
#include "LanguageText.h"
//..


    DisplayLanguageText(5, 25, 2, EN);
    
    DisplayLanguageText(5, 55, 2, DE);

Ausgabe auf dem Display ...
Check calibration
Kalibrierung überprüfen
 
Schade, dass hier anscheinend sonst keiner helfen kann. :(

Du kannst es zum Beispiel so machen:


In einem .c File LanguageText.c
Code:
// ...
#include <avr/pgmspace.h>
#include "LanguageText.h"
// ...

#define LANG_COUNT    2

const char msg_ADC_cal_state[LANG_COUNT][17][35] PROGMEM =
{    {
    {"Eingang setzen                "},//1
    {"ADC Messung läuft             "},//2
    {"Kalibrierung überprüfen       "},//3
    {"ADC-Wert in Variable schreiben"},//4
    {"ADC-Wert in EEPROM schreiben  "},//5
    {"Berechnung m für Einheit      "},//6
    {"m-Einheit in EEPROM schreiben "},//7
    {"Berechnung t für Einheit      "},//8
    {"t-Einheit in EEPROM schreiben "},//9
    {"Berechnung m für mA/V         "},//10
    {"m-mA/V in EEPROM schreiben    "},//11
    {"Berechnung t für mA/V         "},//12
    {"t-mA/V in EEPROM schreiben    "},//13
    {"Kalibrierung beendet          "},//14
    {"Fehler bei der Kalibrierung   "},//failure
    {"Kalibrierung Untergrenze      "},//failure underrange
    {"Kalibrierung Obergrenze       "}},//failure overrange
    
    {
    {"Set Input                     "},//1
    {"ADC measurement run           "},//2
    {"Check calibration             "},//3
    {"Write ADC value in variable   "},//4
    {"Write ADC value in EEPROM     "},//5
    {"Calculation m for unit        "},//6
    {"Write m of unit in EEPROM     "},//7
    {"Calculation t for unit        "},//8
    {"Write t of unit in EEPROM     "},//9
    {"Calculation m for mA/V        "},//10
    {"Write m of mA/V in EEPROM     "},//11
    {"Calculation t for mA/V        "},//12
    {"Write t of mA/V in EEPROM     "},//13
    {"Calibration finished          "},//14
    {"Failure at Calibration        "},//failure
    {"Calibration underrange        "},//failure underrange
    {"Calibration overrange         "}},//failure overrange
        
    };

In das selbe .c File dann noch:
Code:
void DisplayLanguageText(uint16_t x, uint16_t y, uint8_t index, uint8_t language)
{
    
    char *ptr;
    
    ptr =  &msg_ADC_cal_state[language][index][0];  // language und index solltest du zuvor eingrenzen
    
    Display_DisplayText_F(x, y, ptr);
        
}

Das zugehörige Header-File LanguageText.h ...
Code:
#define EN            1
#define DE            0

void DisplayLanguageText(uint16_t x, uint16_t y, uint8_t index, uint8_t language);


Aufruf dann so:

Code:
//...
#include "LanguageText.h"
//..


    DisplayLanguageText(5, 25, 2, EN);
    
    DisplayLanguageText(5, 55, 2, DE);

Ausgabe auf dem Display ...


Danke für das Beispiel.....

Das das so auch geht, war mir eigentlich schon auch klar...

nur wollte ich wissen, ob ich wie im vorherigem Posting das so machen kann....

bzw. muss ich die Konstante in der C-File mit PROGMEM definieren?


----------------------------------------------------------------------------------------------
so gehts nicht,oder? - also es geht zwar zu kompilieren, aber ob es im flash wandert, weiß ich nicht.....

im header:
Code:
 extern const char msg_test[LANG_COUNT][35]	[B]PROGMEM	[/B];

im c-file:
Code:
const char msg_test[LANG_COUNT][35]			= {"Menü 1 - Analog Digital Converter    "		, "Menu 1 - Analog Digital Converter"};

----------------------------------------------------------------------------------------------
dagegen so, gibt es eine warnung vom compilier:

im header:
Code:
 extern const char msg_test[LANG_COUNT][35]	[B]PROGMEM	[/B];

im c-file auch mit PROGMEM :
Code:
const char msg_test[LANG_COUNT][35]	[B]PROGMEM		[/B]= {"Menü 1 - Analog Digital Converter    "		, "Menu 1 - Analog Digital Converter"};
 
Danke für das Beispiel.....

Das das so auch geht, war mir eigentlich schon auch klar...

nur wollte ich wissen, ob ich wie im vorherigem Posting das so machen kann....

bzw. muss ich die Konstante in der C-File mit PROGMEM definieren?
Ja, dann wird die String-Tabelle im Flash angelegt.
Die Tabelle im C-File definieren, nicht im Header-File. Wenn du das header-File mehrfach einbindest, gibts Fehler, da ja die Tabelle mehrfach definiert wird.

so gehts nicht,oder? - also es geht zwar zu kompilieren, aber ob es im flash wandert, weiß ich nicht.....

im header:
Code:
 extern const char msg_test[LANG_COUNT][35]    [B]PROGMEM    [/B];

im c-file:
Code:
const char msg_test[LANG_COUNT][35]            = {"Menü 1 - Analog Digital Converter    "        , "Menu 1 - Analog Digital Converter"};
Nein, so gehts nicht.

dagegen so, gibt es eine warnung vom compilier:

im header:
Code:
 extern const char msg_test[LANG_COUNT][35]    [B]PROGMEM    [/B];

im c-file auch mit PROGMEM :
Code:
const char msg_test[LANG_COUNT][35]    [B]PROGMEM        [/B]= {"Menü 1 - Analog Digital Converter    "        , "Menu 1 - Analog Digital Converter"};

Du möchtest, dass die Tabelle global bekannt ist, da du diese im Header mit extern deklarierst. Ich würde die Tabelle einfach in einem C-File definieren (also privat), andere Programmteile müssen die Tabelle nicht kennen. Danach noch in das C-File eine kleine Funktion einfügen (und deren Prototyp im Headerfile bekannt geben) ... so wie in meinem Beispiel.
 
Ja, dann wird die String-Tabelle im Flash angelegt.
Die Tabelle im C-File definieren, nicht im Header-File. Wenn du das header-File mehrfach einbindest, gibts Fehler, da ja die Tabelle mehrfach definiert wird.


Nein, so gehts nicht.



Du möchtest, dass die Tabelle global bekannt ist, da du diese im Header mit extern deklarierst. Ich würde die Tabelle einfach in einem C-File definieren (also privat), andere Programmteile müssen die Tabelle nicht kennen. Danach noch in das C-File eine kleine Funktion einfügen (und deren Prototyp im Headerfile bekannt geben) ... so wie in meinem Beispiel.



sorry, dass ich nerv, aber das is jetzt wirklich das letzte mal zu diesem thema....

ich hätte es gernde trotzdem global definiert, da ich ja nicht nur eine Tabelle hab.
sonst müsste ich ja, so wie du es gemacht hast, für jede Tabelle eine funktion schreiben, also quasi jedes mal eine DisplayLanguageText-Funktion für jede Tabelle....


und jetzt nochmal zum Verständis - Antwort ja oder nein genügt:

kann ich das jetzt so machen ?

es wird nur im header das PROGMEM verwendet. In der c-file brauch ich dann das PROGMEM nicht mehr. Im folgendem Beispiel wirds auch im Flash angelegt?

im header:
Code:
 extern const char msg_test[LANG_COUNT][35]	[B]PROGMEM	[/B];

im c-file
Code:
const char msg_test[LANG_COUNT][35]	= {"Menü 1 - Analog Digital Converter    "		, "Menu 1 - Analog Digital Converter"};
 
sorry, dass ich nerv, aber das is jetzt wirklich das letzte mal zu diesem thema....

ich hätte es gernde trotzdem global definiert, da ich ja nicht nur eine Tabelle hab.
sonst müsste ich ja, so wie du es gemacht hast, für jede Tabelle eine funktion schreiben, also quasi jedes mal eine DisplayLanguageText-Funktion für jede Tabelle....
:D Du "nervst" nicht ;)
und jetzt nochmal zum Verständis - Antwort ja oder nein genügt:

kann ich das jetzt so machen ?

es wird nur im header das PROGMEM verwendet. In der c-file brauch ich dann das PROGMEM nicht mehr. Im folgendem Beispiel wirds auch im Flash angelegt?

im header:
Code:
 extern const char msg_test[LANG_COUNT][35]    [B]PROGMEM    [/B];

im c-file
Code:
const char msg_test[LANG_COUNT][35]    = {"Menü 1 - Analog Digital Converter    "        , "Menu 1 - Analog Digital Converter"};

Nein. Ich denke nicht, dass es so geht. Die Tabelle im C-File wird sicher im SRAM angelegt. Der Compiler müsste hier eigentlich auch ein Warning oder Error melden (kann ich jetzt nicht austesten) ?! Ich bin mir da aber jetzt auch nicht hundertprozentig sicher. Probiere es doch einfach mal aus.

Aber: Du kannst es doch trotzdem mit einer Funktion machen, indem du noch einen weiteren Parameter übergibst und in der Funktion dann durch diesen mit einem switch oder if-else die Strings aus einer entprechenden Tabelle holst. So könntest du alle Sprachelemente in einem C-File erstellen und hättest alles modular. Das wäre eventuell auch besser wartbarer ... ist aber natürlich "Geschmacksache".

Dirk :ciao:
 
ok, wenn ichs so mach, meckert er nicht, habs testweise alle tabellen so umgestellt (also globale variante von mir), und hab ne große struktur zum test angelegt. Das Programm bleibt jetzt nicht mehr stehn, wie vorher..... scheint trotzdem zu klappen.. :confused::confused: :D

trotzdem werde ich mir nochmal überlegen, ob ich nicht doch nach deiner variante vorgehe.... mit switch-case dann quasi zu filtern hatte ich mir auch schon überlegt....



noch ne kleine frage...
mein compiler zeigt jetzt z.B. nach compiliern an:

Program Memory Usage : 49670 bytes 18,9 % Full
Data Memory Usage : 2853 bytes 4,4 % Full


Program Memory Usage = ?
Data Memory Usage ?

ist da jetzt eins von beiden der flash dabei?
 
Program Memory Usage ist das Flash Memory, du hast also 49670 bytes belegt.

Data Memory Usage ist der belegte Speicherplatz im SRAM für Variablen, die in der Compile-Zeit zugeordnet werden (auch konstante Strings). Hier ist nicht der Stack enthalten. Warum bei dir 4,4% angezeigt wird, weiß ich nicht, das müssten dann eher 44% sein? (Diese Angaben werden vom Make-File erstellt)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)