Forum: Compiler & IDEs ARDUINO class oder struct in ISR Fehler


von Joachim B. (jar)


Lesenswert?

kann jemand diesen Fehler erklären oder wie ich das anstellen muss das 
es in der ISR läuft?

isr:153: error: passing 'volatile TS_Point' as 'this' argument of 
'TS_Point& TS_Point::operator=(const TS_Point&)' discards qualifiers

im Hauptprogramm
1
volatile TS_Point p;

in der ISR
1
extern volatile TS_Point p;
2
3
    if(ts.touched())
4
    {  p = ts.getPoint();   // Retrieve a point  
5
       p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width()); p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
6
       ts_data = 1;
7
    }
IMHO verbirgt sich doch nur ein Struct hinter TS_Point, also sollte die 
Adresse doch reichen aber mit cpp kenne ich mich halt nicht aus.
1
class TS_Point {
2
 public:
3
  TS_Point(void);
4
  TS_Point(int16_t x, int16_t y, int16_t z);
5
  
6
  bool operator==(TS_Point);
7
  bool operator!=(TS_Point);
8
9
  int16_t x, y, z;
10
};

: Bearbeitet durch User
von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Ich kann mich irren, aber:
extern volatile TS_Point p;
sollte nicht innerhalb einer Funktion (ISR) stehen.

Oder ist das erlaubt und welche Eigenschaft hat das dann?

Edit: Ah versuchst du etwa auf eine lokale Variable von main aus einer 
ISR zuzugreifen? Das Funktioniert nicht, du musst sie mindestens 
Modulglobal machen.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Christopher B. schrieb:
> Edit: Ah versuchst du etwa auf eine lokale Variable von main aus einer
> ISR zuzugreifen?

ne die ist in Main global denke ich zumindest, in der main.ino aber 
ausserhalb der Routine.

Christopher B. schrieb:
> du musst sie mindestens
> Modulglobal machen.

wie muss ich das bitte machen?

von Joachim B. (jar)


Lesenswert?

gelöst mit einem Umweg über eine eigen TS_Point in der ISR und Rückgabe 
andere volatile Var.

von Karl H. (kbuchegg)


Lesenswert?

Ein
1
class TS_Point {
2
 public:
3
  TS_Point(void) : x(0), y(0), z(0) {}
4
  TS_Point(int16_t x_, int16_t y_, int16_t z_) : x(x_), y(y_), z(z_) {}
5
  
6
  bool operator==(const volatile TS_Point& rhs) const volatile
7
           { return x == rhs.x && y == rhs.y && z == rhs.z; }
8
  bool operator!=(const volatile TS_Point& rhs) const volatile
9
           { return x != rhs.x || y != rhs.y || z != rhs.z; }
10
11
  TS_Point& operator=(const volatile TS_Point& rhs)
12
           { x = rhs.x; y = rhs.y z = rhs.z; return *this; }
13
  volatile TS_Point& operator=(const volatile TS_Point& rhs) volatile
14
           { x = rhs.x; y = rhs.y z = rhs.z; return *this; }
15
16
  int16_t x, y, z;
17
};

müsste es eigentlich auch tun.

Der Qualifier, von dem der Compiler spricht, ist das 'volatile', und 
zwar das vom Objekt, für welches der Zuweisungsoperator aufgerufen wird, 
das ansonsten verloren gehen würde, wenn die Operation mit dem 
'normalen' Zuweisungsoperator aufgerufen werden würde (den sich der 
Compiler selbst schreibt, wenn du es nicht tust)


Beachte bitte auch, dass du den Operatoren als Argumente jeweils 
Referenzen zum anderen Objekt geben willst, um die Erzeugung einer 
temporären Kopie zu verhindern. Und zwar allen! Die Übergabe per 
Referenz ist in C++ mit Ausnahme der Basisdatentypen (char, int, double, 
long, ....) der Regelfall! Gegebenenfalls als const-Referenz. Und in 
deinem Fall dann (leider) auch noch mit einem zusätzlichen volatile.

Möglich, dass du die Operatoren in weiterer Folge im Header File als 
inline Funktionen geschrieben hast. Persönlich bevorzuge ich die direkte 
Schreibweise in der Klassendefinition. Ich finde dort sieht man besser, 
dass sie inline sind. Und ja. Du willst sie inline machen, um dem 
Compiler alle Möglichkeiten zur Optimierung zu geben.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Karl Heinz schrieb:
> Ein
>  public:
> .....
> müsste es eigentlich auch tun.

danke, ich glaube ich verstehe so halb, aber da ich in cpp ganz schön 
absaufe und in Pointer auf Pointer kurz vor dem absaufen bin hebe ich 
mir das durchdenken für freie Zeit auf.

Momentan will ich nur vorwärts kommen, Ziel ist es PeDa bulletprof 
Tastaturentprellung in der ISR zur TouchScreen Entprellung umzubauen.

Ich finde diese Entprellroutine so geil und nie entgeht mir ein 
Tastendruck, das möchte ich gerne auch auf dem Touch haben.

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:
> Karl Heinz schrieb:
>> Ein
>>  public:
>> .....
>> müsste es eigentlich auch tun.
>
> danke, ich glaube ich verstehe so halb, aber da ich in cpp ganz schön
> absaufe


Im Prinzip ist das, worum es hier geht, sehr simpel.

Du bist von C gewohnt, dass ein
1
  a = b;
einfach nur eine Umkopieraktion ist.
Dagegen ist auch ncihts zu sagen.

In C++ ist da aber noch ein Schritt dazwischen. Eine derartige Zuweisung 
ist im Sinne der Objektorientierung einfach nur ein AUfruf einer 
Memberfunktion (die lediglich einen etwas spezielleren Namen hat).
1
  a.operator=( b );

D.h. das Objekt a ist selbst dafür zuständig, was bei einer Zuweisung zu 
passieren hat. Es kapselt dieses Wissen in der Implementierung dieses 
Operators (der nichts anderes als eine speziellere Form einer Member 
Funktion ist).

Wenn du keine derartige Member Funktion selber schreibst, dann schreibt 
der Compiler eine für dich. Die macht - tada - nichts anders als eine 
Zuweisung aller Member des Objektes. Damit sind wir wieder genau da, 
dass ein
1
  a = b;
für Klassen, die keine Spezialbehandlung benötigen, genau das macht, was 
du erwarten würdest und was du auch gewohnt bist.

In deinem speziellen Fall, kommt dir das volatile von
1
 volatile MyClass a;
in die Quere.

Denn der standardmässig erzeugte Operator ist dafür nicht ausgelegt. Der 
ist eigentlich nur für nicht volatile Objekte gedacht. Warum das wichtig 
ist, ist einer Eigenschaft geschuldet: Der Operator gibt eine Referenz 
auf sein Objekt zurück. Und da darf dieses volatile nicht verloren 
gehen. D.h. es bleibt nichts anderes übrig, als eine Version des 
Operators zu schreiben, die ausdrückt: kann für volatile Objekte 
aufgerufen werden
1
  ....
2
3
   ........ operator= ( ..... ) volatile;

und liefert dann auch wieder eine Referenz auf ein volatile Objekt
1
   ....
2
3
  volatile MyClass& operator= ( .... ) volatile;

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.