Forum: Compiler & IDEs Probleme mit Stringlänge


von Ingo L. (corrtexx)


Lesenswert?

Hallo,
ich habe folgende Funktion:
1
void EA_DOGM163_String( const char *Data )
2
{
3
    while( *Data != '\0' ){
4
      EA_DOGM163_Write_Data ( *Data++ , DATA );
5
    }
6
}
Folgendes geht und geht nicht, ich lande im Reset_Handler meines 
STM32F030 in Coocox wenn es nicht geht:
EA_DOGM163_String( "1" ); // geht
EA_DOGM163_String( "12" ); // geht nicht
EA_DOGM163_String( "123" ); // geht nicht
EA_DOGM163_String( "1234" ); // geht nicht
EA_DOGM163_String( "12345" ); // geht
...6 // geht nicht
...7 // geht nicht
...8 // geht nicht
...9 // geht

Es scheint irgendwas mit der Pointergröße zu tun zu haben? kann mir 
jemand helfen, komme absolut nicht weiter...

Viele Grüße,
Ingo

von Ingo L. (corrtexx)


Lesenswert?

Hier noch:
1
void EA_DOGM163_Write_Data ( uint8_t Data, int RS )
2
{
3
  if ( RS ) {
4
     GPIOB->ODR |= GPIO_Pin_0;
5
  }else {
6
    GPIOB->ODR &= ~GPIO_Pin_0;
7
  }
8
  /* ChipSelect low */
9
  GPIOA->ODR &= ~ GPIO_Pin_6;
10
  SPI_SendData8( SPI1 , Data );
11
  MyDelayUS( LCD_WRITEDATA_US );
12
  /* ChipSelect high */
13
  GPIOA->ODR |= GPIO_Pin_6;
14
}

von Walter T. (nicolas)


Lesenswert?

Ingo L. schrieb:
> SPI_SendData8( SPI1 , Data );

Das prüft selbstständig, ob der vorhergehende Transfer abgeschlossen 
ist?

von Mitlesa (Gast)


Lesenswert?

Walter T. schrieb:
> Das prüft selbstständig, ob der vorhergehende Transfer abgeschlossen
> ist?

Das wird nicht reichen.

Die selbstgebaute MyDelayUS ist ein protentieller Fehlerbringer.

Ausserdem wird bei zwei aufeinanderfolgenden Zeichen der
Chipselect so schnell wieder betätigt dass ein Display
eventuell noch zu beschäftigt ist.

CS:   ~~~~~~\__________/~\__________/~~~~
(hier ------------------^----------------

von Ingo Less (Gast)


Lesenswert?

Wenn ich die Funktion ...WriteData händisch aufrufen und mit einem 
Zeichen versehe und das ganze n mal, gibts keine Probleme. Das MyDelayUS 
hatte ich garnicht auf dem Schirm, die dürfte aber tendenziell viel zu 
lange dauern, da sie 1:1 von einem 168MHz F4 übernommen wurde und noch 
nicht angepasst wurde (schäm). Wenn das natürlich nicht passt oder es 
sogar weg optimiert wird, wäre ein ResetHandler nur logisch. An der 
Funktion an sich kann es nicht liegen? Ich kann es leider erst morgen 
früh wieder an der Hardware testen...

von Ingo Less (Gast)


Lesenswert?

Was jedoch etwas unlogisch ist, ist das 1,5,9 usw. Zeichen im String 
funktionieren. Das spricht gegen die These eines zu knappen Delays oder?

von Ingo Less (Gast)


Lesenswert?

Keiner weitere Ideen?

von eagle user (Gast)


Lesenswert?

1, 5, 9 spricht für ein Alignment-Problem. Der M0 ist dabei 
anspruchsvoller als der M4.

von Ingo Less (Gast)


Lesenswert?

Kannst du das näher ausführen?

von eagle user (Gast)


Lesenswert?

Die Cortex-M haben 32 Bit breite Register. Wenn man eine möglichst 
einfache CPU bauen will, kann die nur 32 Bit am Stück verarbeiten und 
speichern. Um ein einzelnes Zeichen (char, uint8_t, 8 Bit) aus dem 
Speicher in ein Register zu laden, sind zusätzliche Befehle und 
Multiplexer nötig. Die hat der M0 zwar auch, aber Flash, RAM und 
Peripherie-Register müssen das auch unterstützen.

Der Compiler muss für jede Zeile C wissen, ob da ein 32-Bit Befehl 
funktioniert oder ob er vier 8-Bit Befehle einbauen muss. Optimal wäre 
natürlich ein einzelner Befehl, aber das geht eben nicht immer mit jeder 
CPU.

Soviel zur Theorie. Praktisch habe ich nur eine doofe Idee, was bei dir 
faul sein könnte: du übersetzt das Programm für einen F4 (=M4) statt für 
deinen F030 (=M0).

von Ingo L. (corrtexx)


Lesenswert?

Ich habe einfach mal die 4.8 Toolchain benutzt und dann ging es. 
Komischerweise, als ich dann wieder auf die 6.2017.q1 zurück bin, ging 
es dann auch dort. Jetzt bin ich zwar glücklich das es geht, aber es ist 
unbefriedigend nicht zu wissen warum.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ingo L. schrieb:
> EA_DOGM163_Write_Data ( *Data++ , DATA );

Wenn EA_DOGM163_Write_Data() ein Makro ist, welches den ersten Parameter 
mehrfach verwendet, geht das in die Hose. Dann wird nämlich der 
Inkrement, den Du da eingebaut hast, mehrfach ausgeführt. Das hätte dann 
zur Folge, dass gar nichts oder nur ein Teil des Strings ausgegeben 
wird.

Bevor man da als Programmierer in den include-Dateien stundenlang 
rumsucht, ob das denn nun ein Macro oder eine richtige Funktion ist, 
kann ich Dir nur den Tipp geben: Lass das mit dem Increment von 
Makro-/Funktionsparametern. Vor 30 Jahren war das vielleicht noch ein 
Hinweis an den Compiler, dass er hier irgendein Register optimieren 
kann, heutzutage ist das komplett irrelevant.

Schreibe also:
1
  EA_DOGM163_Write_Data ( *Data , DATA );
2
  Data++;

und Du lebst wesentlich stressfreier.

von Dirk B. (dirkb2)


Lesenswert?

Frank M. schrieb:
> Wenn EA_DOGM163_Write_Data() ein Makro ist,

Im zweiten Post steht doch die gesamte Funktion.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Dirk B. schrieb:
> Im zweiten Post steht doch die gesamte Funktion.

Upps, das habe ich tatsächlich übersehen. :-)

von Ingo L. (corrtexx)


Lesenswert?

Also den konkreten Fehler konnte ich nicht finden. Wie gesagt: einmal 
mit einer anderen Toolchain "gebuildet" und es lief und dann auch mit 
der, die vorher nutzte. Ich bin jetzt aber insgesamt auf EmBitz 
umgestiegen, nur Theater mit Atollic gehabt:
Beitrag "Re: SPL und Atollic"

Coocox ist auch cool, aber leider wird es nicht mehr gepflegt und neue 
Controller nicht eingebaut.

von Markus F. (mfro)


Lesenswert?

Das ist einigermassen unwahrscheinlich; meine Compiler machen mit den 
gleichen Quellen immer dasselbe, egal wie oft ich es probiere (auch wenn 
ich bei manchen Problemen gern was anderes glauben möchte).

Du hast (wahrscheinlich unbeabsichtigt) was anderes verändert. Aber das 
wird man jetzt wohl nicht mehr nachvollziehen können.

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.