sa sobie moje wlasne funkcje do zapisu do EEPROMu:
jest tez sobie funkcja, ktora liczy jakas tam prosta sume kontrolna.
i teraz jest kod glowny:
przy kompilacji tego slicznego kawalka kodu z opcja -Os gcc uznaje, ze pierwsze wywolanie funkcji zapisu do EEPROMu jest w zasadzie zbedne, bo zostaje z niego tyle (funkcja zostaje wlaczona do funkcji glownej:
do tego kompilator stwierdza rowniez, ze funkcja liczaca sume kontrolna jest bezsensu, gdyz w ogolne nie zostaje ona wywolana.
efekt tego jest wiadomo jaki - kod 'prawie' dziala - zapis do eepromu jest, ale nie tego co chce i nie tam gdzie chce...
czy istnieje jakikolwiek inny sposob zmuszenia GCC do nieoptymalizowania funkcji poza nastawianiem wszedzie gdzie sie da volatile? aby funkcja zapisu do eepromu zadzialala jak trzeba musze jej zmienne globalne deklarowac jako:
aby zadzialala suma kontrolna, musze zmienna wynikowa deklarowac jako volatile, o co oczywiscie kompilator tez sie czepi, bo cos mu tam znow nie pasuje z typami (discard qualifier...)
zaraz oszaleje, wiec bede wdzieczny za pomoc...
czy w ogole tryb -Os sie do czegokolwiek nadaje?
4\/3!!
uint8_t *_save_src_adr=0;
uint8_t *_save_dst_adr=0;
volatile uint8_t _save_length=0;
...
void _eeprom_save_block(uint8_t *src,uint8_t *dst,uint8_t length)
{
while(_save_length);
_save_src_adr=src;
_save_dst_adr=dst;
_save_length=length;
EECR|=EECR_EERIE;
}
...
ISR(EE_RDY_vect)
{
uint8_t val;
EEAR=(uint16_t)_save_dst_adr++; // set up address
EEDR=*(_save_src_adr++); // ... and data
if(--_save_length)
val=EECR_EERIE|EECR_EEMWE; // enable master write and interrupt
else
val=EECR_EEMWE; // for last write - no interrupt
EECR=val;
EECR|=EECR_EEWE; // start the write operation
}
jest tez sobie funkcja, ktora liczy jakas tam prosta sume kontrolna.
uint8_t _xor_checksum(uint8_t *ptr,uint8_t length)
{
uint8_t checksum=0;
while(length--)
checksum^=*ptr++;
return checksum;
}
i teraz jest kod glowny:
uint8_t checksum;
// request data store in EEPROM
_eeprom_save_block((uint8_t*)step_ctrl.limit.min,(uint8_t*)_backups_eeprom.limit.min,sizeof(step_limit_t));
// meanwhile generate new checksum
checksum=_xor_checksum((uint8_t*)step_ctrl.limit.min,sizeof(step_limit_t));
// request checksum store in EEPROM
_eeprom_save_block(&checksum,(uint8_t*)&_checksums_eeprom.limit,sizeof(uint8_t));
przy kompilacji tego slicznego kawalka kodu z opcja -Os gcc uznaje, ze pierwsze wywolanie funkcji zapisu do EEPROMu jest w zasadzie zbedne, bo zostaje z niego tyle (funkcja zostaje wlaczona do funkcji glownej:
while(_save_length);
a0: 80 91 7a 00 lds r24, 0x007A
a4: 88 23 and r24, r24
a6: e1 f7 brne .-8 ; 0xa0 <bkup_store_limits+0xa>
_save_src_adr=src;
_save_dst_adr=dst;
_save_length=length;
a8: 88 e0 ldi r24, 0x08 ; 8
aa: 80 93 7a 00 sts 0x007A, r24
EECR|=EECR_EERIE;
ae: e3 9a sbi 0x1c, 3 ; 28
do tego kompilator stwierdza rowniez, ze funkcja liczaca sume kontrolna jest bezsensu, gdyz w ogolne nie zostaje ona wywolana.
efekt tego jest wiadomo jaki - kod 'prawie' dziala - zapis do eepromu jest, ale nie tego co chce i nie tam gdzie chce...
czy istnieje jakikolwiek inny sposob zmuszenia GCC do nieoptymalizowania funkcji poza nastawianiem wszedzie gdzie sie da volatile? aby funkcja zapisu do eepromu zadzialala jak trzeba musze jej zmienne globalne deklarowac jako:
volatile static uint8_t * volatile _save_src_adr=0;
volatile static uint8_t * volatile _save_dst_adr=0;
volatile static uint8_t _save_length=0;
aby zadzialala suma kontrolna, musze zmienna wynikowa deklarowac jako volatile, o co oczywiscie kompilator tez sie czepi, bo cos mu tam znow nie pasuje z typami (discard qualifier...)
zaraz oszaleje, wiec bede wdzieczny za pomoc...
czy w ogole tryb -Os sie do czegokolwiek nadaje?
4\/3!!
