Forum: Mikrocontroller und Digitale Elektronik Seltsames Programmverhalten


von uli (Gast)


Lesenswert?

Hallo,

benutze SW4STM32 als IDE mit GNU Toolchain.

Das Programm hat bislang gut funktioniert.
Habe eine bool Variable hinzugefügt und initialisiere diese mit false.

An einer Programmstelle frage ich diese bool Variable auf false ab.

Habe dort einen Breakpoint gesetzt.

Nun das seltsame Verhalten.

In der Watchlist wird mir die bool Variable mit 200 angezeigt und es 
wird in den If Block hineingegangen, was nicht richtig ist, da ich die 
bool Variable mit false initialisiert habe.
Erzeuge ich an einer anderen Stelle im Programm eine weitere Variable
z.b. uint8_t count = 9; und habe nichts weiter verändert,
dann wird am gleichen Breakpoint die bool Variable in der Watchlist 
richtig mit false angezeigt und es wird nicht in den If Block 
hineingegangen.

Habe gerade keine Idee, was dieses reproduzierbare Verhalten verursacht.

von Jobst M. (jobstens-de)


Lesenswert?

Was steht in Zeile 42?

Gruß
Jobst

von uli (Gast)


Lesenswert?

da weiste doch .... 42 :-)

Hatte die bool Variable im private Bereich unter einer Klasseninstanz in 
welcher ich string Variablen initialisiere. (std::string a = "123";)

Habe die bool Variable davor gesetzt und nun verhält sich das Programm 
wieder wie zu erwarten.

Muss morgen mal schauen, was ich in der Klasse  mit den string Typen 
genau mache. Möglicherweise passt da was nicht.

von Opi (Gast)


Lesenswert?

Denke es liegt genau daran!

von Wolfgang (Gast)


Lesenswert?

uli schrieb:
> Habe gerade keine Idee, was dieses reproduzierbare Verhalten verursacht.

Nicht das Programmverhalten ist seltsam, sondern deine 
Erwartungshaltung.

Der Controller wird mit großer Wahrscheinlichkeit tun, was du 
programmiert hast.

von Andreas M. (andiator)


Lesenswert?

Die Beschreibung klingt so, als ob Deine Klasse außerhalb eines Arrays 
schreibt und genau da lag Dein Boolean (hatte so was auch schon mal 
gesehen)
Verschiebe den bool zurück, setze Variablen davor und danach, z.B. 
chars, und beobachte deren Inhalt.
Der Inhalt würde sich ändern, falls in falsche Speicherbereiche 
geschrieben wird.

Kann man auch einen Breakpoint auf die Adresse der bool Variable setzen? 
Ich weiß nicht, ob das bei dem STM-Debugger geht.

von uli (Gast)


Lesenswert?

Problem habe ich leider noch nicht wirklich gelöst.

Hier ein Ausschnitt meiner Klasse.

--------------------------------------------------
private:

  const QueueHandle_t sma_rx_qh;

  uint8_t TrnEscapedTelegram[200];

  uint8_t TrnEscapedTelegramLength;

  CSMAData oCSMAData;

  CTelegramBody oTelegramBodyReceived;

  CTelegramBody oTelegramBodyToSend;

  bool transmittedAndReceived = false;


  void Fn_Process(void);
----------------------------------------------------

Also, wenn ich "transmittedAndReceived" über
"CTelegramBody oTelegramBodyToSend;"
setze, dann stimmt das Programmverhalten.
Ebenso, wenn ich
"CTelegramBody oTelegramBodyReceived;" und
"CTelegramBody oTelegramBodyToSend;" in den Zeilen gegeneinander tausche 
und "transmittedAndReceived" in die Zeile dazwischen setze.

Wenn ich das wie oben lasse, dann enthält die Variable 
"transmittedAndReceived" nicht false sondern 200.

Denke, dass Array "TrnEscapedTelegram[200]" ist hier deklariert und 
sollte auch 200 Felder im statischen Speicher groß sein.

von Markus F. (mfro)


Lesenswert?

Das riecht nach Stack-Überlauf.

von uli (Gast)


Lesenswert?

https://www.youtube.com/watch?v=x40XnMGI75M

Aha.....kan ich die Stackgröße irgendwie selber festlegen?

von Dieter F. (Gast)


Lesenswert?

uli schrieb:
> Habe die bool Variable davor gesetzt und nun verhält sich das Programm
> wieder wie zu erwarten.

uli schrieb:
> Hier ein Ausschnitt meiner Klasse.

uli schrieb:
> Also, wenn ich "transmittedAndReceived" über
> "CTelegramBody oTelegramBodyToSend;"
> setze, dann stimmt das Programmverhalten.
> Ebenso, wenn ich
> "CTelegramBody oTelegramBodyReceived;" und
> "CTelegramBody oTelegramBodyToSend;" in den Zeilen gegeneinander tausche
> und "transmittedAndReceived" in die Zeile dazwischen setze.
>
> Wenn ich das wie oben lasse, dann enthält die Variable
> "transmittedAndReceived" nicht false sondern 200.
>
> Denke, dass Array "TrnEscapedTelegram[200]" ist hier deklariert und
> sollte auch 200 Felder im statischen Speicher groß sein.

Ja - oder auch nein.

Da keiner hier im Forum Dein Programm kennt ist nur vorstehende Aussage 
möglich.

von Jobst M. (jobstens-de)


Lesenswert?

DU brauchst mehr Details!?

Grandios!
Aber eigentlich helfen da keine Details mehr. Die Details schweben schon 
singend am Abendhimmel.

Gruß
Jobst

von Einer K. (Gast)


Lesenswert?

uli schrieb:
> Youtube-Video "Ich brauche mehr Details"
>
> Aha.....kan ich die Stackgröße irgendwie selber festlegen?

Kenne deinen Prozessor nicht, aber das Fehlerbild.

Typische Ursachen:
1. Stack Heap Kollision
2. Zeiger, welcher in die Wiese zeigen
3. Array Grenzen Überschreitung

Tipp:
Der Fehler ist nicht da, wo du ihn suchst
(denn dann hättest du ihn schon).
Der Fehler steckt da, wo du ihn nie vermuten würdest.
(darum zeigst du auch völlig unwichtigen Code)
Er steckt an der Stelle, wo zu zuletzt suchst.

von Dieter F. (Gast)


Lesenswert?

Jobst M. schrieb:
> Aber eigentlich helfen da keine Details mehr. Die Details schweben schon
> singend am Abendhimmel.

Na, dann kannst Du das ja sicherlich allen hier ausführlich erklären - 
ich bin gespannt.

von uli (Gast)


Lesenswert?

Sagt mal, wenn ich ein Array im header deklariere...
Also so....


*.h

uint8_t TrnEscapedTelegram[200];

Dann sollte doch ein 200er Feld von dem Typ uint8_t im Speicher angelegt 
worden sein... oder?

Und ich kann da von [0] ... bis ... [199] reinschreiben.

Denke ja oder?

Wenn dieses 200er Feld im Speicher angelegt wird, steht da default 0x00 
in jeder Zelle oder was X beliebiges?

Danke und Gruß

von uli (Gast)


Lesenswert?

Also ich bilde auch eine Instanz von der Klasse .... klaro.

von Alex W. (a20q90)


Lesenswert?

Der TE ist nicht mal in der Lage den gesammten Code zu posten, wie soll 
er da nen Fehler finden?

von Dieter F. (Gast)


Lesenswert?

uli schrieb:
> Also ich bilde auch eine Instanz von der Klasse .... klaro

Ich weiß wo Deine Haus wohnt :-)

von uli (Gast)


Lesenswert?

@ Dieter F.
Das freut mich für dich.

Wenn auch noch deine fachliche Meinung zu meiner Frage hier zum besten 
geben könntest, dann hätte ich mir dieses "Rumgetippe" jetzt sparen 
können.

Wenn aber jetzt auf stur schalten magst, .... bitte, gibt noch andere.
;-)
Legende:
;-) bedeutet Augenzwinker, da locker geschrieben.

Also gebe dir nen Ruck .... kann auch unter falschem Namen sein.

von Dieter F. (Gast)


Lesenswert?

uli schrieb:
> Wenn auch noch deine fachliche Meinung zu meiner Frage hier zum besten
> geben könntest,

Wenn Du mal Deinen Code veröffentlichen würdest (die andere 
Schgreibweise verkneife ich mir hier) ...

von Dieter F. (Gast)


Lesenswert?

uli schrieb:
> kann auch unter falschem Namen sein.

Das ist Dein Metier - nicht da meine ...

von Jobst M. (jobstens-de)


Lesenswert?

uli schrieb:
> Wenn auch noch deine fachliche Meinung zu meiner Frage

Frage wozu? - Das fehlt noch immer irgendwie. Was Du leider nicht 
verstehen möchtest.

Gruß
Jobst

von Einer K. (Gast)


Lesenswert?

uli schrieb:
> .... bitte, gibt noch andere.

Ich könnte dir eine Kristallkugel aufs Auge drücken.
Schon leicht angebraucht, aber mit allen Updates.

von uli (Gast)


Lesenswert?

Selbst ist der Mann.
Ich kriege das schon hin.

Danke und Gruß

von Einer K. (Gast)


Lesenswert?

Ja, das schaffst du!

Und dann wirst du auch erkennen, dass du uns keine Chance gegeben hast.

von rmu (Gast)


Lesenswert?

was ist CTelegramBody? Wo und wie wird oTelegramBodyToSend initialisiert 
bzw. geschrieben? Da schreibt möglicherweise jemand zu viel.

von Dieter F. (Gast)


Lesenswert?

uli schrieb:
> Selbst ist der Mann.
> Ich kriege das schon hin.

Schwaller :-)

von uli (Gast)


Lesenswert?

class CTelegramBody {
public:
  CTelegramBody();
  virtual ~CTelegramBody();

  uint8_t    StartByte;
  uint8_t    Adress;
  uint8_t    Control;
  uint16_t   Protokol;
  uint16_t   Quelle;
  uint16_t   Ziel;
  uint8_t    Ctrl;
  uint8_t    PktCnt;
  uint8_t    Cmd;
  uint8_t    Data[200];
  uint8_t    DataBytes;
  uint16_t   CRC16;
  uint8_t    StopByte;

};

Declaration in Header CTelegramBody.h siehe oben.

Implementiert in CTelegramBody.cpp ist nichts. Nur Constructor und 
Destructor.


In CTelegram.h habe ich dies drinnen. In der dargestellten Reihenfolge.
Nehme ich "bool transmittedAndReceived = false;" zwei Zeilen höher, hat 
die
transmittedAndReceived den Wert false.
So wie dargestellt hat "transmittedAndReceived" 200.

CTelegramBody oTelegramBodyToSend;
bool transmittedAndReceived = false;

Das Data[200] Array endet an der Adresse 0x2001ffd5
transmittedAndReceived hat die Adresse 0x2001ffdc.

von Einer K. (Gast)


Lesenswert?

Weiterhin hältst du die fehlerhafte Stelle geheim.
Offensichtlich sogar vor dir selber.

Naja, ich glaube, die Fehlersuche wird sich noch etwas strecken....

von Dieter F. (Gast)


Lesenswert?

uli schrieb:
> Declaration in Header CTelegramBody.h siehe oben.
>
> ...
>
> Das Data[200] Array endet an der Adresse 0x2001ffd5
> transmittedAndReceived hat die Adresse 0x2001ffdc.

Dieter F. schrieb:
> Schwaller :-)

Sorry - ich musste reduzieren - macht aber nichts :-)

von rmu (Gast)


Lesenswert?

Was soll das mit dem Array zu tun haben? Offenbar ist diese 
bool-variable ja ganz wo anders.

Abgesehen davon, warum ist der dtor virtuell?

Wenn sich das Fehlerbild abhängig vom Layout der Klasse ändert dann 
schreibt irgendwer irgendwas out of bound(s). Ohne den Code zu sehen 
kann man nicht sagen was.

von uli (Gast)


Lesenswert?

Für die liebe Fan Gemeinde, sei mal so viel mitgeteilt....


ich benutze freeRTOS -neu- und die Methode "Fn_Process(void)" wird vom 
Scheduler des OS nun vereinfacht, permanent aufgerufen. Es gibt keine 
anderen Tasks.

Habe da alles herausgenommen, was zum Eingrenzen des Problems nicht 
notwendig ist. Ergebnis ist unten.


Und nun das für mich unverständliche:
Wenn ich hier beim Debuggen (F5-Step Into) also single Step nutze, ist 
alles wie zu erwarten. "transmittedAndReceived" ist immer auf false, da 
so im header initialisiert.

Wenn ich aber (F8-Resume) also Run until Breakpoint nutze, dann zeigt 
mir
die "Watch Expression" Liste die 200 in "transmittedAndReceived" und 
dies führt dazu, dass in den If Block hineingegangen wird.

Es passt bei (F5-Step Into) und bei (F6-Step Over)
Es passn nicht bei (F7-Step Return) und bei (F8-Resume)

???
Morgen versuche ich das mal mit dem Atollic True Studio oder gebe die 
Variable über die Serielle Schnittstelle aus.

Eure Meinung dazu interessiert mich aber.


void CTelegram::Fn_Process(void)
{


  uint8_t count = 0;

  for(;;)
  {


*     if(transmittedAndReceived == true)  // Hier habe ich ein 
Breakpoint
      {
  count+=1;

      }
      count+=2;


  }
}

von uli (Gast)


Lesenswert?

Habe nun etwas herumgetüftelt......

Kurz wichtige Quellcodestellen:

So geht es nicht...
----------------------------------------------------------
void TaskScheduler(void)
{
  :
  :
  CTelegram oCTelegram(sma_rx_qh);
  :
  :
  xTaskCreate(  oCTelegram.Fn_Thread,
          (const char*)"t3",
    1000,
    &oCTelegram,
    2,
    NULL
       );

  vTaskStartScheduler();

  for(;;)
  {
    // Should never reached.
  }
}

Implementierungen in CTelegram.cpp

void CTelegram::Fn_Thread(void* pvParameters)
{
  static_cast<CTelegram*> (pvParameters)->Fn_Process();
}

void CTelegram::Fn_Process(void)
{

  uint8_t count = 0;

  for(;;)
  {


*   if(transmittedAndReceived == true)  // Hier habe ich ein Breakpoint
    {
      count+=1;

    }
    count+=2;
  }
}

----------------------------------------------------------
Vor dieser Zeile
static_cast<CTelegram*> (pvParameters)->Fn_Process();
ist die Variable "transmittedAndReceived" false, was stimmt.
Single Step ... also nach dieser Zeile
static_cast<CTelegram*> (pvParameters)->Fn_Process();
ist die Variable "transmittedAndReceived" irgendwas, was so nicht 
gewollt ist..
Alles andere Verhalten war OK.





So tut es soweit...
----------------------------------------------------------
CTelegram *oCTelegram = nullptr;

void TaskScheduler(void)
{
  :
  :
  oCTelegram = new CTelegram(sma_rx_qh);
  :
  :
  xTaskCreate(  oCTelegram->Fn_Thread,
          (const char*)"t3",
    1000,
    oCTelegram,
    2,
    NULL
       );

  vTaskStartScheduler();

  for(;;)
  {
    // Should never reached.
  }
}


Implementierungen in CTelegram.cpp

void CTelegram::Fn_Thread(void* pvParameters)
{
  static_cast<CTelegram*> (pvParameters)->Fn_Process();
}

void CTelegram::Fn_Process(void)
{

  uint8_t count = 0;

  for(;;)
  {


*   if(transmittedAndReceived == true)  // Hier habe ich ein Breakpoint
    {
      count+=1;

    }
    count+=2;
  }
}

----------------------------------------------------------

Vor dieser Zeile
static_cast<CTelegram*> (pvParameters)->Fn_Process();
ist die Variable "transmittedAndReceived" false, was stimmt.
Single Step ... also nach dieser Zeile
static_cast<CTelegram*> (pvParameters)->Fn_Process();
ist die Variable "transmittedAndReceived" false, was stimmt.
Alles andere Verhalten ist OK.


Ich bin erstmal happy das das tut und sofern mir hier keiner sagen mag 
oder kann, wieso das so war, werde ich morgen mal selber näher darüber 
nachgrübeln.


Bin noch nicht so vertraut mit freeRTOS und C++.
Aber C++ ist nicht nur gemein sondern Hundsgemein.

von Alex W. (a20q90)


Lesenswert?

Hör auf uns zu verarschen! Nur weil die Mods deinen tread nicht gelöscht 
haben bedeutet es nicht, dass du nen Freifahrtsschein hast!

von uli (Gast)


Lesenswert?

sorry .... aber worin genau liegt die Verarschung???

Ich hatte Fragen und es gab Antworten.
Und du glaubst doch net das ich meinen ganzen Source Code hier poste.
Schaut sich doch keine Sau an. Hätte ja eh keinen Sinn gemacht bei dem 
Fehlerbild..... wie auch jemand meinte, da kann von ganz anderer Stelle 
was nicht passen ..... was ja auch der Fall war.
Zudem haben die Anstöße der Comumnity doch gefruchtet.

Meine letzte Frage würde mich immer noch interessieren.

Nur das wir uns nicht falsch verstehen....
Ich bin in C++ und freeRTOS ein Anfänger und die Rückmeldungen 
interessieren mich um mein Halbwissen da auszubauen.

von rmu (Gast)


Lesenswert?

Offenbar ist aber nicht klar was das eigentliche Problem war und obs 
wirklich nachhaltig behoben ist. Vermutlich ist der out-of-bounds 
Zugriff noch immer vorhanden und radiert potentiell in Zukunft eine 
andere Datenstruktur aus.


Für zukünftige Fragestellungen:

* Weiterhin Salamitaktik verwenden und Infos nur scheibenweise 
herausrücken. Auch dann immer nur das allernotwendigste sagen, 
unwichtige und nebensächliche Details wie z.B. Platform, (RT)OS, 
Compiler, Programmiersprache, Warnings und Compile-Fehler und anderes 
nicht erwähnen, das lenkt nur vom eigentlichen Problem ab.

* Programme möglichst nicht als Quellcode ins Forum einstellen sondern 
mit möglichst blumiger und mit vielen Adjektiven ausgeschmückter Prosa 
beschreiben.

* Wenn schon Quellcode verwendet werden muss dann darauf achten dass er 
syntaktisch inkorrekt ist, z.B. alle schliessenden Klammern am Schluss 
weglassen; auf keinen Fall darf das Problem auf eine einzige 
kompilierbare Datei zusammengekürzt dargestellt werden. Verwendung von 
Auszeichnung für Quellcode der Foren-Software vermeiden, das stört durch 
die ruppige Unterbrechung im Grauwert den Lesefluss der Prosa.

* Quellcode von Programmen am besten gleich verschlüsselt schreiben, 
Struktur und Konsistenz bei Namen von Eigenschaften, Klassen, Methoden 
schon im Ansatz vermeiden. Einrückungen verschwenden nur Speicherplatz.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

uli schrieb:
> Und du glaubst doch net das ich meinen ganzen Source Code hier poste.

Das wäre aber schon sinnvoll. Du kannst hier auch Dateien anhängen.

> Schaut sich doch keine Sau an. Hätte ja eh keinen Sinn gemacht bei dem
> Fehlerbild....

Das Fehlerbild ist: Der Inhalt einer Variablen wird nicht 
nachvollziehbar geändert.

In 99% der Fälle liegt das an einem Überschreiber im RAM, welcher an 
einer ganz anderen Stelle im Programm passiert.

Beispiel:
1
int main ()
2
{
3
    char buf[8];
4
    int val;
5
6
    val = 7;
7
    // 1000 Programmzeilen dazwischen...
8
    strcpy (buf, "Hello, World\n");
9
    // weitere 1000 Programmzeilen dazwischen...
10
    printf ("val = %d\n", val);
11
    return 0;
12
}

Preisfrage: Was wird für val ausgegeben?

von uli (Gast)


Lesenswert?

Na ja, du schreibst hier offensichtlich mehr in das feld buf als dieses 
speicher vom compiler zugewiesen bekommen hat.

Erkennt das nicht der compiler?

Ich kann nahezu ausschließen, das ich sowas in meinem selbst 
geschriebenen source  habe.

Habe freeRros komplett raus genommen und da hat alles gepasst.
FreeRtos rein in den zwei varianten wie oben zu sehen und konnte den 
fehler mit der einen nicht mehr herbeiführen. Mit der anderen immer.

Sieht so aus als habe ich die freertos funktion xtaskcreate nicht 
richtig bedient.

Also möglicherweise kann wer meine zwei varianten erläutern und den 
bestätigen, das die eine variante zu solchem fehlverhalten führen kann.

Man sieht ja wo und wie ich die objekte erzeuge.
Einmal wird das im fehlerfall meiner meinung nach auf dem stack 
angelegt?? Denke ich.
Und das andere mal auf dem heap.

Ansonsten übergebe ich der funktion noch die adresse auf das objekt 
oCTelegram und mache dann einen typcast im Fn_Thread da freeRtos das mit 
c++ nicht auf die reihe bekommt.

von uli (Gast)


Lesenswert?

Nachtrag...
Der einzige unterschied liegt ja darin, das ich das objekt oCTelegram 
unterschiedlich erzeuge.

Möglicherweise lag da der fehler.
Deswegen der post und das könnte ja bewerzet werden.
Wenn jemand erfahrenes sagt das passt soweit alles, dann muss ich weiter 
suchen.

von Eric B. (beric)


Lesenswert?

Frank M. schrieb:
> Preisfrage: Was wird für val ausgegeben?

Gegenfrage: welche uC? :-P

von Eric B. (beric)


Lesenswert?

uli schrieb:
> Einmal wird das im fehlerfall meiner meinung nach auf dem stack
> angelegt?? Denke ich.
> Und das andere mal auf dem heap.

Genau - und das wurde dir auch gefühlte 100x gesagt: Stack-Overflow oder 
Stack/Heap Collision!!

Also: wie groß sind deine Objekte? Wie groß ist der Stack? Wieviel Stack 
braucht FreeRTOS selber?

von Adam P. (adamap)


Lesenswert?

uli schrieb:
> Ich kann nahezu ausschließen, das ich sowas in meinem selbst
> geschriebenen source  habe.

:-D   :'(
...sorry, aber da weiß ich echt nicht, ob ich/wir lachen oder weinen 
sollen?

Wenn du in der Methode die das Array beschreibt, nur ein Index-Fehler 
hast und die bool direkt dahinter liegt - ist es schon passiert.

Dies ist nur eine vermutung, da ja kein Source einsehbar ist.

Solche meist dummen und kleinen Flüchtigkeitsfehler, können jedem 
passieren und meist verbringt man Std. bis Tage diese zu finden, weil 
man eben denkt:
"Ach, sowas blödes hab ICH doch nicht gemacht"

Meist sieht man den Wald vor lauter Bäumen nicht.
Obwohl man tagtäglich Source produziert und sich seiner Prog.-Sprache 
sicher ist.

---
Wenn du evtl. noch über ein Zeiger in das Array schreibst, wird dir der 
Compiler gar nichts sagen.
Da die strcpy() Funktion nicht über den Index des Arrays Daten kopiert, 
sondern mit Zeiger, ist für den Compiler alles OK.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

uli schrieb:
> Na ja, du schreibst hier offensichtlich mehr in das feld buf als dieses
> speicher vom compiler zugewiesen bekommen hat.

Ja, und deshalb wird die dahinterliegende Variable "val" überschrieben.

Jetzt drehe ich das mal um:
Alt:
1
    char buf[8];
2
    int val;

Neu:
1
    int val;
2
    char buf[8];

Folge: Der Fehler ist immer noch da, aber jetzt wird er nicht mehr 
bemerkt. Die Variable "val" wird nun nicht mehr überschrieben, sondern 
irgendwas ganz anderes, was aber unter Umständen keinerlei Auswirkungen 
mehr hat. Der Fehler ist dann augenscheinlich verschwunden. Ist er aber 
nicht.

> Erkennt das nicht der compiler?

Nein.

> Ich kann nahezu ausschließen, das ich sowas in meinem selbst
> geschriebenen source  habe.

Das habe ich früher in meinem jugendlichen Leichtsinn auch immer erst 
gedacht. Schmink Dir das ab, der Fehler sitzt meistens vor der Tastatur.

von Hans (Gast)


Lesenswert?

Setz doch einfach einen Watchpoint auf die Variable. Dann hält der 
Debugger das Programm an, sobald auf die Speicherstelle geschrieben 
wird.

von uli (Gast)


Lesenswert?

Eric B.
Tipp am rande. Soltest mal dein feeling checken lassen.

Also ich hab 128kByte ram. 500kByte flash.

Default eingestellt war:
Heap 512 byte
Stack 1024 byte.

Habe das nun vervierfacht.
Heap    800h     2048dez
Stack 1000h     4096dez

Liegt das objekt auf dem stack schlägt es immer noch fehl liegt es auf 
dem heap geht es.
Siehe oben variante 1 und 2.
Auch wenn ich Stack auf 8000h setze geht es mit variante 1 nicht.

Auch wenn ich den parameter, für den task stack, der xCreateTask 
funktion anschließend auf 2000dez setze, .....nada.....
Gleiches verhalten der variante 1.

Zu wenig stack dürfte ausgeschlossen sein.

Und CTelegram hat zwar einen buffer von 200 Byte und ich habe von der 
klasse 2 objekte im thread und dann lass nochmal 400 byte dazukommen.
Die 1k stack werde ich nie benötigen.
Stack wird ja nur benötigt, tja .... wann eigentlich genau.... wenn 
variablen innerhalb einer geschweiften klammer angelegt werden.
Also
{
  int a = 0
}
Läge auf dem stack.
Beim verlassen dieser klammer ist die variable nicht mehr gültig und 
nicht mehr auf dem stack.

von Stefan K. (stefan64)


Lesenswert?

Bei freeRTOS kannst Du stack overflow checking einschalten:
http://www.freertos.org/Stacks-and-stack-overflow-checking.html

Auch interessant:
http://www.freertos.org/a00111.html

Im Übrigen ist diese Haltung:
> Ich kann nahezu ausschließen, das ich sowas in meinem selbst
> geschriebenen source  habe.

selten hilfreich, einen Fehler zu finden. Denn der ist zu 99% im eigenen 
Code - an welcher Stelle auch immer. Eine positive Haltung den eigenen 
Fehlern gegenüber hilft ungemein, diese auch zu finden.

Viele Grüße, Stefan

von uli (Gast)


Lesenswert?

Wie ich den watchpoint setzen soll, da bin ich noch dran.

Ansonsten sehe ich ja beim single Step was passiert und habe das oben ja 
geschrieben.

So geht es nicht...
----------------------------------------------------------


void TaskScheduler(void)
{
  :
  :
  CTelegram oCTelegram(sma_rx_qh);
  :
  :
  xTaskCreate(  oCTelegram.Fn_Thread,
                (const char*)"t3",
                1000,
                &oCTelegram,
                2,
                NULL
             );

  vTaskStartScheduler();

  for(;;)
  {
    // Should never reached.
  }
}



Implementierungen in CTelegram.cpp

void CTelegram::Fn_Thread(void* pvParameters)
{
  HIER PASSIERT WAS MIT "transmittedAndReceived"########
  static_cast<CTelegram*> (pvParameters)->Fn_Process();
  WAS KOMISCH IST ######################################
}

void CTelegram::Fn_Process(void)
{

  uint8_t count = 0;

  for(;;)
  {


*   if(transmittedAndReceived == true)  // Hier habe ich ein Breakpoint
    {
      count+=1;

    }
    count+=2;
  }
}
----------------------------------------------------------
Vor dieser Zeile
static_cast<CTelegram*> (pvParameters)->Fn_Process();
ist die Variable "transmittedAndReceived" false, was stimmt.
NUR SINGLE STEP und kein Schritt weiter  ... also nach dieser Zeile
static_cast<CTelegram*> (pvParameters)->Fn_Process();
ist die Variable "transmittedAndReceived" irgendwas (200), was so nicht
gewollt ist..
Alles andere Verhalten war OK.

Also, ich kenne ja die Stelle, wo das Verbiegen von 
"transmittedAndReceived" zumindest für mich passiert.

Dies ist die Variante 1. Variante 2 mit der es Funktioniert ist auch 
oben.
Daher meine Vermutung, dass ich freeRtos mit Variante 1 nicht richtig 
bedient habe.

Hierzu hat sich leider noch niemand geäußert.

von Stefan K. (stefan64)


Lesenswert?

Welche Optimierung benutzt Du?
Bei eingeschalteter Optimierung zeigt der Debugger oft wildes Zeug für 
Variablen-Werte an.

Gruß, Stefan

von Alex W. (a20q90)


Lesenswert?

uli schrieb:
> Und du glaubst doch net das ich meinen ganzen Source Code hier poste.

Hast recht! Glaub ich nicht! Dann mal viel Spaß beim weiterraten!

Selbst wenn es jetzt funktioniert, später kommt der Bug wieder hoch! Und 
dann gibts Glubschaugen. Sprich: blöder Blick! :-)

von rmu (Gast)


Lesenswert?

uli schrieb:
> Hierzu hat sich leider noch niemand geäußert.

Doch, die gleichlautende Vermutung ist, dass der Fehler im nicht 
gezeigten Code liegt, einmal die Variable "transmittedAndReceived" (sic) 
überschreibt und ein andermal irgendwas anderes, was derzeit offenbar 
ohne negative Konsequenz ist.

von uli (Gast)


Lesenswert?

Eh Axel W. Ich muss mich grad beherrschen.
Wenn ich das alles durchscrolle, kam von dir nur bullshit.

NUN FÜR DICH.

GEHE  AB HIER ZU MEINEM LETZTEN BEITRAG UND LESE IHN.
DORT STEHT DOCH EINDEUTIG DASS VOR DEM AUSFÜHREN VON

static_cast<CTelegram*> (pvParameters)->Fn_Process();

ALLES OK IST UND NACH NUR DIESER ANWEISUNG DIE BESAGTE BOOL VARIABLE

transmittedAndReceived

EINEN ANDEREN WERT HAT.

DER TYPECAST IST OK..... DA DIE FUNKTION

Fn_Process()

ANGESPRUNGEN WIRD.

UND NUN SAGE ER MIR WAS SICH DA IM HINTERGRUND VON MIR UNBEMERKT 
ÜBERSCHREIBEN SOLL?

ALLEN RELEVANTEN SOURCECODE HAT ER.
ERKLÄR MIR MAL DEN UNTERSCHIED DER ZWEI VARIANTEN.

Ein unbemerktes überschreiben von mir schliesse ich nahezu aus. So viel 
quellcode habe ich noch nicht erstellt.

von Walter S. (avatar)


Lesenswert?

uli schrieb:
> Ein unbemerktes überschreiben von mir schliesse ich nahezu aus.

das "nahezu" muss man dir zugute halten, aber dass du ohne Grund deine 
potentiellen Helfer provozierst indem du du irgendwelche Brocken 
hinwirfst anstatt ein kompilierbares, möglichst gekürztes Programm, das 
aber den Fehler zeigt, zu posten ist unverständlich.

Schließlich willst du was von den Leuten

von rmu (Gast)


Lesenswert?

uli schrieb:
> static_cast<CTelegram*> (pvParameters)->Fn_Process();
>
> ALLES OK IST UND NACH NUR DIESER ANWEISUNG DIE BESAGTE BOOL VARIABLE

Fn_Process von oben beinhaltet eine Endlosschleife, da kann man also 
kaum drübersteppen.

von uli (Gast)


Lesenswert?

Habe ja oben geschrieben, dass ich mehr als genug Stack eingestellt 
habe.
Auch dem freeRtos Thread habe ich mit 2000Byte mehr als genug Stack 
gegeben.

Wenn ich das Objekt oCTelegram auf dem Heap anlege, dann ist alles OK.

HEAP

CTelegram *oCTelegram = nullptr;

void TaskScheduler(void)
{

  const uint32_t QUEUE_LENGTH = 1;

  const uint32_t QUEUE_ITEM_SIZE = sizeof(STC_MSG_TELEGRAM*);

  qh = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

  sma_rx_qh = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

  oCTelegram = new CTelegram(sma_rx_qh);  ################

  xTaskCreate(  oCTelegram->Fn_Thread,
            (const char*)"t3",
          2000,
          oCTelegram,
          2,
          NULL
        );

  vTaskStartScheduler();

  for(;;)
  {
    // Should never reached.
  }

}






Version mit STACK .... der besagte Fehler


void TaskScheduler(void)
{

  const uint32_t QUEUE_LENGTH = 1;

  const uint32_t QUEUE_ITEM_SIZE = sizeof(STC_MSG_TELEGRAM*);

  qh = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

  sma_rx_qh = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

  CTelegram oCTelegram(sma_rx_qh);  #####################

  xTaskCreate(  oCTelegram.Fn_Thread,
         (const char*)"t3",
          2000,
    &oCTelegram,
          2,
    NULL
       );

  vTaskStartScheduler();

  for(;;)
  {
    // Should never reached.
  }

}






Version mit RAM geht auch.

QueueHandle_t sma_rx_qh = xyz;    //Beispiel
CTelegram oCTelegram(sma_rx_qh);  #### Modulglobal #######


void TaskScheduler(void)
{

  const uint32_t QUEUE_LENGTH = 1;

  const uint32_t QUEUE_ITEM_SIZE = sizeof(STC_MSG_TELEGRAM*);

  qh = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

  sma_rx_qh = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

  xTaskCreate(  oCTelegram.Fn_Thread,
         (const char*)"t3",
          2000,
    &oCTelegram,
          2,
    NULL
       );

  vTaskStartScheduler();

  for(;;)
  {
    // Should never reached.
  }

}


*Der Queue übergebe ich nur einen Zeiger.
*Stack mehr als genug eingestellt
*Vermutlich (waage) bediene ich in der Stack Version FreeRtos nicht
 richtig. Das ist mit C geschrieben und ich werkel hier mit C++ herum.


CTelegram sieht so aus.

--------------------------------------------------
private:

  const QueueHandle_t sma_rx_qh;

  uint8_t TrnEscapedTelegram[200];

  uint8_t TrnEscapedTelegramLength;

  CSMAData oCSMAData;

  CTelegramBody oTelegramBodyReceived;

  CTelegramBody oTelegramBodyToSend;

  bool transmittedAndReceived = false;


  void Fn_Process(void);
----------------------------------------------------


Ich verabschiede mich nun und konzentriere mich auf die Version die 
läuft.
Ist private Beschäftigung und das Wissen über C++ freeRtos ist im 
entstehen.

von Adam P. (adamap)


Lesenswert?

Walter S. schrieb:
> Schließlich willst du was von den Leuten

...ich glaube er will es einfach nicht begreifen!

Und selbst wenn, könnte man ja wohl den Augen zuliebe die Code-Fragmente 
in
[ c ] [ /c ] Tags setzen!

Vllt. arbeitet er ja für ein super geheime Institution und sein Source 
(in dem ja anscheinend eh nicht viel drin steht) beeinhaltet Infos, die 
nur in Teilen preisgegeben werden können, ohne ein Zusammenhang zu 
erkennen.

kopfschüttel

---

Soviele Code Fragmente (ohne Zusammenhang), die hier gepostet wurden...
da wäre eine *.zip mit dem Projekt wahrscheinlich weniger Code-Zeilen -
und alle könnten sich ein Überblick verschaffen.

von Felix F. (wiesel8)


Lesenswert?

uli schrieb:
> static_cast<CTelegram*> (pvParameters)->Fn_Process();

Hast du schon mal versucht, diese Zeile aufzuspalten?? Hier sind 
ziemlich viele Befehle in einer Zeile verpackt. Das macht das Debuggen 
nicht einfacher.
1
CTelegram *ptr = static_cast<CTelegram*> (pvParameters);
2
ptr->-Fn_Process();

mfg

von Markus F. (mfro)


Lesenswert?

uli schrieb:
> Ansonsten übergebe ich der funktion noch die adresse auf das objekt
> oCTelegram und mache dann einen typcast im Fn_Thread da freeRtos das mit
> c++ nicht auf die reihe bekommt.

vielleicht zeigst Du wenigstens mal die Definition der Klasse 
oCTelegram?

von Eric B. (beric)


Lesenswert?

Wieviel Stack du dein Task gibst ist eh schnurzegal. Die Variabele 
oCTelegram liegt ja nicht im Task, sondern auf dem "allgemeinen" Stack.

Beitrag #5065829 wurde von einem Moderator gelöscht.
Beitrag #5065835 wurde von einem Moderator gelöscht.
Beitrag #5065837 wurde von einem Moderator gelöscht.
Beitrag #5065913 wurde von einem Moderator gelöscht.
Beitrag #5065944 wurde von einem Moderator gelöscht.
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.