Forum: Compiler & IDEs avr-gcc 4.5.1 zu 4.8.3 andere Anordnung im EEPROM?


von Holm T. (Gast)


Lesenswert?

Hallo Leute,

Ich habe allerlei Software die ich für Kunden geschrieben habe und habe 
nun nach einem OS Update das Problem das nach dem Update von 
avr-gcc2.5.1 zu avr-gcc 4.8.3 plötzlich das Zeuch nicht mehr 
funktioniert..

Beispiel:
1
struct  ee_setpar{
2
                uint16_t        startfreq;
3
                uint16_t        endfreq;
4
                uint8_t         micsteps;
5
                uint8_t         steps;
6
                uint8_t         ramptime;
7
                uint8_t         current;
8
                uint8_t         decay;
9
                uint8_t         torque;
10
                };
11
//0x00
12
const uint16_t pl0              EEMEM =0xffff; // Platzhalter
13
const uint16_t eessw            EEMEM =10000; // Startschrittweite
14
const uint16_t pl2              EEMEM =0xffff;
15
const uint16_t pl3              EEMEM =0xffff;
16
const uint16_t pl4              EEMEM =0xffff;
17
const uint16_t pl5              EEMEM =0xffff;
18
const uint16_t pl6              EEMEM =0xffff;
19
const uint16_t pl7              EEMEM =0xffff;
20
//0x10
21
const uint16_t pl8              EEMEM =0xffff;
22
const uint16_t pl9              EEMEM =0xffff;
23
const uint16_t pl10             EEMEM =0xffff;
24
const uint16_t pl11             EEMEM =0xffff;
25
const uint16_t pl12             EEMEM =0xffff;
26
const uint16_t pl13             EEMEM =0xffff;
27
const uint16_t pl14             EEMEM =0xffff;
28
const uint16_t pl15             EEMEM =0xffff;
29
30
const uint16_t set0_startfreq   EEMEM   = 800;
31
const uint16_t set0_endfreq     EEMEM   = 16000;
32
const uint8_t set0_micsteps     EEMEM   = 2;    /* Microstepmode */
33
const uint8_t set0_steps        EEMEM   = 8;
34
const uint8_t set0_ramptime     EEMEM   = 64; /* Steps pro Frequenz in Rampe */
35
const uint8_t set0_current      EEMEM   = 1;
36
const uint8_t set0_decay        EEMEM   = 0;    /* 0..2 */
37
const uint8_t set0_torque       EEMEM   = 0;    /* 0..2 */
38
39
const uint16_t set1_startfreq   EEMEM   = 800;
40
const uint16_t set1_endfreq     EEMEM   = 8000;
41
const uint8_t set1_micsteps     EEMEM   = 2;
42
const uint8_t set1_steps        EEMEM   = 8;
43
const uint8_t set1_ramptime     EEMEM   = 64;
44
const uint8_t set1_current      EEMEM   = 1;
45
const uint8_t set1_decay        EEMEM   = 0;    /* 0..2 */
46
const uint8_t set1_torque       EEMEM   = 0;    /* 0..2 */

dieser Header compilierte mit 4.5.1 so wie in diesem map file angegeben:
1
.eeprom         0x00810000       0x34
2
 *(.eeprom*)
3
 .eeprom        0x00810000       0x34 transport.o
4
                0x00810000                pl0
5
                0x00810002                eessw
6
                0x00810004                pl2
7
                0x00810006                pl3
8
                0x00810008                pl4
9
                0x0081000a                pl5
10
                0x0081000c                pl6
11
                0x0081000e                pl7
12
                0x00810010                pl8
13
                0x00810012                pl9
14
                0x00810014                pl10
15
                0x00810016                pl11
16
                0x00810018                pl12
17
                0x0081001a                pl13
18
                0x0081001c                pl14
19
                0x0081001e                pl15
20
                0x00810020                set0_startfreq
21
                0x00810022                set0_endfreq
22
                0x00810024                set0_micsteps
23
                0x00810025                set0_steps
24
                0x00810026                set0_ramptime
25
                0x00810027                set0_current
26
                0x00810028                set0_decay
27
                0x00810029                set0_torque
28
                0x0081002a                set1_startfreq
29
                0x0081002c                set1_endfreq
30
                0x0081002e                set1_micsteps
31
                0x0081002f                set1_steps
32
                0x00810030                set1_ramptime
33
                0x00810031                set1_current
34
                0x00810032                set1_decay
35
                0x00810033                set1_torque
36
                0x00810034                __eeprom_end = .
37
38
.fuse
39
 *(.fuse)

und bei 4.8.3 steht das Ganze plötzlich auf dem Kopf:
1
.eeprom         0x00810000       0x34
2
 *(.eeprom*)
3
 .eeprom        0x00810000       0x34 transport.o
4
                0x00810000                set1_torque
5
                0x00810001                set1_decay
6
                0x00810002                set1_current
7
                0x00810003                set1_ramptime
8
                0x00810004                set1_steps
9
                0x00810005                set1_micsteps
10
                0x00810006                set1_endfreq
11
                0x00810008                set1_startfreq
12
                0x0081000a                set0_torque
13
                0x0081000b                set0_decay
14
                0x0081000c                set0_current
15
                0x0081000d                set0_ramptime
16
                0x0081000e                set0_steps
17
                0x0081000f                set0_micsteps
18
                0x00810010                set0_endfreq
19
                0x00810012                set0_startfreq
20
                0x00810014                pl15
21
                0x00810016                pl14
22
                0x00810018                pl13
23
                0x0081001a                pl12
24
                0x0081001c                pl11
25
                0x0081001e                pl10
26
                0x00810020                pl9
27
                0x00810022                pl8
28
                0x00810024                pl7
29
                0x00810026                pl6
30
                0x00810028                pl5
31
                0x0081002a                pl4
32
                0x0081002c                pl3
33
                0x0081002e                pl2
34
                0x00810030                eessw
35
                0x00810032                pl0
36
                0x00810034                __eeprom_end = .
37
38
.fuse

dementsprechend sehen auch die Hex files aus:
:10000000FFFF1027FFFFFFFFFFFFFFFFFFFFFFFFC7
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:100020002003803E0208400100002003401F020818
:04003000400100008B
:00000001FF

versus:

:10000000000001400802401F2003000001400802D8
:10001000803E2003FFFFFFFFFFFFFFFFFFFFFFFF0B
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:040030001027FFFF97
:00000001FF

Beziehungsweise binär:
1
00000000  ff ff 10 27 ff ff ff ff  ff ff ff ff ff ff ff ff  |...'............|
2
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
3
00000020  20 03 80 3e 02 08 40 01  00 00 20 03 40 1f 02 08  | ..>..@... .@...|
4
00000030  40 01 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |@...............|
5
00000040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
6
*
versus
1
00000000  00 00 01 40 08 02 40 1f  20 03 00 00 01 40 08 02  |...@..@. ....@..|
2
00000010  80 3e 20 03 ff ff ff ff  ff ff ff ff ff ff ff ff  |.> .............|
3
00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
4
00000030  10 27 ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |.'..............|
5
00000040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
6
*


Warum ist das so und wie werde ich das wieder los?
Der Kunde hantiert mit einem externen Editor (Exel Sheet) in dem Binary
des .eep files herum um dort Parameter anzupassen.
Wenn das so bleibt muß ich nicht nur die Software selbst ändern sondern 
auch diese Tools abhängig von der gerade benutzen Compiler Version..was 
soll das also? Habe ich was Wesentliches verpasst? Wird das irgendwo 
beschrieben?

Gruß,

Holm

von Clemens L. (c_l)


Lesenswert?

Holm T. schrieb:
> Warum ist das so

Weil der C-Standard für globale Variablen keine bestimme Reihenfolge 
garantiert.

> und wie werde ich das wieder los?

Alles in ein struct packen:
1
const struct {
2
    uint16_t pl0;
3
    uint16_t eessw;
4
    ...
5
} das_Zeuch EEMEM = {
6
    .pl0   = 0xffff, // Platzhalter
7
    .eessw = 10000,  // Startschrittweite
8
    ...
9
};

: Bearbeitet durch User
von visitor (Gast)


Lesenswert?

Dein eigentliches Problem besteht darin, dass das ursprüngliche 
SW-Konzept mit der nachträglichen Parameteranpassung im *.eep File 
schlecht ist.
Sauberer und sicherer wäre es gewesen, die Parameter via serieller 
Kommunikation über den µC in das Eeprom zu übertragen, damit gelangen 
die Parameter immer an die richtige Stelle unabhängig welche 
Compilerversion benutzt wird.

Deine beschriebene Vorgehensweise kenne ich auch aus Produkten der 
Vergangenheit, die einfach nicht abgekündigt werden. Letztlich stehst du 
nun vor dem Problem: neues Konzept inkl. den Kunden davon zu überzeugen 
(= Zeit + Geld) oder ein Workaround zu schaffen, welches in einiger Zeit 
wieder zu einem Problem führt!

Hier solltest du im Vorfeld alle Für und Wieder prüfen und gut guten 
Argumenten zusammen mit dem Kunden die für euch beste Lösung finden.

Frage:
War das Compilerupdate notwendig? Andernfalls arbeite doch mit dem alten 
Compiler weiter, das würde das Problem zumindest verschieben!

von Nase (Gast)


Lesenswert?

visitor schrieb:
> War das Compilerupdate notwendig? Andernfalls arbeite doch mit dem alten
> Compiler weiter, das würde das Problem zumindest verschieben!
Und zwar genau so lange, bis du irgendeine neue Variable ins EEPROM 
ablegst.

visitor schrieb:
> Sauberer und sicherer wäre es gewesen, die Parameter via serieller
> Kommunikation über den µC in das Eeprom zu übertragen, damit gelangen
> die Parameter immer an die richtige Stelle unabhängig welche
> Compilerversion benutzt wird.
Die Theorie ist fein.
Lustig wirds, wenn du ein Firmwareupdate des Controllers machst...

von Holm T. (Gast)


Lesenswert?

Clemens L. (c_l) schrubtete:
>Weil der C-Standard für globale Variablen keine bestimme Reihenfolge
>garantiert.

..das der C-Standard das nicht garantiert bedeutet aber noch lange nicht 
das eine Compiler-Sub-Release für eine Architektur das so mirnichts 
dirnichts ändern sollte.. oder spinne ich?

Ich werde versuchen das in Structs zu verhäkeln.

visitor schrieb:
> Dein eigentliches Problem besteht darin, dass das ursprüngliche
> SW-Konzept mit der nachträglichen Parameteranpassung im *.eep File
> schlecht ist.
> Sauberer und sicherer wäre es gewesen, die Parameter via serieller
> Kommunikation über den µC in das Eeprom zu übertragen, damit gelangen
> die Parameter immer an die richtige Stelle unabhängig welche
> Compilerversion benutzt wird.

Unsinn.
Es ist nicht der Endkunde der darin herumeändert, es ist der Produzent 
von Geräten der den u.a. Schrittmotorantrieb seiner Geräte uf das 
spezifische Modell paramerisiert und 1 Mal pro Gerät den Flash und den 
EEPROM vor der Auslieferung programmiert.
Dazu hat er ein fertiges Hex File und konfiguriert den EEPROM Inhalt
vor dem bruzeln mit Seriennummer und den Motorparametern wie zu fahrende 
Wege u.A.
Das macht der glaube ich seit Zeiten zu denen gcc-2.x noch aktuell war.
Nur weil es den Compilergurus plötzlich vom Arsch in den Kopf steigt das 
innerhalb einer Mainrelease (4) des Compilers plötzlich anders herum zu 
anzuordnen erfinde ich doch keinen Lader der Platz im Flash braucht um 
das
andersherum da einzufädeln..



>
> Deine beschriebene Vorgehensweise kenne ich auch aus Produkten der
> Vergangenheit, die einfach nicht abgekündigt werden. Letztlich stehst du
> nun vor dem Problem: neues Konzept inkl. den Kunden davon zu überzeugen
> (= Zeit + Geld) oder ein Workaround zu schaffen, welches in einiger Zeit
> wieder zu einem Problem führt!

Genau.

>
> Hier solltest du im Vorfeld alle Für und Wieder prüfen und gut guten
> Argumenten zusammen mit dem Kunden die für euch beste Lösung finden.
>
> Frage:
> War das Compilerupdate notwendig? Andernfalls arbeite doch mit dem alten
> Compiler weiter, das würde das Problem zumindest verschieben!

Das Compilerupdate hat sich aus der Neuinstallation des Betriebssystems 
meines Rechners ergeben (FreeBSD10) auf einem Laptop habe ich noch die 
ältere Release.


Gruß,

Holm

von Peter II (Gast)


Lesenswert?

Holm T. schrieb:
> Das Compilerupdate hat sich aus der Neuinstallation des Betriebssystems
> meines Rechners ergeben (FreeBSD10) auf einem Laptop habe ich noch die
> ältere Release.

und was sagt dir das.

Zu einem Projekt sichert man alles was zur Erzeugung notwendig ist. Man 
darf sich nicht einfach darauf verlassen, das man ohne Probleme eine 
neue Version einsetzen kann. Dafür müsste man die komplette QS machen.

Wenn Fehler in einer alten Version noch behoben werden soll, dann sollte 
man das auch mit den alten Compiler machen.

von Clemens L. (c_l)


Lesenswert?

Holm T. schrieb:
> ... bedeutet aber noch lange nicht
> das eine Compiler-Sub-Release für eine Architektur das so mirnichts
> dirnichts ändern sollte.. oder spinne ich?

Bei gcc gibt es solche Garantien nur für Änderungen der dritten Stelle 
der Versionsnummer.

von Holm T. (Gast)


Lesenswert?

Peter II schrieb:
> Holm T. schrieb:
>> Das Compilerupdate hat sich aus der Neuinstallation des Betriebssystems
>> meines Rechners ergeben (FreeBSD10) auf einem Laptop habe ich noch die
>> ältere Release.
>
> und was sagt dir das.
>
> Zu einem Projekt sichert man alles was zur Erzeugung notwendig ist. Man
> darf sich nicht einfach darauf verlassen, das man ohne Probleme eine
> neue Version einsetzen kann. Dafür müsste man die komplette QS machen.
>
> Wenn Fehler in einer alten Version noch behoben werden soll, dann sollte
> man das auch mit den alten Compiler machen.

Mach Dir keinen Kopf darüber, ich bin problemlos in der Lage eine ältere 
Version zu bauen.

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

Clemens L. schrieb:
> Holm T. schrieb:
>> ... bedeutet aber noch lange nicht
>> das eine Compiler-Sub-Release für eine Architektur das so mirnichts
>> dirnichts ändern sollte.. oder spinne ich?
>
> Bei gcc gibt es solche Garantien nur für Änderungen der dritten Stelle
> der Versionsnummer.

..Garantieen? Du beliebst zu scherzen...


Gruß,

Holm

von Clemens L. (c_l)


Lesenswert?

Holm T. schrieb:
> Clemens L. schrieb:
>> Bei gcc gibt es solche Garantien ...
>
> ..Garantieen? Du beliebst zu scherzen...

Das ist natürlich eine 200%-Geld-zurück-Garantie.  :)

Aber konkret: solch eine Imkompatibilität in 4.5.x würde als ein Bug 
behandelt werden. (Und in > 4.5 eben nicht.)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Holm T. schrieb:
> Clemens L. (c_l) schrubtete:
>>Weil der C-Standard für globale Variablen keine bestimme Reihenfolge
>>garantiert.
>
> ..das der C-Standard das nicht garantiert bedeutet aber noch lange nicht
> das eine Compiler-Sub-Release für eine Architektur das so mirnichts
> dirnichts ändern sollte.. oder spinne ich?

Es hat sich nichts geändert:

Es war in der alten Version nicht spezifiziert, und es ist in der neuen 
Version immer noch nicht spezifiziert.

Falls du unbedingt die Anordnung wie in der Quelle willst, dann mit 
-fno-toplevel-reorder.

Alternativ kannst du auch eine eigenes Linker-Description File bemühen 
und die Objekte händisch darin aufzählen.

Dritte lösung ist, die Objekte in entsprechende Sections zu legen (z.B. 
per -fdata-sections oder per section_attribute) und per 
Linker-Description File die Input-Section so in der gewünschten 
Output-Section anordnen, dass die Reihenfolge ist wie gewünscht.

Vierte Lösung wurde bestimmt schon genannt: Alles in eine Struktur.

Fünfte Lösung: Suboptimaler Hack ist die Adressen von Hand anzugeben.


Generell ist es überaus schlechter Stil (und m.E. unprofessionell), sich 
auf Undefined Behaviour oder Unspecified Behaviour zu verlassen!

von Holm T. (Gast)


Lesenswert?

Johann L. schrieb:
> Holm T. schrieb:
>> Clemens L. (c_l) schrubtete:
>>>Weil der C-Standard für globale Variablen keine bestimme Reihenfolge
>>>garantiert.
>>
>> ..das der C-Standard das nicht garantiert bedeutet aber noch lange nicht
>> das eine Compiler-Sub-Release für eine Architektur das so mirnichts
>> dirnichts ändern sollte.. oder spinne ich?
>
> Es hat sich nichts geändert:
>
> Es war in der alten Version nicht spezifiziert, und es ist in der neuen
> Version immer noch nicht spezifiziert.

Nunja.. es gab bisher damit keine Sorgen von Version 2.7 bis jetzt.

>
> Falls du unbedingt die Anordnung wie in der Quelle willst, dann mit
> -fno-toplevel-reorder.

Genau nach Sowas hatte ich gesucht, es aber nicht gefunden. Danke!

>
> Alternativ kannst du auch eine eigenes Linker-Description File bemühen
> und die Objekte händisch darin aufzählen.
>
> Dritte lösung ist, die Objekte in entsprechende Sections zu legen (z.B.
> per -fdata-sections oder per section_attribute) und per
> Linker-Description File die Input-Section so in der gewünschten
> Output-Section anordnen, dass die Reihenfolge ist wie gewünscht.
>
> Vierte Lösung wurde bestimmt schon genannt: Alles in eine Struktur.
>
> Fünfte Lösung: Suboptimaler Hack ist die Adressen von Hand anzugeben.
>
>
> Generell ist es überaus schlechter Stil (und m.E. unprofessionell), sich
> auf Undefined Behaviour oder Unspecified Behaviour zu verlassen!

Ich werde das überarbeiten aber es ist gut das ich das nicht alles auf 
ein Mal machen muß.
Diese Art das EEPROM File zu bearbeien stammt nicht mal von mir, aber 
ich mußte die halt weiter verwenden.

Gruß,

Holm

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.