ATmega328P Funktionsadresse in Register speichern und aufrufen

#7663100
Lesenswert?

Hallo, ich bins...

Ich brauche für die Solaranlage eine Steuerung mit CAN und RS485.

Kann mir bitte einer sagen, was da nicht stimmt? Ich habe schon die ganze Nacht gesucht. Leider sind da in dem Quelltext von dem TCB_t und ListItem_t so viele #ifdef dass ich nicht weiß, wie ich aus einem StackType_t * ein TCB_t bekomme.

1
typedef uint16_t StackType_t;
2
typedef void(*TaskFunction_t)(void*);
3
//#define portFLAGS_INT_ENABLED    ( ( StackType_t ) 0x00 )
4
#define portFLAGS_INT_ENABLED    ( ( StackType_t ) 0x80 )
5
#define PRIVILEGED_DATA
6

7
typedef void TCB_t;
8
extern volatile TCB_t * volatile pxCurrentTCB;
9
PRIVILEGED_DATA volatile TCB_t * volatile pxCurrentTCB = NULL;
10

11
/*
12
 * See header file for description.
13
 */
14
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
15
                                     TaskFunction_t pxCode,
16
                                     void * pvParameters )
17
{
18
uint16_t usAddress;
19

20
    /* Simulate how the stack would look after a call to vPortYield() generated by
21
     * the compiler. */
22

23
    /* The start of the task code will be popped off the stack last, so place
24
     * it on first. */
25
    usAddress = ( uint16_t ) pxCode;
26
    *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
27
    pxTopOfStack--;
28

29
    usAddress >>= 8;
30
    *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
31
    pxTopOfStack--;
32

33
#if defined(__AVR_3_BYTE_PC__)
34

35
    /* The AVR ATmega2560/ATmega2561 have 256KBytes of program memory and a 17-bit
36
     * program counter. When a code address is stored on the stack, it takes 3 bytes
37
     * instead of 2 for the other ATmega* chips.
38
     *
39
     * Store 0 as the top byte since we force all task routines to the bottom 128K
40
     * of flash. We do this by using the .lowtext label in the linker script.
41
     *
42
     * In order to do this properly, we would need to get a full 3-byte pointer to
43
     * pxCode. That requires a change to GCC. Not likely to happen any time soon.
44
     */
45
    *pxTopOfStack = 0;
46
    pxTopOfStack--;
47
#endif
48

49
    /* Next simulate the stack as if after a call to portSAVE_CONTEXT().
50
     * portSAVE_CONTEXT places the flags on the stack immediately after r0
51
     * to ensure the interrupts get disabled as soon as possible, and so ensuring
52
     *  the stack use is minimal should a context switch interrupt occur. */
53
    *pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
54
    pxTopOfStack--;
55
    *pxTopOfStack = portFLAGS_INT_ENABLED;
56
    pxTopOfStack--;
57

58
#if defined(__AVR_3_BYTE_PC__)
59

60
    /* If we have an ATmega256x, we are also saving the EIND register.
61
     * We should default to 0.
62
     */
63
    *pxTopOfStack = ( StackType_t ) 0x00;    /* EIND */
64
    pxTopOfStack--;
65
#endif
66

67
#if defined(__AVR_HAVE_RAMPZ__)
68

69
    /* We are saving the RAMPZ register.
70
     * We should default to 0.
71
     */
72
    *pxTopOfStack = ( StackType_t ) 0x00;    /* RAMPZ */
73
    pxTopOfStack--;
74
#endif
75

76
    /* Now the remaining registers. The compiler expects R1 to be 0. */
77
    *pxTopOfStack = ( StackType_t ) 0x00;    /* R1 */
78

79
    /* Leave R2 - R23 untouched */
80
    pxTopOfStack -= 23;
81

82
    /* Place the parameter on the stack in the expected location. */
83
    usAddress = ( uint16_t ) pvParameters;
84
    *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
85
    pxTopOfStack--;
86

87
    usAddress >>= 8;
88
    *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
89

90
    /* Leave register R26 - R31 untouched */
91
    pxTopOfStack -= 7;
92

93
    return pxTopOfStack;
94
}
95

96

97
#define portRESTORE_CONTEXT()                                                           \
98
        __asm__ __volatile__ (  "lds    r26, pxCurrentTCB                       \n\t"   \
99
                                "lds    r27, pxCurrentTCB + 1                   \n\t"   \
100
                                "ld     r28, x+                                 \n\t"   \
101
                                "out    __SP_L__, r28                           \n\t"   \
102
                                "ld     r29, x+                                 \n\t"   \
103
                                "out    __SP_H__, r29                           \n\t"   \
104
                                "pop    r31                                     \n\t"   \
105
                                "pop    r30                                     \n\t"   \
106
                                "pop    r29                                     \n\t"   \
107
                                "pop    r28                                     \n\t"   \
108
                                "pop    r27                                     \n\t"   \
109
                                "pop    r26                                     \n\t"   \
110
                                "pop    r25                                     \n\t"   \
111
                                "pop    r24                                     \n\t"   \
112
                                "pop    r23                                     \n\t"   \
113
                                "pop    r22                                     \n\t"   \
114
                                "pop    r21                                     \n\t"   \
115
                                "pop    r20                                     \n\t"   \
116
                                "pop    r19                                     \n\t"   \
117
                                "pop    r18                                     \n\t"   \
118
                                "pop    r17                                     \n\t"   \
119
                                "pop    r16                                     \n\t"   \
120
                                "pop    r15                                     \n\t"   \
121
                                "pop    r14                                     \n\t"   \
122
                                "pop    r13                                     \n\t"   \
123
                                "pop    r12                                     \n\t"   \
124
                                "pop    r11                                     \n\t"   \
125
                                "pop    r10                                     \n\t"   \
126
                                "pop    r9                                      \n\t"   \
127
                                "pop    r8                                      \n\t"   \
128
                                "pop    r7                                      \n\t"   \
129
                                "pop    r6                                      \n\t"   \
130
                                "pop    r5                                      \n\t"   \
131
                                "pop    r4                                      \n\t"   \
132
                                "pop    r3                                      \n\t"   \
133
                                "pop    r2                                      \n\t"   \
134
                                "pop    __zero_reg__                            \n\t"   \
135
                                "pop    __tmp_reg__                             \n\t"   \
136
                                "out    __SREG__, __tmp_reg__                   \n\t"   \
137
                                "pop    __tmp_reg__                             \n\t"   \
138
                             );
139

140
void callback(void *args){
141
  digitalWrite(LED_BUILTIN, HIGH);
142
  while(1);
143
}
144

145
void setup() {
146

147
  //extern int __heap_start,*__brkval;
148
  Serial.begin(115200); // open the serial port at 9600 bps:
149
  while(!Serial){}
150

151
  pinMode(LED_BUILTIN, OUTPUT);
152

153
pxCurrentTCB = pxPortInitialiseStack(0x4F5,callback,0);
154

155

156
  portRESTORE_CONTEXT();
157
  asm volatile ( "ret" );
158

159
}
#7663101
Lesenswert?

Matthias schrieb:

Hallo, ich bins...

Ich brauche für die Solaranlage eine Steuerung mit CAN und RS485.

Kann mir bitte einer sagen, was da nicht stimmt?

Du hast die Netiquette nicht beachtet, längere Quelltexte gehören in den Anhang.

Ich habe schon die ganze Nacht gesucht. Leider sind da in dem Quelltext von dem TCB_t und ListItem_t so viele #ifdef dass ich nicht weiß, wie ich aus einem StackType_t * ein TCB_t bekomme.

Ich auch nicht. Aber für bissel CAN und Solaranlage scheint das hier eine verdammt aufgeblähte Lösung zu sein.

#7663109
Lesenswert?

Ja, mei, wie es halt immer ausartet...

Ich glaube, nach

1
portSAVE_CONTEXT();
2
portRESTORE_CONTEXT();

ist das Programm richtig weitergelaufen.

1
#define portSAVE_CONTEXT()                                                              \
2
        __asm__ __volatile__ (  "push   __tmp_reg__                             \n\t"   \
3
                                "in     __tmp_reg__, __SREG__                   \n\t"   \
4
                                "cli                                            \n\t"   \
5
                                "push   __tmp_reg__                             \n\t"   \
6
                                "push   __zero_reg__                            \n\t"   \
7
                                "clr    __zero_reg__                            \n\t"   \
8
                                "push   r2                                      \n\t"   \
9
                                "push   r3                                      \n\t"   \
10
                                "push   r4                                      \n\t"   \
11
                                "push   r5                                      \n\t"   \
12
                                "push   r6                                      \n\t"   \
13
                                "push   r7                                      \n\t"   \
14
                                "push   r8                                      \n\t"   \
15
                                "push   r9                                      \n\t"   \
16
                                "push   r10                                     \n\t"   \
17
                                "push   r11                                     \n\t"   \
18
                                "push   r12                                     \n\t"   \
19
                                "push   r13                                     \n\t"   \
20
                                "push   r14                                     \n\t"   \
21
                                "push   r15                                     \n\t"   \
22
                                "push   r16                                     \n\t"   \
23
                                "push   r17                                     \n\t"   \
24
                                "push   r18                                     \n\t"   \
25
                                "push   r19                                     \n\t"   \
26
                                "push   r20                                     \n\t"   \
27
                                "push   r21                                     \n\t"   \
28
                                "push   r22                                     \n\t"   \
29
                                "push   r23                                     \n\t"   \
30
                                "push   r24                                     \n\t"   \
31
                                "push   r25                                     \n\t"   \
32
                                "push   r26                                     \n\t"   \
33
                                "push   r27                                     \n\t"   \
34
                                "push   r28                                     \n\t"   \
35
                                "push   r29                                     \n\t"   \
36
                                "push   r30                                     \n\t"   \
37
                                "push   r31                                     \n\t"   \
38
                                "lds    r26, pxCurrentTCB                       \n\t"   \
39
                                "lds    r27, pxCurrentTCB + 1                   \n\t"   \
40
                                "in     __tmp_reg__, __SP_L__                   \n\t"   \
41
                                "st     x+, __tmp_reg__                         \n\t"   \
42
                                "in     __tmp_reg__, __SP_H__                   \n\t"   \
43
                                "st     x+, __tmp_reg__                         \n\t"   \
44
                             );

Speichert denn die portSAVE_CONTEXT() mehr als nur die 32 Register?

Der Stack muss wegen dem uint16_t[] wahrscheinlich auf einer geraden Adresse liegen? Also eher so?

1
pxPortInitialiseStack(0x4F0,callback,0);
#7663136
Lesenswert?

Der Wechselrichter läuft seit einem Jahr ohne Fehler. Problem ist der Batteriespeicher, da kommen ständig Fehlermeldungen wegen der Temperatur und Spannung. Ich hab da an dem BMS schon einen Monat rumgestellt und es dann aufgegeben. Da braucht es je nach Temperatur und Jahreszeit unterschiedliche MinSOC, MaxSOC und Ladestrom, was das BMS und WR nicht kann.

Also Stromverbrauch-/Einspeisemesswerte lesen (RS485), BMS lesen (CAN), Batterie-WR schreiben (Batterieladezustand CAN) (Ladeleistung RS485).

Ohne Multitasking wird es arg kompliziert, wenn da irgendwas hängen bleibt.

Die Schnipsel sind vom FreeRTOS (https://github.com/feilipu/Arduino_FreeRTOS_Library/blob/master/src/port.c), aber wenn ich das aufspiele ist der Speicher voll.

#7663153
Lesenswert?

Matthias schrieb:

Also Stromverbrauch-/Einspeisemesswerte lesen (RS485), BMS lesen (CAN), Batterie-WR schreiben (Batterieladezustand CAN) (Ladeleistung RS485).

Ohne Multitasking wird es arg kompliziert,

Also zwei Messwert(sätz)e lesen und anschließend beide ans BMS-Schreiben? Was ist da so arg kompliziert ohne Multitasking? Wie oft muß das überhaupt passieren, 1/s oder 1/µs?

wenn da irgendwas hängen bleibt.

Meinst Du beim Lesen? Timeout abwarten? k.A. was die sinnvollste Aktion ist, wenn Dir ein Eingabewert fehlt, aber dagegen hilft Dir auch Multitasking nichts, im Gegenteil läufst Du eher Gefahr, nichts mitzubekommen wenn einer der Lese-Tasks dauerhaft hängt und keine Updates liefert.

#7663164
Lesenswert?

Matthias schrieb:

Ohne Multitasking wird es arg kompliziert, wenn da irgendwas hängen bleibt.

Mit MT bleibt es vielleicht noch öfter hängen, wenn man da kein Profi ist.

Ich weiß allerdings nicht genau, wo das Problem liegt. Was soll wo hängen und warum?

Läuft doch alles mit einem Mess-/Aktionstakt > 10 Sekunden, oder? Wenn eine CAN- oder RS-485-Funktion hängt, kann man das mit einem Watchdog-Timer abfangen. Danach kann man dann eine Ersatzfunktion aufrufen (z. B. das Interface zurücksetzen) und die Aktion beim nächsten Durchlauf erneut versuchen. Bei einer Dauerstörung der Hardware hilft dir MT auch nicht.

#7663170
Lesenswert?

Veit D. schrieb:

TCB_t ist ein struct Datentyp der neueren Controller Serien. Ein ATmega328P hat keine Timer des Typs TCB (oder TCA, TCD) oder dergleichen.

Der hat vor allem kein CAN…

@TO Der hat auch keinen 3-Byte-PC. Vielleicht hilft das ja weiter. Wobei die Antwort auf die Frage vermutlich „gar nicht“ lautet, und ansonsten RTFM des unbekannten RTOS.

Oliver

#7663172
Lesenswert?

Okay, ich versuche mich durch die Instruction Set der CPU zu wühlen (https://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf).

Wäre ja eine Schande, wenn es nicht klappt, die paar Register aus dem SRAM zu laden und speichern...

Ist SREG ein Teil von R0-R31? Muss ich die I/O Register beim Taskwechsel auch speichern?

https://i.stack.imgur.com/NWBNO.png

(Firma: Gast) #7663179
Lesenswert?

Veit D. schrieb:

also wenn ich TCB_t und ATmega328P lese, dann sagt mir meine innere Stimme das was nicht zusammenpasst oder zusammengewürfelt wurde.

TCB soll wohl TaskControlBlock heißen. Hat also nix mit Timern zu tun. oder nur um 12 Ecken.

Matthias schrieb:

Wäre ja eine Schande, wenn es nicht klappt, die paar Register aus dem SRAM zu laden und speichern...

Was willst du erreichen? Was willst du "wirklich" erreichen?

Und ja, dass du gerade am Ende einer Sackgasse angekommen bist, und vor einer Wand stehst, hat hier (fast) jeder begriffen.

Die Frage ist daher, wo isser falsch abgebogen um da zu landen.

#7663181
Lesenswert?

Matthias schrieb:

Ohne Multitasking wird es arg kompliziert, wenn da irgendwas hängen bleibt.

Kann man deutlich einfacher kooperativ gestalten. Das Rad "neu" in eckig zu erfinden, weil man mal zum Bäcker fahren will, ist Unsinn.

Die Schnipsel sind vom FreeRTOS (https://github.com/feilipu/Arduino_FreeRTOS_Library/blob/master/src/port.c), aber wenn ich das aufspiele ist der Speicher voll.

Es gibt mehr als genug "Arduinos" mit tonnenweise Speicher, ESP32, RPpico etc. Und für das bissel Klim Bim allemal.

#7663182
Lesenswert?

Matthias schrieb:

Okay, ich versuche mich durch die Instruction Set der CPU zu wühlen (https://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf).

UM ein bisselö auf dem CAN Bus Daten zu verschicken, schnon klar . . .

Wäre ja eine Schande, wenn es nicht klappt, die paar Register aus dem SRAM zu laden und speichern...

Ist SREG ein Teil von R0-R31?

Nö, das SREG liegt im IO-Bereich. Klingt komisch, ist aber so.

Muss ich die I/O Register beim Taskwechsel auch speichern?

Nö.

#7663193
Lesenswert?

Veit D. schrieb:

Arduino F. schrieb:

Veit D. schrieb:

also wenn ich TCB_t und ATmega328P lese, dann sagt mir meine innere Stimme das was nicht zusammenpasst oder zusammengewürfelt wurde.

TCB soll wohl TaskControlBlock heißen. Hat also nix mit Timern zu tun. oder nur um 12 Ecken.

Aha. ;-)

Das könnte zwar wieder eine Abseitsdiskussion werden. Nur wenn ich so rund um die Lib lese wurde diese auch für die neueren Controller angepasst. Wenn TCB_t für was anderes steht, aber für die neuen Controller in deren Headerfile für die Timer schon existiert, dieser Name TCB_t, dann muss das doch früher oder später knallen. Vielleicht knallt das jetzt ausgerechnet beim TO?

Wenn ich der TO wäre, ich würde erstmal die Beispiele der Lib versuchen zu kompilieren. Das soll ja alles auch auf einem ATmega328P funktionieren, also muss das eigentlich laufen. Danach kann man immer noch daran rumfummeln, wenn man weiß was man tut.

#7663198
Lesenswert?

Steve van de Grens schrieb:

Matthias schrieb:

Ist SREG ein Teil von R0-R31?

Nein

Muss ich die I/O Register beim Taskwechsel auch speichern?

Das ist unmöglich.

Danke für die Hilfe! Also relevant sind SREG und R0-R31.

Hier (https://gcc.gnu.org/wiki/avr-gcc) wird beschrieben, was tmp_reg = R0 und zero_reg = R1 ist.

SP_L und SP_H sind wahrscheinlich je ein Byte vom SP. Wobei ich mir jetzt nicht sicher bin ob es SP_L, SP_H oder SP_H, SP_L ist.

1
union{
2
  uint8_t  SP[2]{__SP_L__, __SP_H__};
3
  uint16_t SP;
4
  void     *SP;
5
}

Das Funktionsargument wird scheinbar in R24, R25 übergeben.

#7663199
Lesenswert?

Das ist der TCB_t...

1
struct xLIST_ITEM
2
{
3
?  listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE        /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
4
?  configLIST_VOLATILE TickType_t xItemValue;      /*< The value being listed.  In most cases this is used to sort the list in descending order. */
5
2  struct xLIST_ITEM * configLIST_VOLATILE pxNext;    /*< Pointer to the next ListItem_t in the list. */
6
2  struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;  /*< Pointer to the previous ListItem_t in the list. */
7
2  void * pvOwner;                    /*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
8
2  void * configLIST_VOLATILE pvContainer;        /*< Pointer to the list in which this list item is placed (if any). */
9
?  listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE        /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
10
};
11
typedef struct xLIST_ITEM ListItem_t;
12

13
typedef struct tskTaskControlBlock
14
{
15
2  volatile StackType_t  *pxTopOfStack;  /*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
16

17
  #if ( portUSING_MPU_WRAPPERS == 1 )
18
?    xMPU_SETTINGS  xMPUSettings;    /*< The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
19
?    BaseType_t    xUsingStaticallyAllocatedStack; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */
20
  #endif
21

22
8  ListItem_t      xGenericListItem;  /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
23
8  ListItem_t      xEventListItem;    /*< Used to reference a task from an event list. */
24
?  UBaseType_t      uxPriority;      /*< The priority of the task.  0 is the lowest priority. */
25
2  StackType_t      *pxStack;      /*< Points to the start of the stack. */
26
  char        pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
27
} TCB_t;
28
#endif
#7663209
Lesenswert?

Matthias schrieb:

Muss ich die I/O Register beim Taskwechsel auch speichern?

Schon das Lesen kann den Zustand des zugehörigen Peripheriegeräts ungewollt verändern. Und das Zurückschreiben gespeicherter Inhalte ist noch schlimmer. Und das auch noch in unterschiedlichen Tasks? ουαί κι αλίμονό μου!

Das steht in keinem Datenbuch ausdrücklich drin, weil es für jeden Profi absolut selbstverständlich ist.

#7663276
Lesenswert?

Ich hab mir jetzt Microchip Studio runtergeladen und schon paar Fehler gefunden.

Im Simulator geht das leichter...

Glaube der Stack ist uint8_t und dann stimmt glaube ich noch die pxCurrentTCB Variable nicht.

Ist gleich fertig :)

PS Geht's schon wieder los mit der Fingermotorik...

#7663306
Lesenswert?

Glaube ich habe es mehr oder weniger. Muss noch bissi testen und schauen, wie man das mit dem Speicher macht, wenn man keine MMU hat.

Was noch wichtig ist, während man an SP rumfummelt, muss man die Interrupt abschalten.

1
ZRTOS__INTERRUPTS_DISABLE();
2
portSAVE_CONTEXT(tmp);
3
portRESTORE_CONTEXT(tmp);
4
//asm volatile ( "ret" );
5
ZRTOS__INTERRUPTS_ENABLE();
Beitrag #7663315 wurde von einem Moderator gelöscht.
Gast #7663379
Lesenswert?

Matthias,

ich habe den Eindruck, dass du deine Fähigkeiten extrem überschätzt. Du willst ein RTOS Betriebssystem neu erfinden, ohne den Prozessor zu kennen. Was du vor hast ist machbar, aber das wird nach meiner Einschätzung einige Monate dauern.

100% sicher ist, dass du damit den Fokus auf die Problemursache verlierst. Du verzettelst dich mit einem komplexen Balkon, der dein Problem nicht löst, sondern höchstwahrscheinlich noch schwieriger begreifbar macht. Man soll ja junge Leute nicht demotivieren, doch es tut mir in der Seele weh, zu sehen, wie du mit Anlauf vor die Wand läufst.

Auf dem kleinen Mikrocontroller wird ein aktive Multitasking so viel RAM und CPU Leistung verschlucken, dass du damit nicht glücklich wirst - falls du es überhaupt schaffst.

Einen kooperativen Lösungsansatz ohne Register-Zauber habe ich dort beschrieben: http://stefanfrings.de/multithreading_arduino/index.html

Aber: Finde erst mal die Fehlerursache in deinem Programm! Nur wenn man seine eigenen Fehler erkannt und verstanden hat, kann man es danach besser machen.

(Firma: Gast) #7663381
Lesenswert?

Steve van de Grens schrieb:

Einen besseren Lösungsansatz

Ihm ist nicht an kooperation interessiert.

Steve van de Grens schrieb:

wie du mit Anlauf vor die Wand läufst

Ich sehe auch keinerlei Bestreben, nach rechts oder links zu schauen, ob der Maurer irgendwo ein Loch gelassen hat.

Wie auch immer... Ich bin gespannt wie sein Multitasking (optimiertes FreeRTOS) ausschaut, wenn es denn fertig ist.

#7663383
Lesenswert?

Steve van de Grens schrieb:

ich habe den Eindruck, dass du deine Fähigkeiten extrem überschätzt.

Wenn er es bis hierher nicht verstanden hat dann darf man ihm Beratungsresistenz attestieren.

Leider ist der Thread gestern, am Freitag, entstanden. Was auch kein gutes Zeichen ist. Allein CAN und Multitasking in Einem auf dem ATmega328P lässt mich schon ganz schwindelig werden.

Gast #7663386
Lesenswert?

Was der Matthias vielleicht noch nicht auf sich zu kommen sieht:

Wenn mehrere Threads auf gemeinsame Resourcen zugreifen (z.B. ein Display oder der CAN Bus), dann muss man irgendwie dafür sorgen, dass das in einer geordneten Reihenfolge passiert (Semaphoren). Das läuft oft auf gepufferte Ein/Ausgabe hinaus, für die er aber nicht genug RAM haben wird, da das ja schon von Registern und Stack der Threads "aufgefressen" wurde.

#7663400
Lesenswert?

Falk B. schrieb:

Rolf schrieb:

Das steht in keinem Datenbuch ausdrücklich drin,

Aber sicher, man muss nur des sinnerfassenden Lesens mächtig sein. Bei ALLEN IO-Registern steht, ob und wie ein Schreib- oder Lesezugriff eine Reaktion bewirkt.

Dann lies mal richtig. Was habe ich denn gesagt und was nicht? Und worauf bezog sich das?

Die allgemeine Aussage, dass man bei I/O-Registern nicht einfach blind lesen und schreiben darf, da es – im Gegensatz zu "normalen" Speicherregistern – gar keine Speicher, sondern nur Adressen zum Übermitteln von Befehlen und Stati an/von Peripheriegeräten sind, die steht eben nicht ausdrücklich drin.

#7663416
Lesenswert?

Matthias schrieb:

Ich brauche für die Solaranlage eine Steuerung mit CAN und RS485.

Sowas ähnliches habe ich auch im Einsatz. Auf CAN und UART fahre ich das gleiche Stringprotokoll. Der CAN-Interrupt teilt die Nachrichten in 8-Byte Pakete auf bzw. liest sie ein. RS485 und CAN lesen einfach in getrennte Puffer. Und sobald das Endezeichen erkannt wird, geht beides in den gemeinsamen Parser, der es dann ausführt und die Antwort in den CAN- bzw. UART-Puffer bastelt. Nirgends kann was hängen bleiben und Multitasking ist erst recht völlig unnötig. Sämtliche Parameter (ADC, I2C usw.) werden im Hintergrund permanent eingelesen. Der Parser muß also nirgends warten, sondern schickt gleich die Antworten. Als Schmankerl gibt es noch eine Autosend-Funktion. Der Master schickt dazu den Parameternamen und das gewünschte Intervall. Dann muß er nicht jedes mal erneut anfragen, sondern bekommt zyklisch alles geschickt.

Was Deine Registerrettungsorgie mit der Fragestellung zu tun hat, ist mir jedoch ein völliges Rätsel. Das ist nur unnütze Verschwendung von RAM, Code und CPU-Zeit.

Matthias schrieb:

Ohne Multitasking wird es arg kompliziert, wenn da irgendwas hängen bleibt.

Multitasking hilft aber nicht gegen Programmfehler. Im Gegenteil, es macht die Funktionen nur unnötig kompliziert und damit Fehler wahrscheinlicher. Wenn man die Abläufe sauber strukturiert, kann auch nichts "hängenbleiben".

#7663472
Lesenswert?

Matthias schrieb:

Ich hab mir jetzt Microchip Studio runtergeladen und schon paar Fehler gefunden.

Das stimmt. Besonders in Simulatoren kann man in Microchip Studio viele Fehler finden.

Ich sehe dein Problem aber woanders: du willst Inline Assembler benutzen, ohne AVR einigermaßen kennenzulernen.

An deiner Stelle würde ich zuerst ein paar Projekte mit C und mit Assembler machen, dann etwas mit Inline Assembler Schritt zu Schritt, und erst danach mit RTOS experimentieren. Nur so wirst du verstehen, was du machst.

#7663495
Lesenswert?

Frage, was passiert mit den Registern und Stack im Interrupt?

Kann ich da im Interrupt einfach einen Task starten oder Taskwechsel machen?

Wahrscheinlich muss ich ganz am Anfang vom Interrupt die Register und Stack des alten Task speichern?

Gibt es da ein Muster irgendwo? Ist dafür das naked Funktionsattribut, oder muss das in ASM sein?

(Firma: 1984now) #7663554
Lesenswert?

Matthias schrieb:

Frage, was passiert mit den Registern und Stack im Interrupt?

Beim AVR8? So gut wie nix. Der PC wird auf den Stack gesichert und das I-Flag in SREG gelöscht. Für alles andere ist man selbst (oder der Compiler) verantwortlich.

Kann ich da im Interrupt einfach einen Task starten oder Taskwechsel machen?

Üblicherweise nicht. Üblicherweise ist so ein Multitasking-OS sinnvollerweise so konstruiert, dass die Devicetreiber (und der Task-Scheduler) das einzige sind, was überhaupt Interrupthandler implementiert.

Und die Devicetreiber ihrerseits füttern oder entleeren üblicherweise nur Queues im RAM. Maximal können sie noch dafür sorgen, dass der Task, der auf ein entsprechendes Ereignis wartet, in der Prioritätsliste nach oben wandert.

Fazit: ein Riesenhaufen Verwaltungs-Overhead, den niemand benötigt, der wirklich programmieren kann...

Klar, man kann auch mit einem RTOS was zum Laufen bringen, aber das Ergebnis wird massiv suboptimal sein. Nunja: solange die Rechenzeit-Resourcen dafür reichen, dass es halt den Anforderungen der Anwendung genügt, ist das egal. Aber wehe, es kommt was dazu...

Dann ist das Bein genauso dicke, als hätte man den Kram "klassisch" implementiert, also ohne RTOS. Der Unterschied ist halt nur: das wird bei einem RTOS-Ansatz bei gegebener Hardware viel früher passieren. Dafür sorgt eben der Overhead des RTOS...

#7663559
Lesenswert?

Ob S. schrieb:

Matthias schrieb:

Frage, was passiert mit den Registern und Stack im Interrupt?

Beim AVR8? So gut wie nix. Der PC wird auf den Stack gesichert und das I-Flag in SREG gelöscht. Für alles andere ist man selbst (oder der Compiler) verantwortlich.

Bei mir hat der Compiler zumindest einen Teil der Register auf dem Stack gesichert und vor reti wieder geladen. ISR() vollzieht also sowas wie einen Taskwechsel, wenn es nicht mit attribute((naked)) ist.

Fazit: ein Riesenhaufen Verwaltungs-Overhead, den niemand benötigt, der wirklich programmieren kann...

Klar, man kann auch mit einem RTOS was zum Laufen bringen, aber das Ergebnis wird massiv suboptimal sein. Nunja: solange die Rechenzeit-Resourcen dafür reichen, dass es halt den Anforderungen der Anwendung genügt, ist das egal. Aber wehe, es kommt was dazu...

Dann ist das Bein genauso dicke, als hätte man den Kram "klassisch" implementiert, also ohne RTOS. Der Unterschied ist halt nur: das wird bei einem RTOS-Ansatz bei gegebener Hardware viel früher passieren. Dafür sorgt eben der Overhead des RTOS...

Ja, mal schauen. Wenn es mir am Ende nicht gefällt, kann ich es immer noch mit einem while(1){switch} neu machen.

#7663593
Lesenswert?

Matthias schrieb:

ISR(TIMER2_COMPA_vect) ist per default nicht naked...

Und gut so. Naked brauchst du selten. Z.B. dort wo SREG in ISR nicht geändert wird. Oder muß du per Hand SREG und alle benutzten Register in Stack legen. Aber Compiler selbst macht das noch besser. Nur vergiß nicht, Optimieren auf -Os zu stellen. Dummerweise macht Microchip Studio für neue Projekte -Og.

#7663615
Lesenswert?

Matthias schrieb:

Verdammte kleine Mistdinger, ist doch alles komplizierter als gedacht.

Aber nur, wenn man es sich absichtlich kompliziert machen will. Die Mehrheit läßt einfach den Compiler sich um alles kümmern und pfuscht ihm nicht mit Assembler ins Handwerk. Was stört Dich denn an der Mainloop mit Interrupts Methode?

Hast Du überhaupt schonmal irgend was programmiert oder ist das Dein Einsteigerprojekt?

Persönliche Seite #7663625
Lesenswert?

Ein RTOS zu verwenden macht übrigens auf anderen Controllern deutlich mehr Sinn, wie z.B. Cortex-M. Die sind im Gegensatz zu den AVR extra dafür konzipiert und können den Kontextwechsel fast automatisch und sehr effizient. Außerdem haben die Support für Atomics, Speicherschutz (MPU) und Privilegierung/Separierung von OS und Anwendung, Interrupt-Prioritäten usw. Rein zufällig gibt es dafür auch schon fertige RTOS wie eben FreeRTOS.

(Firma: drx) #7663628
Lesenswert?

Maxim B. schrieb:

Nur vergiß nicht, Optimieren auf -Os zu stellen. Dummerweise macht Microchip Studio für neue Projekte -Og.

Für seinen Fall wäre -Og besser:

-Os: Diese Option optimiert den Code für die Größe des resultierenden ausführbaren Programms. Der Compiler versucht, den Code so zu optimieren, dass er weniger Speicherplatz benötigt, auch wenn dies möglicherweise auf Kosten der Ausführungsgeschwindigkeit geht. Das ist besonders nützlich für eingebettete Systeme oder Programme, bei denen die Größe des Binärdatei eine Rolle spielt.

-Og: Diese Option steht für "Optimize for Debugging". Im Gegensatz zu anderen Optimierungsstufen versucht "-Og" nicht, den Code stark zu optimieren. Stattdessen optimiert es den Code auf eine Weise, die das Debuggen erleichtert. Das bedeutet, dass der generierte Code lesbarer bleibt und das Debuggen einfacher ist, da Variablenwerte leichter nachvollziehbar sind. Diese Option ist besonders nützlich während der Entwicklungsphase, wenn die Hauptpriorität das Debuggen und die Fehlersuche sind.

#7663658
Lesenswert?

Stored B. schrieb:

Der Compiler versucht, den Code so zu optimieren, dass er weniger Speicherplatz benötigt, auch wenn dies möglicherweise auf Kosten der Ausführungsgeschwindigkeit geht.

Meine Erfahrung: mit -Os gewinnt man beides, auch Ausführungsgeschwindigkeit. Noch interessanter: manche Sachen, die mit -Os gut funktionieren, werden mit -Og Fehler bringen. Ein Beispiel:

1
ISR(TIMER1_COMPA_vect,ISR_NAKED){ /* Timer/Counter1 Compare Match A */
2
  PORTB |= 1<<2;
3
  reti(); 
4
}

Mit -Os bekommen wir:

1
SBI 0x05,2
2
RETI

Das wird funktionieren.

Mit -Og bekommen wir:

1
IN R24,0x05
2
ORI R24,0x04 
3
OUT 0x05,R24
4
RETI

Scheinbar wird das auch funktionieren, nur langsamer. In Wirklichkeit aber werden hier SREG und R24 in ISR geändert, das führt zu groben Programmfehler.

(Firma: Gast) #7663732
Lesenswert?

Matthias schrieb:

Nutzen die in den Bibliotheken pthread?

KA, es gibt gefühlte 20 Tausend Arduino Libs. Sicherlich nutzen einige davon die ProtoThreads, davon musst du ausgehen. Und seit die Coroutinen in C++ Einzug gehalten haben, wird das Konzept wohl in Zukunft häufiger zu finden sein.

Matthias schrieb:

irgendwo Kauderwelsch

Alles klar! Keine Fragen mehr. Alles klar!

#7663828
Lesenswert?

Nur mal angenommen, eine Bibliothek würde die posix pthread einbauen.

Was hätte man denn dann verloren?

Ein Zustandsautomat definiert das einfach auf nichts und der wo es braucht, implementiert das je nach eigenen Vorstellungen.

Wenn man da die einzelnen speziellen Funktionen der unzähligen RTOS mit # ifdef einbauen will ist man ja verloren...

Persönliche Seite #7663830
Lesenswert?

Matthias schrieb:

Was hätte man denn dann verloren?

Du müsstest halt genau dieses API implementieren damit die pthread Funktionen was aufrufen können. Aber warum POSIX Threads und nicht Standard C bzw. C++ threading?

Matthias schrieb:

Wenn man da die einzelnen speziellen Funktionen der unzähligen RTOS mit

ifdef einbauen will ist man ja verloren...

Genau so macht man es aber, Stichwort OSAL (OS abstraction layer).

Gast #7663831
Lesenswert?

Matthias schrieb:

Was hätte man denn dann verloren?

RAM, CPU Takte

Ein Zustandsautomat definiert das einfach auf nichts und der wo es braucht, implementiert das je nach eigenen Vorstellungen.

Du meinst wohl ein Makro. Ganz so einfach ist es in der Praxis nicht. Multi-Threading ist nicht nur ein Balkon den man wahlweise weg lassen kann. Das ganze Programm muss strukturell darauf ausgelegt sein und das bekommt man nicht zum Nulltarif.

(Firma: 1984now) #7664978
Lesenswert?

Peter D. schrieb:

Das wäre dann doch der ideale Zeitpunkt, das ganze RTOS selber bauen Gedöns grundsätzlich fallen zu lassen. Und vor allem, wenn man keinerlei Ahnung davon hat.

Ganz genau. Wenn ein RTOS irgendeinen Sinn ergeben soll, dann doch allenfalls, wenn man es nicht erst noch selber basteln muss.

Wenn man das nämlich kann, hat man auch keinerlei Probleme damit, eine Anwendung ganz klassisch ohne RTOS umzusetzen.

Persönliche Seite #7664979
Lesenswert?

Ob S. schrieb:

Wenn man das nämlich kann, hat man auch keinerlei Probleme damit, eine Anwendung ganz klassisch ohne RTOS umzusetzen.

Oft ist man auf externe proprietäre Bibliotheken/Frameworks angewiesen, welche synchron implementiert sind. Wenn man dann noch andere Dinge parallel laufen lassen möchte, braucht man ein RTOS. Das allerdings kompatibel zu solchen Bibliotheken zu machen könnte interessant werden.

(Firma: 1984now) #7664985
Lesenswert?

Niklas G. schrieb:

Oft ist man auf externe proprietäre Bibliotheken/Frameworks angewiesen, welche synchron implementiert sind.

Ist mir noch nie passiert. Hast du Beispiele?

Wenn man dann noch andere Dinge parallel laufen lassen möchte, braucht man ein RTOS.

Selbst dann nicht wirklich. Kommt allerdings auch ein wenig darauf an, was genau da parallel laufen muss. Wenn das dann eine zweiter synchroner zusammengeklauter Scheiß ist, dann könnte es tatsächlich eng werden...

Also: weniger klauen, mehr selber programmieren und gut isses.

Persönliche Seite #7664991
Lesenswert?

Ob S. schrieb:

Hast du Beispiele?

Proprietär: TouchGFX, die ST USB-PD Library

OpenSource: Die STM32WL55 RF und LoRa Middleware, der ATWILC-Treiber, FatFs, die I²C-Libraries für die alten STM32, überhaupt alle möglichen Libraries für (I²C-)Sensoren und Peripherie-ICs

Es gibt bestimmt noch viele mehr für exotische Protokolle z.B. in der Industrie. Die APIs der ESP32 sind größtenteils synchron, aber dort benutzt man ja sowieso FreeRTOS.

Die OpenSource-Libraries kann man prinzipiell umbauen, aber der Aufwand ist oft nicht gerechtfertigt. Wenn man nur ein Framework dieser Art hat kann man sich herauslavieren indem man den Rest asynchron macht, aber sobald es mehr als eins ist braucht man ein RTOS. Ich habe das Gefühl, dass die ganze Embedded-Industrie das Komponentenparadigma nicht verstanden hat - die Annahme ist immer, man nutzt exakt 1 Framework an welchem man das ganze Projekt ausrichtet und sonst nichts.

Ob S. schrieb:

Also: weniger klauen, mehr selber programmieren und gut isses.

Und wer bezahlt das? Mal eben so ein 100kLoC-Framework nachbauen kann sich nicht jedes Unternehmen leisten.

#7665001
Lesenswert?

Arduino F. schrieb:

Johann L. schrieb:

Soweit ich weiß werden Coroutinen in avr-g++ nicht unterstützt,

Sind nicht im Lieferumfang.

Aber hier durchaus vorhanden: https://github.com/modm-io/avr-libstdcpp

-> bisher nicht getestet

Mein (AVR) Arduino beschwert sich zumindest nicht über ein1#include <coroutine>

Jetzt musst du nur noch die AVR-gcc toolchain mit multithreading enabled bauen, und schon wird es auch funktionieren. Die dafür benötigten „Kleinigkeiten“ werden dich ja nicht groß überfordern…

Oliver

#7665251
Lesenswert?

Johann L. schrieb:

Es geht um Unterstützung im Compiler.

Meine Erfahrung ist, es funktioniert am zuverlässigsten, wenn man dem Compiler nicht ins Handwerk pfuscht. Die Compilerbauer verstehen schon ihr Handwerk.

Ich hab mal in einem früheren Projekt naked Interrupts mit Assembler benutzt, um dem AVR eine 2. Priorität beizubringen. Rückblickend würde ich das aber nicht als Masterpiece ansehen.

#7665837
Lesenswert?

Peter D. schrieb:

Johann L. schrieb:

Es geht um Unterstützung im Compiler.

Meine Erfahrung ist, es funktioniert am zuverlässigsten, wenn man dem Compiler nicht ins Handwerk pfuscht. Die Compilerbauer verstehen schon ihr Handwerk.

Das Problem ist, man programmiert halt und rechnet den Speicherbedarf aus und dann wächst der Stack doch plötzlich da rein, wo er nicht hin soll und das Teil stürzt unkontrolliert ab.

Wenn man jetzt bissl Luft lässt, so dass man nicht vor jedem Stackzugriff prüfen muss, könnte man optional schon Rechenzeit gegen Sicherheit tauschen und bei einem Überlauf den laufenden Thread beenden.

Klar kann man auch den Code manuell vor dem Compilerdurchgang mit Stacküberlauftests durchziehen, aber...

#7665883
Lesenswert?

Matthias schrieb:

Klar kann man auch den Code manuell vor dem Compilerdurchgang mit Stacküberlauftests durchziehen, aber...

Ich habe in meinen Programmen 2 kleine Prüffunktionen implementiert, die man per Kommando aufrufen kann. Einmal wird der freie Bereich zwischen Daten und Stackpointer mit 0x77 gefüllt und getestet, wieviel davon seit dem letzten Aufruf übrig ist. Die andere Funktion zählt die maximalen Timerticks (1ms) zwischen 2 Durchgängen der Mainloop. Beim ersten Aufruf kriegt man die Dauer aller Initialisierungen angezeigt. Damit läßt sich bequem die maximale Auslastung während der Laufzeit ermitteln.

Weiterhin wird noch der letzte Resetgrund ausgegeben. Ist dieser seit dem letzen Start der Applikation 0x00, dann ab zurück zum Debuggen. Denn dann ist ja ein wilder Pointer in den Resetvektor gelaufen, d.h. dieses Programm darf nicht ausgeliefert werden.

Beitrag #7665901 wurde von einem Moderator gelöscht.
#7666032
Lesenswert?

Peter D. schrieb:

Ich habe in meinen Programmen 2 kleine Prüffunktionen implementiert, die man per Kommando aufrufen kann. Einmal wird der freie Bereich zwischen Daten und Stackpointer mit 0x77 gefüllt und getestet, wieviel davon seit dem letzten Aufruf übrig ist. Die andere Funktion zählt die maximalen Timerticks (1ms) zwischen 2 Durchgängen der Mainloop. Beim ersten Aufruf kriegt man die Dauer aller Initialisierungen angezeigt. Damit läßt sich bequem die maximale Auslastung während der Laufzeit ermitteln.

und wie schaffst du es alle anfallenden Bedingungen zu testen? Wie erkennst du zerpflückte nicht zusammenhängende Speicherbereiche?

Ich denke an PET2001 da gab es die garbadge collection, der Müll mußte ab und an rausgetragen werden. Ich denke an AtariST TOS 1.0 wo nach 128 malloc/free Aufrufe gebombt wurde, also Absturz, was mit TOS 1.4 nur auf 1024 malloc/free Aufrufe erweitert wurde aber das Problem nur verschob.

Ich dachte auch mal man könnte auf kleinere AVR sowas machen, aber der Code wurde immer aufgeblähter und passte dann nicht mehr ins flash.

Meine Erfahrungen, bekannte viel genutzte Variablen nicht dynamisch zuzuweisen sondern schon vorher zu reservieren, verringert zwar den freien SRAM aber es kommen zur Laufzeit keine Überraschungen.

Speicher ist wie Hubraum, durch nichts zu ersetzen. Die kleinen Motoren mit Turbo aufzublasen schaffen auch mehr Probleme als sie lösen, Golf mit 1,4L und Turbo fällt mir da ein oder die Ford EcoBoost mit in Öl laufenden Zahnriemen.

#7666116
Lesenswert?

Peter D. schrieb:

Matthias schrieb:

Klar kann man auch den Code manuell vor dem Compilerdurchgang mit Stacküberlauftests durchziehen, aber...

Ich habe in meinen Programmen 2 kleine Prüffunktionen implementiert, die man per Kommando aufrufen kann. Einmal wird der freie Bereich zwischen Daten und Stackpointer mit 0x77 gefüllt und getestet, wieviel davon seit dem letzten Aufruf übrig ist. Die andere Funktion zählt die maximalen Timerticks (1ms) zwischen 2 Durchgängen der Mainloop. Beim ersten Aufruf kriegt man die Dauer aller Initialisierungen angezeigt. Damit läßt sich bequem die maximale Auslastung während der Laufzeit ermitteln.

Weiterhin wird noch der letzte Resetgrund ausgegeben. Ist dieser seit dem letzen Start der Applikation 0x00, dann ab zurück zum Debuggen. Denn dann ist ja ein wilder Pointer in den Resetvektor gelaufen, d.h. dieses Programm darf nicht ausgeliefert werden.

Hm, eine dritte ISR die den SP überwacht, das eine sehr gute Idee!!

Baue das heute Abend ein, nachdem ich die ganzen Fehler behoben habe, die ich gestern Abend nach zwei Bier reingeschusselt hab...

Btw. ich musste leider wegen einem Namenskonflikt mit dem Repository umziehen und das Teil in AgileRTOS umbenennen (https://github.com/ykat-UG-haftungsbeschrankt/agilertos).

#7667285
Lesenswert?

Matthias schrieb:

Ich glaube ich bin schon zu alt...

Aus meine Sicht eher zu jung. Ein mittelprächtig anspruchsvolles Programm mit aufwendigen Mitteln lösen zu wollen, spricht eher für mangelnde Weitsicht. Ich kann nur Falk beipflichten: Falk B. schrieb im Beitrag #7663101:

Aber für bissel CAN und Solaranlage scheint das hier eine verdammt aufgeblähte Lösung zu sein.

Es wäre aus meiner Sicht angebracht, zwei Schritte zurückzutreten, das Projekt neu aufzusetzen und sich zunächst mal um die einfacheren Varianten des Multitasking zu kümmern.

Just my 2 cents Klaus (der soundsovielte)

#7667453
Lesenswert?

Steve van de Grens schrieb:

Gerhard H. schrieb:

Eingeschränkt aber z.B. an den Z380

Oh wie cool, der hat ja noch mehr Registersätze! Ich dachte, der Z80 sei der einzige Prozesser dieser Art.

Heute wäre die Werbung für den TMS9900 "Bis zu 2047 Registersätze!" Wirklich schade, dass diese Architektur aus der Mode gekommen ist. Mit 1MByte On Chip RAM und 0 Wait States würde das gut funktionieren.

https://en.wikipedia.org/wiki/TMS9900

#7667469
Lesenswert?

Die Register die beim Taskwechsel gerettet werden müssen sind ja nur das eine. Man gönnt jedem Task ja seinen eigenen Stack. Wenn man da sparsam ist dann kann es in langen Debug Sessions enden, oder man ist großzügig, muss dann aber auch genug RAM haben. Genug Gründe um für preemptives MT Cortex-M einzusetzen.

Gast #7667484
Lesenswert?

Matthias schrieb:

Hm, eine dritte ISR die den SP überwacht, das eine sehr gute Idee!!

Dazwischen kann aber auch sehr viel passieren... Das testweise Markieren des Zwischenraums Daten<>Stack a'la Peter D. ist sicher die bessere Idee. Diese Markierung performance- gesittet d.h. stückweise zu kontrollieren wäre für besagte periodische ISR m.M. eine sinnvollere Aufgabe. Im allgemeinen aber sollten fehlgeleitete SRAM Zugriffe und Stackfehler- und damit der nötige Einsatz von Kontroll- Instrumenten die absolute Ausnahme darstellen. Kann gut sein daß man da mit Assembler besser am Puls der Hardware hört und dran ist :)

Peter D. schrieb:

Die andere Funktion zählt die maximalen Timerticks (1ms) zwischen 2 Durchgängen der Mainloop.

Ich hab dafür (so verfügbar) einen Hardware TC-Counter mit vollem Speed = maximaler Zeitauflösung laufen. Der kann dann nicht nur zu verschiedenen Zeitpunkten in der Main abgefragt werden sondern auch in Interrupts, um die Zeiten der Abarbeitung derselben zu kontrollieren.

#7669832
Lesenswert?

Falk B. schrieb:

Matthias schrieb:

Hallo, ich bins...

Ich brauche für die Solaranlage eine Steuerung mit CAN und RS485.

Kann mir bitte einer sagen, was da nicht stimmt?

Du hast die Netiquette nicht beachtet, längere Quelltexte gehören in den Anhang.

Ich habe schon die ganze Nacht gesucht. Leider sind da in dem Quelltext von dem TCB_t und ListItem_t so viele #ifdef dass ich nicht weiß, wie ich aus einem StackType_t * ein TCB_t bekomme.

Ich auch nicht. Aber für bissel CAN und Solaranlage scheint das hier eine verdammt aufgeblähte Lösung zu sein.

Hab dem Teil noch paar Eventhandler für Arme spendiert...

https://ykat-ug-haftungsbeschrankt.github.io/agilertos/index.html#autotoc_md2

Die Tasks (statisch und vheap) laufen noch nicht richtig und der mutex auf dem vheap fehlt. Weiß nicht, ob ich das heute und morgen noch schaffe.

Danach steht erst mal was anderes an...

#7671275
Lesenswert?

Niklas G. schrieb:

Matthias schrieb:

Hätte gerne noch sowas wie eine Scriptsprache, oder einen Interpreter für bytecode, damit man Fernupdates machen kann.

Warum brauchst du das für Fernupdates?

Wenn ich die Steuerung von der Solaranlage und später mal Heizung fest einprogrammiere, sehe ich mich schon dauernd mit dem Laptop auf einem Hocker im Keller sitzen und das Teil umprogrammieren.

Noch dazu ist das Script kleiner, da hebt sich der zusätzliche Speicherverbrauch schnell auf...

#7671276
Lesenswert?

Klaus schrieb:

Matthias schrieb:

Die Tasks (statisch und vheap) laufen noch nicht richtig und der mutex auf dem vheap fehlt. Weiß nicht, ob ich das heute und morgen noch schaffe.

Da bist du immerhin der Einzige, der das noch nicht weiß.

Das man Versionsnummer 0.2.0 höchstens mal anschaut und nicht produktiv einsetzt ist doch jedem vernünftigen klar??

So ab 0.9 würde ich es persönlich mal kompilieren und aufspielen...

Persönliche Seite #7671282
Lesenswert?

Matthias schrieb:

Wenn ich die Steuerung von der Solaranlage und später mal Heizung fest einprogrammiere, sehe ich mich schon dauernd mit dem Laptop auf einem Hocker im Keller sitzen und das Teil umprogrammieren.

Das erklärt nicht, warum es eine Skriptsprache für das Update braucht.

Matthias schrieb:

Noch dazu ist das Script kleiner, da hebt sich der zusätzliche Speicherverbrauch schnell auf...

Wie komplex ist deine Heizungssteuerung dass sie nicht in einen gewöhnlichen Mikrocontroller passt?

#7671291
Lesenswert?

Matthias schrieb:

Noch dazu ist das Script kleiner, da hebt sich der zusätzliche Speicherverbrauch schnell auf...

Es geht nicht um den Speicher. Woher soll das Script wissen, welche Funktionen Du mal später noch alle implementieren willst.

Viel einfacher ist ein Bootloader, dem man das neue Hex oder Bin schickt. Damit ist man maximal flexibel.

(Firma: Gast) #7671554
Lesenswert?

Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren