[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] C++ and aggregates in flash memory

From: Ned Konz
Subject: [avr-gcc-list] C++ and aggregates in flash memory
Date: Thu, 11 May 2006 21:12:18 -0700
User-agent: Thunderbird (Macintosh/20060308)

I'm using C++ with avr-gcc 4.1 (and also with 4.2-pre).

I've noticed that if I put constant structs in flash memory (simple aggregates: no virtual functions, constructors, destructors, private, or protected) that I get some very stupid constructors that then clobber my I/O registers before main(). This even happens when I'm using the optimizer.

For instance, when I declare the structs like this:

struct DeviceSettings
    volatile uint8_t *csPortAddress; //!< pointer to PORTC or PORTG
    uint8_t csBitMask;               //!< mask for CS signal on port
    uint8_t csPolarity:1;            //!< active level of CS signal
    uint8_t cpol:1;                  //!< setting for CPOL
    uint8_t cpha:1;                  //!< setting for CPHA
    uint8_t dord:1;                  //!< setting for DORD (data order)
    ClockRate clock:3;               //!< SPI2X:SPR1:SPR0, SPI_ClockRate
    uint8_t :1;                      //!< unused

extern const
struct AllDeviceSettings
    DeviceSettings display, leds, gainPot, trimPot,
                      dac1, dac2, atod, dataflash, sdCard;
PROGMEM spiDeviceSettings;

and then define them like this:

const AllDeviceSettings PROGMEM spiDeviceSettings =
/* .display */
    /* .csPortAddress */ &atmega128::PORTC,
    /* .csBitMask */ DISP_CS.mask(),
    /* .csPolarity */ 0,
    /* .cpol */ 0,
    /* .cpha */ 0,
    /* .dord */ 0,
    /* .clock */ SPI_CLOCK_1_92_M
/* .leds */
    /* .csPortAddress */ &atmega128::PORTC,
    /* .csBitMask */ LEDS_CS.mask(),
    /* .csPolarity */ 0,
    /* .cpol */ 1,
    /* .cpha */ 1,
    /* .dord */ 0,
    /* .clock */ SPI_CLOCK_7_68_M
// 7 more of the same kind of struct definition ...

that I get the following kind of very silly global constructor code (which gets called before main()):

__static_initialization_and_destruction_0(int, int)():
     f26:       sbiw    r24, 0x01       ; 1
     f28:       breq    .+2             ; 0xf2c
     f2a:       ret
     f2c:       subi    r22, 0xFF       ; 255
     f2e:       sbci    r23, 0xFF       ; 255
     f30:       brne    .-8             ; 0xf2a
     f32:       ldi     r24, 0x35       ; 53
     f34:       ldi     r25, 0x00       ; 0
     f36:       sts     0x0096, r25
     f3a:       sts     0x0095, r24
     f3e:       ldi     r19, 0x01       ; 1
     f40:       sts     0x0097, r19
     f44:       sts     0x009A, r25
     f48:       sts     0x0099, r24
     f4c:       ldi     r18, 0x02       ; 2
     f4e:       sts     0x009B, r18
     f52:       sts     0x009E, r25
     f56:       sts     0x009D, r24
     f5a:       ldi     r18, 0x04       ; 4
     f5c:       sts     0x009F, r18
     f60:       sts     0x00A2, r25
     f64:       sts     0x00A1, r24
     f68:       ldi     r18, 0x08       ; 8
     f6a:       sts     0x00A3, r18
     f6e:       sts     0x00A6, r25
     f72:       sts     0x00A5, r24
     f76:       ldi     r18, 0x10       ; 16
     f78:       sts     0x00A7, r18
     f7c:       sts     0x00AA, r25
     f80:       sts     0x00A9, r24
     f84:       ldi     r18, 0x20       ; 32
     f86:       sts     0x00AB, r18
     f8a:       sts     0x00AE, r25
     f8e:       sts     0x00AD, r24
     f92:       ldi     r24, 0x40       ; 64
     f94:       sts     0x00AF, r24
     f98:       ldi     r24, 0x65       ; 101
     f9a:       ldi     r25, 0x00       ; 0
     f9c:       sts     0x00B2, r25
     fa0:       sts     0x00B1, r24
     fa4:       sts     0x00B3, r19
     fa8:       sts     0x00B6, r25
     fac:       sts     0x00B5, r24
     fb0:       sts     0x00B7, r19
     fb4:       ret

Note that the addresses 0x0095 through 0x00b7 that it's trying to write to are actually addresses in *flash* (which are already initialized in the object file in the .text section), but the generated code actually clobbers various registers in I/O space instead.

Here's what it is trying to initialize:

00000095 g     O .text  00000024 spiDeviceSettings

and of course it's already set up correctly in the ROM image, in the .text section:

00000095 <spiDeviceSettings>:
      95:       address@hidden@
      a5:       ...F...F.......A
      b5:       ...A

Is there some easy way around this problem?

Ned Konz

reply via email to

[Prev in Thread] Current Thread [Next in Thread]