Forum: Compiler & IDEs STM32 - keine ISR, wegoptimierte Variable


von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Huhu!

Folgender Code, keinerlei ISR:
1
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
2
{
3
  /* Check the parameters */
4
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
5
  
6
  /* Return the data in the DR register */
7
  return SPIx->DR;    // SPIx->DR ist ein Pointer auf ein Register, in der mein neuer Wert für jdid drinsteht.
8
}
9
10
void ExternFlash::ReadBytes(uint8_t * byte_arr, uint32_t amount)
11
{
12
  for (int i = 0; i < amount; i++)
13
  {
14
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
15
    SPI_I2S_SendData(SPI2, 0x00);
16
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
17
    byte_arr[i] = SPI_I2S_ReceiveData(SPI2);
18
  }
19
}
20
21
bool ExternFlash::CheckID(uint8_t jedecid, uint32_t uniqueid)
22
{
23
  uint8_t jdid;
24
  uint32_t uid;
25
26
  // Check JEDEC ID
27
  SetCSLow();
28
  SendCommand(JEDECID);
29
  ReadBytes((uint8_t*)&jdid, 1);
30
  SetCSHigh();
31
  if (jdid != jedecid)
32
    return false;
33
34
  System::DELAY delay(1);
35
36
  // Check Unique ID
37
  SetCSLow();
38
  SendCommand(UNIQUEID);
39
  WaitForBytes(4);
40
  ReadBytes((uint8_t*)&uid, 4);
41
  SetCSHigh();
42
43
  if (uid != uniqueid)
44
    return false;
45
46
  return true;
47
}

jdid wird mit -o3 wegoptimiert, muss ich das wirklich auf volatile 
setzen?
uid wird komischerweise nicht wegoptimiert.

Danke und viele Grüße aus Ulm!
Reggie

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Reginald L. schrieb:
> jdid wird mit -o3 wegoptimiert

Wird die damit verbundene Funktionalität entfernt? Oder wird bloss das 
Byte im Speicher wegoptimiert, aber das Programm tut was es soll?

Du hast Anspruch darauf, dass ein Programm sich wie beschrieben verhält. 
Nicht aber, dass ein auf aggressiv eingestellter Optimizer den Code 
Zeile für Zeile und Byte für Byte genau so umsetzt, wie der Quellcode 
suggeriert.

Erklärung: Da der Compiler bei
  ReadBytes((uint8_t*)&jdid, 1);
den Quellcode kennt und wohl inlined, merkt er in der Umsetzung des 
Codes der Funktion, dass es um genau 1 Byte geht und wird dieses Byte 
ohne Umweg über Speicher direkt im Register belassen.

Bei uid ist das jedoch nicht so einfach, weil 4 Bytes.

: Bearbeitet durch User
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

A. K. schrieb:
> Wird die damit verbundene Funktionalität entfernt? Oder wird bloss das
> Byte im Speicher wegoptimiert, aber das Programm tut was es soll?
Puh, schwer zu sagen, ich schaffe erst seit ein paar Tagen mit 
Compiler-Optimierungen. Breakpoints kann ich bspws. nur auf dem ersten 
und letzten return setzen. Der Breakpoint am return der uid wird 
automatisch gelöscht.

A. K. schrieb:
> Nicht aber, dass ein auf aggressiv eingestellter Optimizer den Code
> Zeile für Zeile und Byte für Byte genau so umsetzt, wie der Quellcode
> suggeriert.
Achso OK, ich verstehe. Also kann man debuggen eigentlich vergessen. 
Kann man dann überhaupt 100%-ig sicher sein, dass ein größeres Programm 
genau das tut, was man von ihm verlangt?

von (prx) A. K. (prx)


Lesenswert?

Reginald L. schrieb:
> Achso OK, ich verstehe. Also kann man debuggen eigentlich vergessen.

Bei -O3 kann man im Debugger recht seltsame Erlebnisse haben, ja. Am 
besten funktioniert ein Debugger ohne Optimierung.

> Kann man dann überhaupt 100%-ig sicher sein, dass ein größeres Programm
> genau das tut, was man von ihm verlangt?

Nur wenn man es gemäss dem C Standard 100%-ig richtig formuliert hat.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Aber ich glaube du hast schon recht gehabt, dass die Funktionalität des 
Programms gegeben ist. Es verhält sich genau so, wie vorher, nur dass 
Debuggen nicht mehr wirklich funktioniert.

A. K. schrieb:
> Nur wenn man es gemäss dem C Standard 100%-ig richtig formuliert hat.
Wer kann sowas bei größeren Programmen, Gott? :)

Vielen Dank für die Hilfestellung, ich weiß jetzt bescheid.

von Hanswurst (Gast)


Lesenswert?

Reginald L. schrieb:
> A. K. schrieb:
>> Wird die damit verbundene Funktionalität entfernt? Oder wird bloss das
>> Byte im Speicher wegoptimiert, aber das Programm tut was es soll?
> Puh, schwer zu sagen, ich schaffe erst seit ein paar Tagen mit
> Compiler-Optimierungen. Breakpoints kann ich bspws. nur auf dem ersten
> und letzten return setzen. Der Breakpoint am return der uid wird
> automatisch gelöscht.
>
> A. K. schrieb:
>> Nicht aber, dass ein auf aggressiv eingestellter Optimizer den Code
>> Zeile für Zeile und Byte für Byte genau so umsetzt, wie der Quellcode
>> suggeriert.
> Achso OK, ich verstehe. Also kann man debuggen eigentlich vergessen.
> Kann man dann überhaupt 100%-ig sicher sein, dass ein größeres Programm
> genau das tut, was man von ihm verlangt?

Du hast, denke ich, die Aussage nicht vollständig erfasst.

Die Optimierung wird dann Variablen wegfallen lassen, wenn sie die 
gleiche durch den Code beschrieben Funktionalität auch ohne sie erzeugen 
kann.

Der Effekt ist also nur, dass Du die Variable im Debugger nicht mehr 
siehst oder anzeigen lassen kannst. In einigen Fällen entfallen auch 
Codeteile, auf die Du dann keine Breakpoints mehr setzen kannst.

ABER: Die Funktionalität ist (in der Regel, also nur dann nicht, wenn 
ein Fehler im Compiler vorliegt - und das ist ausgesprochen selten) 
haargenau die selbe.

Daher: Testet und debuggt man einen Code erst einmal ohne Optimierung. 
Erst wenn das gelungen ist, schaltet man die Optimierung ein.

Wenn es dann Fehler gibt, dann liegt ein anderer Fall vor. Nämlich der, 
dass Du zwar syntaktisch korrekt eine interpretierbare Anweisung 
hingeschrieben hast, die aber nicht tatsächlich unter allen relevanten 
Umständen, dass machst, was Du tatsächlich beschreiben wolltest.

Du kannst also sicher sein, das getester und debuggter Code tut was er 
aussagt. Nur kannst Du nicht sicher sein, dass Du Dich hundertprozentig 
korrekt ausgedrückt hast.
Das ist ein Unterschied zu, der Compiler macht was er will ohne das Du 
darüber Kontrolle hast.

Obwohl ich selbst sehr gerne in C programmiere, muss ich einräumen, dass 
auch ich immer wieder mal über etwas abwegige Deutungen stolpere, die 
aber nichts desto trotz durch den Standard (mehr oder weniger klar) 
beschrieben sind. Das zeigt sich aber eben genau bei der Optimierung. 
Die Optimierung ist extrem "konservativ" und geht nach dem "Buchstaben 
des Gesetzes". Anders als wir Menschen. Das ist das Problem. Es sitzt 
vor dem Bildschirm.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Hanswurst schrieb:
> Du hast, denke ich, die Aussage nicht vollständig erfasst.
Ich habe mich undeutlich ausgedrückt, genauso wie du es beschreibst, 
habe ich es verstanden :)

von (prx) A. K. (prx)


Lesenswert?

Reginald L. schrieb:
>> Nur wenn man es gemäss dem C Standard 100%-ig richtig formuliert hat.
> Wer kann sowas bei größeren Programmen, Gott? :)

Deshalb gibt es auch keine 100%-ig fehlerfreie grössere Programme. Auch 
Gott hat bekanntlich seinen ersten Ansatz (Paradies) völlig versemmelt 
und auch den zweiten nach längeren Tests in grossen Teilen wieder 
vernichtet (Noah).

von Hanswurst (Gast)


Lesenswert?

Reginald L. schrieb:
> Hanswurst schrieb:
>> Du hast, denke ich, die Aussage nicht vollständig erfasst.
> Ich habe mich undeutlich ausgedrückt, genauso wie du es beschreibst,
> habe ich es verstanden :)

Aha. Schön. Viel Erfolg, weiterhin.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

A. K. schrieb:
> Auch
> Gott hat bekanntlich seinen ersten Ansatz (Paradies) völlig versemmelt
Mal davon abgesehen, dass ich ich absolut nicht bibeltreu bin:
Vielleicht war ja genau das der Plan ;)

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.