Re: [avr-gcc-list] Program Space String optimization
On Dec 14, 2005, at 8:57 AM, Joerg Wunsch wrote: volatile PGM_P txt= P_Txt; Your volatile qualifier is at the wrong place. You're marking the object txt points to as volatile, not the pointer itself. Change that into PGM_P volatile txt = P_Txt; and it will work. Believe that is correct. But the other thing that was tripping him is in general all function calls are effectively volatile as well. Call a function and expect it will be called simply because you said to, the the optimizer probably won't descend into the function and decide it can be skipped. If the function is inlined then all bets are off. do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char While pgm_read_byte(txt) looks like a function call it is totally macro. I don't believe this is a problem with the compiler at all, it did exactly what it was told it could do. -- David Kelly N4HHE, [EMAIL PROTECTED] Actually, gcc is getting steadily better at optomising function calls - there is no reason to assume that function calls are effectively volatile. Under normal optomisation, the compiler will use what it knows about previously defined functions to determine if they can be re-ordered, inlined, or skipped entirely. Some standard library functions are handled as special cases, and it is possible to use function attributes in header files to tell the compiler more (such as const or pure) giving the compiler lots more freedom to move around the function calls. With -O2 and above, unit-at-a-time compilation allows the compiler to use information about functions later in the same unit, and if you've specified several C files at the same time, it can use information about all of them. Thus assuming that function calls are volatile is dangerous. mvh., David ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Space String optimization
Your volatile qualifier is at the wrong place. You're marking the object txt points to as volatile, not the pointer itself. Change that into PGM_P volatile txt = P_Txt; and it will work. Thank you for your fast answer. I've compiled whith those changes and it works as expected. I supose I'll have to read more C manuals... Btw., to make other people's job (who are willing to help you) easier, please supply compilable examples (all required #includes present, things like Init code here in /* */ comment delimiters). Thank you. Sure I will do next time. And Thank you again Bolet Sent from the AVR - gcc forum at Nabble.com: Re: Program Space String & optimization ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Space String optimization
A solution I would propose is to change the offending line like this (I haven't checked this, though): do{} while( (a=(volatile char)(pgm_read_byte(txt))) ); Thanks for answering. I've tryed your suggestion with the same result, but the answer given by Joerg Wunsch (first answer in thread) works OK: Your volatile qualifier is at the wrong place. You're marking the object txt points to as volatile, not the pointer itself. Change that into PGM_P volatile txt = P_Txt Thanks Bolet Sent from the AVR - gcc forum at Nabble.com: Re: Program Space String & optimization ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Space String optimization
bolet (sent by Nabble.com) [EMAIL PROTECTED] wrote: The 'end of string' is checked in 'main' (just for test purposes). A very strange way, indeed... volatile PGM_P txt= P_Txt; Your volatile qualifier is at the wrong place. You're marking the object txt points to as volatile, not the pointer itself. Change that into PGM_P volatile txt = P_Txt; and it will work. Btw., to make other people's job (who are willing to help you) easier, please supply compilable examples (all required #includes present, things like Init code here in /* */ comment delimiters). Thank you. -- Jorg Wunsch Unix support engineer [EMAIL PROTECTED]http://www.interface-systems.de/~j/ ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Space String optimization
On 14.12.2005 11:42, bolet (sent by Nabble.com) wrote: The program works OK without optimization. It doesn't work with optimization (-o1). The code is: ...includes... const char P_Txt[] PROGMEM = Just a test..; volatile PGM_P txt= P_Txt; int main (void) { ...Init code ... (reg setup enable int) do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char cli(); //Disable int for (;;); // Do nothing return(0); } SIGNAL (SIG_USART_DATA) { UDR0=pgm_read_byte(txt++); //Send a byte and increment pointer } Hi, Your problem seems to be in this line: do{} while( (a=pgm_read_byte(txt)) ); In spite of txt being declared as volatile, the pgm_read_byte macro evaluates it as a plain uint16_t. To see what I mean, check out these two macros from avr/pgmspace.h : #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short)) #define pgm_read_byte(address_short)pgm_read_byte_near(address_short) A solution I would propose is to change the offending line like this (I haven't checked this, though): do{} while( (a=(volatile char)(pgm_read_byte(txt))) ); ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Program Space String optimization
From: bolet (sent by Nabble.com) [EMAIL PROTECTED] [...] The program works OK without optimization. It doesn't work with optimization (-o1). The code is: ...includes... const char P_Txt[] PROGMEM = Just a test..; volatile PGM_P txt= P_Txt; int main (void) { ...Init code ... (reg setup enable int) do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char cli(); //Disable int for (;;); // Do nothing return(0); } SIGNAL (SIG_USART_DATA) { UDR0=pgm_read_byte(txt++); //Send a byte and increment pointer } The 'do while' assembler code generated (with -o1) : +0041: 91E00100LDS R30,0x0100 +0043: 91F00101LDS R31,0x0101 +0045: 9184 LPM R24,Z 51: do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char +0046: 2388 TST R24 +0047: F7F1 BRNEPC-0x01 Branch if not equal 52: cli(); //Disable int As you can see, the LPM instruction is outside the loop, so this is an infinite loop. -What's wrong with this code? Seems to be a strange corner case. I'm not sure the compiler is misbehaving, but it might be. There should be a simple fix. You've declared 'txt' to be volatile, which is good, but you don't show the declaration of 'a'. And I suspect it's not volatile. Since 'a' is not volatile, subsequent writes to the value may be optimized out. But the LPM should always happen because txt is volatile. In any case, changing the declaration of 'a' to something like unsigned char volatile a; should do it. Removing 'a' entirely should fix it as well, but I'm assuming you're using it for other reasons. -Which is this the correct way to work with flash data? You don't seem to be handling flash wrong. Any suggestion would be greatly appreciated. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Space String optimization
On Dec 14, 2005, at 8:57 AM, Joerg Wunsch wrote: volatile PGM_P txt= P_Txt; Your volatile qualifier is at the wrong place. You're marking the object txt points to as volatile, not the pointer itself. Change that into PGM_P volatile txt = P_Txt; and it will work. Believe that is correct. But the other thing that was tripping him is in general all function calls are effectively volatile as well. Call a function and expect it will be called simply because you said to, the the optimizer probably won't descend into the function and decide it can be skipped. If the function is inlined then all bets are off. do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char While pgm_read_byte(txt) looks like a function call it is totally macro. I don't believe this is a problem with the compiler at all, it did exactly what it was told it could do. -- David Kelly N4HHE, [EMAIL PROTECTED] Whom computers would destroy, they must first drive mad. ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Space String optimization
David Kelly [EMAIL PROTECTED] wrote: Believe that is correct. But the other thing that was tripping him is in general all function calls are effectively volatile as well. That's not entirely true. For standard library functions, if the compiler knows exactly the result (and knows it has no side effects), it can do whatever would have happened instead actually calling the function. Consider the pgm_read_*() functions to be similar to that in behaviour: the compiler knows exactly what needs to be done here. Likewise, GCC can analyze simple functions, and notice they don't have side effects, and return a constant result, and then skip multiple invocations if it has the result `cached' still. If the function is inlined then all bets are off. A true inlined function should behave identical to a non-inlined one. But of course, macros are different here. -- cheers, Jorg .-.-. --... ...-- -.. . DL8DTL http://www.sax.de/~joerg/NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-) ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list