Mon 18 Feb 2008 06:02:32 PM UTC, original submission:
eeprom_read_block and eeprom_write_block product terrible code when used with a 32-bit variable stored in the register file, since the 32-bit variable must be first copied to the stack, which usually includes adjusting the stack-pointer and allocating a frame-pointer, leading to all sorts of ugly overhead. For this reason, I suggest adding eeprom_read_32 and eeprom_write_32. Simple definitions of these functions follow.
With the current state of optimization, the line `return (uint32_t)hi << 16 | lo;' does not produce very tight code. Using a union will produce smaller code. Alternatively, I would love to see the GCC optimizer fixed to make the shift and or produce tight code, but that's a bigger task.
n.b. I don't have AVR hardware at the moment, so these functions are untested.
Cheers,
Shaun
uint32_t eeprom_read_32(const uint32_t *src)
{
const uint16_t p = (const uint16_t )src;
uint16_t lo = eeprom_read_word(&p[0]);
uint16_t hi = eeprom_read_word(&p[1]);
return (uint32_t)hi << 16 | lo;
}
void eeprom_write_32(uint32_t *dest, uint32_t value)
{
uint16_t p = (uint16_t )dest;
eeprom_write_word(&p[0], (uint16_t)value);
eeprom_write_word(&p[1], value >> 16);
}
|