Hi,
ich hab hier ein Problem mit den Optimierungen, die der gcc auf einen
Pointer einer Struct anwendet:
Zum Patienten:
In bus.c wird ein Pointer auf eine Struct definiert:
1 | volatile struct frame * bus_frame;
|
In bus.h wird der Pointer als extern deklariert:
1 | extern volatile struct frame * bus_frame;
|
In bridge.c wird nun dieser Pointer in einer Schleife verwendet:
1 | void bridge_mainloop(void)
|
2 | {
|
3 | while (1){
|
4 | if( bus_frame->isnew == 1){
|
5 | bus_frame->isnew = 0;
|
6 | }
|
7 | wdt_reset();
|
8 | }
|
9 | }
|
Der gcc generiert mir aus der Schleife folgendes:
1 | void bridge_mainloop(void)
|
2 | {
|
3 | 2ba: e0 91 57 02 lds r30, 0x0257
|
4 | 2be: f0 91 58 02 lds r31, 0x0258
|
5 | 2c2: 01 c0 rjmp .+2 ; 0x2c6 <bridge_mainloop+0xc>
|
6 | while (1){
|
7 | if( bus_frame->isnew == 1){
|
8 | bus_frame->isnew = 0;
|
9 | }
|
10 | wdt_reset();
|
11 | 2c4: a8 95 wdr
|
12 | }
|
13 |
|
14 | void bridge_mainloop(void)
|
15 | {
|
16 | while (1){
|
17 | if( bus_frame->isnew == 1){
|
18 | 2c6: 85 a9 ldd r24, Z+53 ; 0x35
|
19 | 2c8: 81 30 cpi r24, 0x01 ; 1
|
20 | 2ca: e1 f7 brne .-8 ; 0x2c4 <bridge_mainloop+0xa>
|
21 | bus_frame->isnew = 0;
|
22 | 2cc: 15 aa std Z+53, r1 ; 0x35
|
23 | 2ce: e0 91 57 02 lds r30, 0x0257
|
24 | 2d2: f0 91 58 02 lds r31, 0x0258
|
25 | 2d6: f6 cf rjmp .-20 ; 0x2c4 <bridge_mainloop+0xa>
|
26 |
|
27 | 000002d8 <bridge_tick>:
|
28 | wdt_reset();
|
29 | }
|
30 | }
|
Das Problem:
Solange die if-Bedingung nicht erfuellt ist wird das Z-Register nicht
wieder mit einer neuen Adresse geladen obwohl der Pointer als volatile
gekennzeichnet ist.
Dieses Problem tritt nur bei -O2 und -O3 auf.
Jemand eine Idee, ob ich was falsch mache oder einfach nur der Compiler
ein Problem hat?
Gruss, Tobias