Witam.
Przytrafił mi się ciekawy problem, którego nijak nie potrafię rozwiązać.
Piszę procedurkę do odczytu kart mmc/sd pod attiny2313 -ponieważ nie ma w tym procku SPI, użyłem USI. Aby uzyskać maksymalną prędkość transmisji zastosowałem się do wskazówek zawartych w dokumentacji procka i napisałem funkcję wysyłania/odbierania bajtu z softwareowym taktowaniem USI:
No i tu pojawia się problem...
Przy każdym wywołaniu tej funkcji kompilator traktuje ją jako inline co w efekcie daje niesamowicie spuchnięty kod wynikowy. Np funkcja:
generuje taki oto piękny kod:
Zabawa z flagami optymalizacji, modyfikatorami register czy zawartością samej funkcji nic w tej materii nie zmienia.
Czy ktoś ma pomysł jak ten problem rozwiązać? Cy można wymusić na kompilatorze, aby funkcja NIE BYŁA inline?
Przytrafił mi się ciekawy problem, którego nijak nie potrafię rozwiązać.
Piszę procedurkę do odczytu kart mmc/sd pod attiny2313 -ponieważ nie ma w tym procku SPI, użyłem USI. Aby uzyskać maksymalną prędkość transmisji zastosowałem się do wskazówek zawartych w dokumentacji procka i napisałem funkcję wysyłania/odbierania bajtu z softwareowym taktowaniem USI:
uint8_t spi_byte(uint8_t byte)
{
USIDR=byte;
register uint8_t tik=(1<<USIWM0)|(0<<USICS0)|(1<<USITC);
register uint8_t tak=(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK);
//8 taktów zeara, żeby wysłać /odebrać cały bajt
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
USICR=tik;
USICR=tak;
return USIDR;
}No i tu pojawia się problem...
Przy każdym wywołaniu tej funkcji kompilator traktuje ją jako inline co w efekcie daje niesamowicie spuchnięty kod wynikowy. Np funkcja:
void mmc_send_command(uint8_t command, uint16_t px, uint16_t py)
{
register union u16convert r;
MMC_CS_PORT &= ~(1 << MMC_CS); // CS
spi_byte(0xff);
spi_byte(command | 0x40);
r.value = px;
spi_byte(r.bytes.high);
spi_byte(r.bytes.low);
r.value = py;
spi_byte(r.bytes.high);
spi_byte(r.bytes.low);
spi_byte(0x95); // poprawne CRC dla pierwszej komendy SPI
spi_byte(0xff);
}
generuje taki oto piękny kod:
+000001DD: 98C4 CBI 0x18,4
+000001DE: EF3F LDI R19,0xFF ; 0xFF = 0b11111111 = 255
+000001DF: B93F OUT 0xF,R19
+000001E0: E121 LDI R18,0x11 ; 0x11 = 0b00010001 = 17
+000001E1: B92D OUT 0xD,R18
+000001E2: E193 LDI R25,0x13 ; 0x13 = 0b00010011 = 19
+000001E3: B99D OUT 0xD,R25
+000001E4: B92D OUT 0xD,R18
+000001E5: B99D OUT 0xD,R25
+000001E6: B92D OUT 0xD,R18
+000001E7: B99D OUT 0xD,R25
+000001E8: B92D OUT 0xD,R18
+000001E9: B99D OUT 0xD,R25
+000001EA: B92D OUT 0xD,R18
+000001EB: B99D OUT 0xD,R25
+000001EC: B92D OUT 0xD,R18
+000001ED: B99D OUT 0xD,R25
+000001EE: B92D OUT 0xD,R18
+000001EF: B99D OUT 0xD,R25
+000001F0: B92D OUT 0xD,R18
+000001F1: B99D OUT 0xD,R25
+000001F2: B1EF IN R30,0xF
+000001F3: 6480 ORI R24,0x40 ; 0x40 = 0b01000000 = 64
+000001F4: B98F OUT 0xF,R24
+000001F5: B92D OUT 0xD,R18
+000001F6: B99D OUT 0xD,R25
+000001F7: B92D OUT 0xD,R18
+000001F8: B99D OUT 0xD,R25
+000001F9: B92D OUT 0xD,R18
+000001FA: B99D OUT 0xD,R25
+000001FB: B92D OUT 0xD,R18
+000001FC: B99D OUT 0xD,R25
+000001FD: B92D OUT 0xD,R18
+000001FE: B99D OUT 0xD,R25
+000001FF: B92D OUT 0xD,R18
+00000200: B99D OUT 0xD,R25
+00000201: B92D OUT 0xD,R18
+00000202: B99D OUT 0xD,R25
+00000203: B92D OUT 0xD,R18
+00000204: B99D OUT 0xD,R25
+00000205: B18F IN R24,0xF
+00000206: B97F OUT 0xF,R23
+00000207: B92D OUT 0xD,R18
+00000208: B99D OUT 0xD,R25
+00000209: B92D OUT 0xD,R18
+0000020A: B99D OUT 0xD,R25
+0000020B: B92D OUT 0xD,R18
+0000020C: B99D OUT 0xD,R25
+0000020D: B92D OUT 0xD,R18
+0000020E: B99D OUT 0xD,R25
+0000020F: B92D OUT 0xD,R18
+00000210: B99D OUT 0xD,R25
+00000211: B92D OUT 0xD,R18
+00000212: B99D OUT 0xD,R25
+00000213: B92D OUT 0xD,R18
+00000214: B99D OUT 0xD,R25
+00000215: B92D OUT 0xD,R18
+00000216: B99D OUT 0xD,R25
+00000217: B18F IN R24,0xF
+00000218: B96F OUT 0xF,R22
+00000219: B92D OUT 0xD,R18
+0000021A: B99D OUT 0xD,R25
+0000021B: B92D OUT 0xD,R18
+0000021C: B99D OUT 0xD,R25
+0000021D: B92D OUT 0xD,R18
+0000021E: B99D OUT 0xD,R25
+0000021F: B92D OUT 0xD,R18
+00000220: B99D OUT 0xD,R25
+00000221: B92D OUT 0xD,R18
+00000222: B99D OUT 0xD,R25
+00000223: B92D OUT 0xD,R18
+00000224: B99D OUT 0xD,R25
+00000225: B92D OUT 0xD,R18
+00000226: B99D OUT 0xD,R25
+00000227: B92D OUT 0xD,R18
+00000228: B99D OUT 0xD,R25
+00000229: B18F IN R24,0xF
+0000022A: B95F OUT 0xF,R21
+0000022B: B92D OUT 0xD,R18
+0000022C: B99D OUT 0xD,R25
+0000022D: B92D OUT 0xD,R18
+0000022E: B99D OUT 0xD,R25
+0000022F: B92D OUT 0xD,R18
+00000230: B99D OUT 0xD,R25
+00000231: B92D OUT 0xD,R18
+00000232: B99D OUT 0xD,R25
+00000233: B92D OUT 0xD,R18
+00000234: B99D OUT 0xD,R25
+00000235: B92D OUT 0xD,R18
+00000236: B99D OUT 0xD,R25
+00000237: B92D OUT 0xD,R18
+00000238: B99D OUT 0xD,R25
+00000239: B92D OUT 0xD,R18
+0000023A: B99D OUT 0xD,R25
+0000023B: B18F IN R24,0xF
+0000023C: B94F OUT 0xF,R20
+0000023D: B92D OUT 0xD,R18
+0000023E: B99D OUT 0xD,R25
+0000023F: B92D OUT 0xD,R18
+00000240: B99D OUT 0xD,R25
+00000241: B92D OUT 0xD,R18
+00000242: B99D OUT 0xD,R25
+00000243: B92D OUT 0xD,R18
+00000244: B99D OUT 0xD,R25
+00000245: B92D OUT 0xD,R18
+00000246: B99D OUT 0xD,R25
+00000247: B92D OUT 0xD,R18
+00000248: B99D OUT 0xD,R25
+00000249: B92D OUT 0xD,R18
+0000024A: B99D OUT 0xD,R25
+0000024B: B92D OUT 0xD,R18
+0000024C: B99D OUT 0xD,R25
+0000024D: B18F IN R24,0xF
+0000024E: E985 LDI R24,0x95 ; 0x95 = 0b10010101 = 149
+0000024F: B98F OUT 0xF,R24
+00000250: B92D OUT 0xD,R18
+00000251: B99D OUT 0xD,R25
+00000252: B92D OUT 0xD,R18
+00000253: B99D OUT 0xD,R25
+00000254: B92D OUT 0xD,R18
+00000255: B99D OUT 0xD,R25
+00000256: B92D OUT 0xD,R18
+00000257: B99D OUT 0xD,R25
+00000258: B92D OUT 0xD,R18
+00000259: B99D OUT 0xD,R25
+0000025A: B92D OUT 0xD,R18
+0000025B: B99D OUT 0xD,R25
+0000025C: B92D OUT 0xD,R18
+0000025D: B99D OUT 0xD,R25
+0000025E: B92D OUT 0xD,R18
+0000025F: B99D OUT 0xD,R25
+00000260: B18F IN R24,0xF
+00000261: B93F OUT 0xF,R19
+00000262: B92D OUT 0xD,R18
+00000263: B99D OUT 0xD,R25
+00000264: B92D OUT 0xD,R18
+00000265: B99D OUT 0xD,R25
+00000266: B92D OUT 0xD,R18
+00000267: B99D OUT 0xD,R25
+00000268: B92D OUT 0xD,R18
+00000269: B99D OUT 0xD,R25
+0000026A: B92D OUT 0xD,R18
+0000026B: B99D OUT 0xD,R25
+0000026C: B92D OUT 0xD,R18
+0000026D: B99D OUT 0xD,R25
+0000026E: B92D OUT 0xD,R18
+0000026F: B99D OUT 0xD,R25
+00000270: B92D OUT 0xD,R18
+00000271: B99D OUT 0xD,R25
+00000272: B18F IN R24,0xF
+00000273: 9508 RET
Zabawa z flagami optymalizacji, modyfikatorami register czy zawartością samej funkcji nic w tej materii nie zmienia.
Czy ktoś ma pomysł jak ten problem rozwiązać? Cy można wymusić na kompilatorze, aby funkcja NIE BYŁA inline?
