Hallo!
Ich habe gerade ein Problem mit meinem GCC, Version ist das neuste
WinAVR (vom Juni).
Und zwar meint er trotz Optimierung -Os häufig Funktionen inlinen zu
müssen, auch wenn das aus meiner Sicht völlig schwachsinnig /
verschwenderisch ist. Gibt es ein Keyword, um dem Compiler zu sagen,
dass diese Funktion immer explizit aufgerufen werden soll? Ich kann ja
schlecht für jede Funktion ein eigenes C-File machen :-)
Ein Beispielcode:
1 | char pgmInitSirfMode[] PROGMEM = "\x1b" "$PSRF100,0,38400,8,1,0*3C\r\n";
|
2 |
|
3 | void gps_enable (void)
|
4 | {
|
5 | PRR &= ~(1 << PRUSART0);
|
6 | UBRR0 = GPS_UBRRVAL;
|
7 | UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
|
8 | FETPORT &= ~(1 << GPS_FET);
|
9 | UCSR0B = (1 << RXEN0) | (1 << TXEN0);
|
10 | gps_transmit_p(pgmInitSirfMode);
|
11 | }
|
12 |
|
13 | void gps_transmit (uint8_t byte)
|
14 | {
|
15 | while (! (UCSR0A & (1 << UDRE0)));
|
16 | UDR0 = byte;
|
17 | }
|
18 |
|
19 | void gps_transmit_p (PGM_P address)
|
20 | {
|
21 | uint8_t count = pgm_read_byte(address++);
|
22 | while(count--)
|
23 | {
|
24 | gps_transmit(pgm_read_byte(address++));
|
25 | }
|
26 | }
|
Das generierte Listing für den Abschnitt ist im Anhang.
Kurz beschrieben: Er inlined einmal die gps_transmit_p und dortdrin auch
noch den gps_transmit Aufruf. Somit vergeudet der liebe GCC alleine an
dieser Stelle etliche Bytes Flash, ohne gezählt zu haben sind das
sicherlich ~30.
Das gleiche Problem hatte ich mit meiner Init() Funktion, welche zu
Beginn der Main aufgerufen wird. Das Problem habe ich gelöst, indem ich
sie einfach als inline deklariert habe, sodass er sie nicht nochmal als
aufrufbare Funktion ins Flash packt. Das ist aber eher ein work-around
und geht nicht immer... Warum "optimiert" er denn bei -Os nicht wirklich
auf kleinen Code? In diesem Fall hier wäre der Geschwindigkeitsverlust
durch den call sehr marginal im Vergleich zur sowieso benötigten
Ausführungszeit...
Was mache ich falsch? :-)
cu
Matze