Forum: Compiler & IDEs Probleme bei Konvertierung von IAR zu GCC


von Felix (Gast)


Lesenswert?

Hallo,

ich habe ein Problem bei der Umsetzung eines Codes vom IAR zum GCC.

Im IAR sieht es so aus:
1
__regvar __no_init volatile union{
2
                                  uchar R_flag0;
3
                                  struct{
4
                                         uchar
5
                                            bFlag_Packet_Transimit:1,
6
                                            bFlag_Calibration_Status:1;                                            
7
                                        };
8
                                 }@ 0x0f;


Im Prinzip wird doch dort das Register R15 gelocked, bis ein 
entsprechender Funktionsaufruf stattfindet der dieses Register dann 
nutzt. Was ich aber nicht verstehe ist dass eigentlich keine Instanz 
definiert ist.

Kann mir einer erklären was diese Funktion genau macht und wie ich sie 
auf dem GGC umsetzen kann?

Vielen Dank!

von Oliver (Gast)


Lesenswert?

Das ist keine Funktion, sondern (vermutlich) die Deklaration einer 
globalen Variable im Register 15.

Und m.E. geht so etwas mit dem gcc nicht.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

__regvar  deutet zwar auf eine 'Variable in einem Register' hin, 
allerdings ist mir nicht ganz klar, warum ausgerechnet r15 da so einen 
Sonderfall haben soll. Die Bezeichnungen der Member deuten für mich eher 
darauf hin, dass es sich hier um ein Statusregister einer externen 
Komponente handelt, die irgendwie in den Adressraum eingeblendet wird.

Wenn das so nicht zu klären ist, wird man wohl nicht umhin kommen, den 
verwendenden Code zu studieren, wobei u.U auch die ganze Hardware 
drumherum, auf die hier IMHO Bezug genommen wird, berücksichtigt werden 
muss.

Zeig doch mal etwas mehr Code drumherum. Vielleicht bringt das etwas 
mehr Licht in die Sache.

von Felix (Gast)


Lesenswert?

Hi, danke für die schnellen Antworten!

Im restlichen Code wird nur die Variable "bFlag_Packet_Transimit" aus 
dem union verwendet. Und die wird eigentlich nur als Schleifenbedingung 
genutzt.

Siehe hier:
1
#if debug_Master        
2
            if(bFlag_Packet_Transimit)
3
            { 
4
                output_ledRed^=true;
5
                A71_Fifo_Write(&send[0]);
6
                PORTB |= (1 << 3);
7
                RF_Setup_transmiter(); 
8
                while(GPIO1_WTR){};
9
                
10
                PORTB &= ~(1 << 3);
11
                
12
                bFlag_Packet_Transimit= false;                
13
                send_count    = 10;
14
            }

Dazu der Timer Interrupt der die Variable wieder setzt:
1
#pragma      vector = TIMER1_COMPA_vect
2
__interrupt  void  Timer1_CompareA_Entry(void)
3
{
4
        if(send_count)
5
        {
6
            if((--send_count) == 0x00)
7
            bFlag_Packet_Transimit    = true;
8
        }
9
}


Also nur ein festes Zeitintervall fürs Daten senden über einen 
Interrupt.

von Karl H. (kbuchegg)


Lesenswert?

OK.
Sieht für mich so aus, als ob ich mit der Annahme eines memory mapped 
Devices falsch liege.

Sieht so aus, als ob da wer auf Biegen und Brechen den Compiler dazu 
brignen will, ein paar Flags in Register zu halten.

Ich denke die vernünftigste Entsprechung ist
1
volatile uint8_t bFlag_Packet_Transimit;
2
volatile uint8_t bFlag_Calibration_Status;

und den Rest überlässt man besser dem Compiler.


Wird bFlag_Calibration_Status ähnlich verwendet?

von Felix (Gast)


Lesenswert?

Ja,

bflag_Calibration_Status wird ähnlich verwendet.

Hab gerade noch mal in den "System Header" Dateien des IAR Projekts 
gestöbert. Die hatte ich für den GCC nicht übernommen, weil ich da 
lieber die altbekannten nutzen wollte.

>ein paar Flags in Register zu halten.
Ein paar ist gut....;-)

Da sieht es überall so aus:
1
     /*  declare PortB */
2
__io union{
3
             uchar   PINB;
4
             struct{
5
                     uchar  inputBbit0:1,
6
                            inputBbit1:1,
7
                            inputBbit2:1,
8
                            inputBbit3:1,
9
                            inputBbit4:1,
10
                            inputBbit5:1,
11
                            inputBbit6:1,
12
                            inputBbit7:1;
13
                    };
14
           } @ 0x03;
15
__io union{
16
             uchar   DDRB;
17
             struct{
18
                     uchar  ddrBbit0:1,
19
                            ddrBbit1:1,
20
                            ddrBbit2:1,
21
                            ddrBbit3:1,
22
                            ddrBbit4:1,
23
                            ddrBbit5:1,
24
                            ddrBbit6:1,
25
                            ddrBbit7:1;
26
                    };
27
           } @ 0x04;
28
__io union{
29
             uchar   PORTB;
30
             struct{
31
                     uchar  portBbit0:1,
32
                            portBbit1:1,
33
                            portBbit2:1,
34
                            portBbit3:1,
35
                            portBbit4:1,
36
                            portBbit5:1,
37
                            portBbit6:1,
38
                            portBbit7:1;
39
                    };
40
           } @ 0x05;
41
/****************************************/
42
     /*  declare PortC */
43
__io union{
44
             uchar   PINC;
45
             struct{
46
                     uchar  inputCbit0:1,
47
                            inputCbit1:1,
48
                            inputCbit2:1,
49
                            inputCbit3:1,
50
                            inputCbit4:1,
51
                            inputCbit5:1,
52
                            inputCbit6:1,
53
                            inputCbit7:1;
54
                    };
55
           } @ 0x06;
56
__io union{
57
             uchar   DDRC;
58
             struct{
59
                     uchar  ddrCbit0:1,
60
                            ddrCbit1:1,
61
                            ddrCbit2:1,
62
                            ddrCbit3:1,
63
                            ddrCbit4:1,
64
                            ddrCbit5:1,
65
                            ddrCbit6:1,
66
                            ddrCbit7:1;
67
                    };
68
           } @ 0x07;
69
__io union{
70
             uchar   PORTC;
71
             struct{
72
                     uchar  portCbit0:1,
73
                            portCbit1:1,
74
                            portCbit2:1,
75
                            portCbit3:1,
76
                            portCbit4:1,
77
                            portCbit5:1,
78
                            portCbit6:1,
79
                            portCbit7:1;
80
                    };
81
           } @ 0x08;
82
/****************************************/
83
     /*  declare PortD */
84
__io union{
85
             uchar   PIND;
86
             struct{
87
                     uchar  inputDbit0:1,
88
                            inputDbit1:1,
89
                            inputDbit2:1,
90
                            inputDbit3:1,
91
                            inputDbit4:1,
92
                            inputDbit5:1,
93
                            inputDbit6:1,
94
                            inputDbit7:1;
95
                    };
96
           } @ 0x09;
97
__io union{
98
             uchar   DDRD;
99
             struct{
100
                     uchar  ddrDbit0:1,
101
                            ddrDbit1:1,
102
                            ddrDbit2:1,
103
                            ddrDbit3:1,
104
                            ddrDbit4:1,
105
                            ddrDbit5:1,
106
                            ddrDbit6:1,
107
                            ddrDbit7:1;
108
                    };
109
           } @ 0x0a;
110
__io union{
111
             uchar   PORTD;
112
             struct{
113
                     uchar  portDbit0:1,
114
                            portDbit1:1,
115
                            portDbit2:1,
116
                            portDbit3:1,
117
                            portDbit4:1,
118
                            portDbit5:1,
119
                            portDbit6:1,
120
                            portDbit7:1;
121
                    };
122
           } @ 0x0b;

von Karl H. (kbuchegg)


Lesenswert?

Das sieht mir nach unions aus, die einen einfacheren bitweisen Zugriff 
auf die PORT und PIN Register ermöglichen sollen.

Vom PeDa gibt es da eine schöne Technik, die zumindest in der Verwendung 
auf in etwa dasselbe hinauslaufen sollte. Leider hab ich da jetzt keinen 
Link dazu.

von Klaus (Gast)


Lesenswert?

Wobei die zuletzt gezeigten Codeausschnitte, kein __regvar haben, und 
damit tatsächlich Memory-mapped-IO Register sind.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Felix schrieb:
> Im restlichen Code wird nur die Variable "bFlag_Packet_Transimit" aus
> dem union verwendet.

Das heißt, die erzeugen damit sowas wie eine "Bit-Variable".
Möglicherweise gestatten sie (als Spracherweiterung) den Zugriff
auf den Feldnamen einer nichtinstanziierten union, solange der
Name halt im entsprechenden Namensraum eindeutig ist.  GCC bietet
eine leicht ähnliche Erweiterung an, bei der man innerhalb einer
union auf struct fields zugreifen kann, ohne dass die struct
selbst einen Namen bekommen hat:
1
#include <stdint.h>
2
3
union foo {
4
        struct {
5
                uint8_t bar: 7;
6
                uint8_t mumble: 1;
7
        };
8
        uint8_t all;
9
} foo;
10
11
uint8_t getit(void)
12
{
13
        if (foo.mumble)
14
                return foo.bar;
15
        else
16
                return 42;
17
}

von Felix (Gast)


Lesenswert?

Danke für die ganzen Antworten!!!

Die beschriebene Routine von Jörg funktioniert, hab aber die ganzen 
Union Deklarationen weg gelassen und "normale" Variablen benutzt. Das 
Modul läuft weiterhin ohne Probleme, jetzt auch mit dem GCC ;-).

War für mich einfach übersichtlicher weil ich es so gewohnt bin und nen 
Vorteil durch diese Union Geschichte gab es jetzt hier nicht.

Die vereinfachte Bitweise Zugriffstechnik von PeDa würd mich aber 
interessieren. Vielleicht hat ja noch jemand den Link?


Gruß

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.