Hallo zusammen, gibt es eine möglichkeit bestimmte Teile eines Codes aus der Optimierung zu nehmen ? Als Compiler benutze ich IAR embedded Workbench. Oder ist dies nur möglich in dem der betreffende Code-Abschnitt in Assembler geschrieben wird ?
Die Wahrscheinlichkeit, dass du das gar nicht brauchst liegt bei 90%.
>Die Wahrscheinlichkeit, dass du das gar nicht brauchst liegt bei 90%.
Ich erhöhe auf 99%
Ich habe mit IAR noch nie gearbeitet, kann dir also nicht sagen ob dein Compiler das unterstützt. (bei Keil gibt es diese Funktionalität) Schau in der Hilfe nach Compiler Direktiven (pragma, optimize, ...). Wenn es die Funktion gibt, steht sie auch im Handbuch. Allerdings solltest du dich fragen wofür du das wirklich brauchst...
Ich habe bestimmten Code der erst nach einer Warteschleife ausgeführt werden soll. Ich habe aber festgestellt das je nach Optimierungseinstellungen Teile des Codes anscheinend vor der Warteschleife ausgeführt werden. Ich habe schon versucht alle möglichen Ursachen für das Fehlverhalten auszuschliessen, und jetzt wollte ich es mal damit probieren. Werde dann noch mal schauen ob ich in der Compiler-Hilfe irgendwas finde.
dastien schrieb: > Ich habe aber festgestellt das je nach Optimierungseinstellungen Teile > des Codes anscheinend vor der Warteschleife ausgeführt werden. vielleicht wird ja deine Warteschleife wegoptimiert? Kannst ja mal den Code posten. :-)
Peter schrieb: > Ich erhöhe auf 99% Aber immerhin noch 1%, wo man es doch braucht. dastien schrieb: > gibt es eine möglichkeit bestimmte Teile eines Codes aus der Optimierung > zu nehmen ? Anweisungen an den Compiler werden mit der pragma-Direktive gemacht. Damit solltest du auch Optimierungen ausschalten können. Google mal nach pragma...
@dastien: Sonderlich lang kannst du ja nicht danach gesucht haben. O-Text Manual: #pragma optimize=param[ param...]
dito schrieb: > Aber immerhin noch 1%, wo man es doch braucht. Oder man andere auch nicht sehr elegante Wege einschlagen muss. Ja, eine portable optimization barrier gibt's in C leider nicht. In GCC kann man sich z.B. mit bestimmten leeren asm-statements behelfen, wenn der Compiler beispielsweise eine langsame Division genau in das Codestück reinschiebt, in dem man es partout nicht gebrauchen kann.
Hier der Teil von dem Code der nicht optimiert werden soll.
1 | void detect_short_circuit(void) |
2 | {
|
3 | if(relay_state == ON) |
4 | {
|
5 | for (unsigned long int count = 0; count < 125; count++) |
6 | {
|
7 | asm ("nop"); |
8 | }
|
9 | |
10 | C3_adc_value = Read_ADC_Ch(AD_PORT_SHORT_CIRCUIT_C3); |
11 | if (C3_adc_value < 1000) |
12 | {
|
13 | C3_OFF; |
14 | }
|
15 | |
16 | C2_adc_value = Read_ADC_Ch(AD_PORT_SHORT_CIRCUIT_C2); |
17 | if (C2_adc_value < 1000) |
18 | {
|
19 | C2_OFF; |
20 | }
|
21 | |
22 | C1_adc_value = Read_ADC_Ch(AD_PORT_SHORT_CIRCUIT_C1); |
23 | if (C1_adc_value < 1000) |
24 | {
|
25 | C1_OFF; |
26 | }
|
27 | }
|
28 | }
|
Ich habe jetzt folgendes noch eingefügt
1 | #pragma optimize = no_code_motion
|
Scheint aber immer noch nich richtig zu laufen.
Gibt es in IAR keinerlei Delay-Funktionen? Solche unbewaffneten Delay-Schleifen sind Zeitbomben. Oft reicht schon ein grosszügigerer Umgang mit "volatile" für die beteiligten lokalen Variablen, hier beispielsweise käme der Index der Schleife dafür in Frage.
dastien schrieb: > Ich habe aber festgestellt das je nach Optimierungseinstellungen Teile > des Codes anscheinend vor der Warteschleife ausgeführt werden. Vermutung oder durch Blick in den erzeugten Code? Kannst ja letzteren mal rausrücken, als Disassembly-Listing von dem Stück beispielsweise.
Liefert dein ADC kein Statussignal, das signalisiert wann ein gültiges Cx_adc_value bereit steht?
Habe jetzt die for-Schleife durch
1 | __delay_cycles(5000); |
ersetzt und die Zeit erhöht. Jetzt scheint es erstmal zu funktionieren. Danke für die hilfreichen Antworten.
dastien schrieb: > for (unsigned long int count = 0; count < 125; count++) > { > asm ("nop"); > } Vermutung: Der Compiler optimiert die Schleife weg. Würde das mit dem beobachteten Verhalten übereinstimmen? :-)
Wegoptimiert wird sie nicht. Habe einen Output Pin davor und danch toggeln lassen. Klappt.
Aber die Laufzeit der Schleife ist extrem optimierungsabhängig.
problier mal volatile asm ("nop"); das darf er nicht wegoptimieren
wenn geht sollte die Schleife durch was anderes ersetzt werden.
1 | asm volatile ("nop"); |
würde dem Compiler sicher auch helfen, damit er nichts weg optimiert. Oder auch wie schon oben gesagt die Schleifen Variable als volatile.
thomasH schrieb: > wenn geht sollte die Schleife durch was anderes ersetzt werden.
1 | asm volatile ("nop"); |
Beim IAR Compiler funktioniert das auch? Aber auch dann ist die Laufzeit stark optimierungsabhängig.
Habe es jetzt mit
1 | __delay_cycles(5000); |
gemacht. Funktioniert wunderbar. Ist aus dem Help-File vom IAR-Compiler.
Mein Vorschlag: Compile die C files zu object files (mit den spezifischen Compiler-Optimierungen). Und dann das ganze zu einem binary zusammenlinken. Cheers
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.