[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 1.5.0.2 (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?
Thanks,
--
Ned Konz
address@hidden
http://bike-nomad.com
- [avr-gcc-list] C++ and aggregates in flash memory,
Ned Konz <=