|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
optimizer removes volatile pin access code. why?Hello all.
I' using gcc version 4.3.2 (Ubuntu Jaunty) to compile some simple code. The makefile is one of these standard AVR makefile. The optimization is set to -Os (size). For some historic reasons, I use the following macros: #ifndef BV #define BV(bit) (1<<(bit)) #endif #ifndef cbi #define cbi(reg,bit) reg &= ~(BV(bit)) #endif #ifndef sbi #define sbi(reg,bit) reg |= (BV(bit)) #endif So far so good. In my current sandbox project, I've tried to mark the occurrence of an interrupt by setting an "debug pin" high. For now, the ISR is empty. ISR(TIMER2_COMP_vect) { sbi(PORTC,6); // ... cbi(PORTC,6); } With -Os enables, the setup of the port pin is removed! Without optimization the pin toggles as expected. Why does the compiles removes the pin access code? It shouldn't do this, because the SFR pointer are declared volatile. Aren't they? What's my fault? -- Email: Joerg Desch <jd DOT vvd AT web DOT de> _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Joerg Desch <jd.vvd@...> wrote:
> With -Os enables, the setup of the port pin is removed! Without > optimization the pin toggles as expected. How did you verify it? I don't believe the compiler removed the code. (If you really think it does, please supply a compilable code example.) However, the optimized code will just toggle the pin for a single CPU cycles only, while the pin will stay a little longer at high in the non-optimized example. So if your oscilloscope is too slow, you might not notice the pin actually becoming high for one clock period. -- cheers, J"org .-.-. --... ...-- -.. . 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@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?On Tue, 27 Oct 2009 20:17:46 +0100 (MET)
j@... (Joerg Wunsch) wrote: > How did you verify it? First I can't see the pulse on the oscilloscope ;-) Than I had a look in the list file. > I don't believe the compiler removed the code. (If you really think > it does, please supply a compilable code example.) Give me some time. I try to put it in a simple snippet. Is it OK to attach it as tgz to this mailing list? > However, the > optimized code will just toggle the pin for a single CPU cycles only, > while the pin will stay a little longer at high in the non-optimized > example. So if your oscilloscope is too slow, you might not notice > the pin actually becoming high for one clock period. Tektroniks TDS784 with 4GS/s ;-) -- Email: Joerg Desch <jd DOT vvd AT web DOT de> _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Joerg Desch wrote:
> On Tue, 27 Oct 2009 20:17:46 +0100 (MET) > j@... (Joerg Wunsch) wrote: > >> How did you verify it? > > First I can't see the pulse on the oscilloscope ;-) > Have you checked things like the direction setting for the pin, or if it is used by a peripheral? That might sound obvious, but sometimes the little things get forgotten. > Than I had a look in the list file. > > >> I don't believe the compiler removed the code. (If you really think >> it does, please supply a compilable code example.) > > Give me some time. I try to put it in a simple snippet. Is it OK to > attach it as tgz to this mailing list? > The normal practice is to paste the snippet into the text of the email. Then people can view it and comment on it directly in the email, rather than jumping through loops to see the code. If you think your code is too big to fit in an email text, then it's not a snippet! Also remember to give the command line switches you used. mvh., David _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Hi David,
On Wed, 28 Oct 2009 11:02:35 +0100 David Brown <david@...> wrote: > Joerg Desch wrote: > Have you checked things like the direction setting for the pin, or if > it is used by a peripheral? That might sound obvious, but sometimes > the little things get forgotten. Yes, I know. But all this is working fine. Using -Os had solved the problem. > The normal practice is to paste the snippet into the text of the email. Without the Makefile is would be a snippet. ;-) For now I have the problem, that I can't reproduce the code which leads to the missing code. I've worked on the project after posting here. The code snippet I had extracted this morning doesn't show the problem too. So I have to play with it in order to get the same effects. I've talked to an colleague this morning. He had the same problems with WinAVR a few months ago. His solution was adding a asm volatile("nop") between cbi() and sbi(). He had to generate a bus timing by software. At the end, I don't have a snippet. But I'm trying to reproduce the effect. -- Email: Joerg Desch <jd DOT vvd AT web DOT de> _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: Re: optimizer removes volatile pin access code. why?On Wed, Oct 28, 2009 at 12:44:48PM +0100, Joerg Desch wrote:
> I've talked to an colleague this morning. He had the same problems with > WinAVR a few months ago. His solution was adding a asm volatile("nop") > between cbi() and sbi(). He had to generate a bus timing by software. When generating output pulses of only a few cpu cycles, I've always preferred to do it in an asm file, linked in with the rest of the code. That does cost a function call and return, but the timing cannot be changed by gcc or command-line option vagaries. (In an embedded system, protection against experiences like yours is why I don't like to leave such critical things in the hands of compiler coders. YMMV, however.) Erik P.S. If this somehow doesn't make it to the list, could you please forward it? _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Hi Erik,
On Wed, 28 Oct 2009 23:29:59 +1100 Erik Christiansen <dvalin@...> wrote: > When generating output pulses of only a few cpu cycles, I've always > preferred to do it in an asm file, linked in with the rest of the code. I personally don't use assembler any more. At least I try to avoid it. ;-) > That does cost a function call and return, but the timing cannot be > changed by gcc or command-line option vagaries. I've played with "inline" and with "__attribute__((gnu_inline, always_inline))" to avoid this overhead, but it doesn't work as expected. #if defined(__GNUC__) # define ALLWAYS_INLINE inline __attribute__((gnu_inline, always_inline)) #endif ALLWAYS_INLINE int foo (void) { // ... } I've tried it with -Os and foo() is still called. > P.S. If this somehow doesn't make it to the list, could you please > forward it? As you can see it receives in the list. But with 1/2 hour delay. -- Email: Joerg Desch <jd DOT vvd AT web DOT de> _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?On Wed, Oct 28, 2009 at 02:08:05PM +0100, Joerg Desch wrote:
> I've played with "inline" and with "__attribute__((gnu_inline, > always_inline))" to avoid this overhead, but it doesn't work as expected. > > #if defined(__GNUC__) > # define ALLWAYS_INLINE inline __attribute__((gnu_inline, always_inline)) > #endif > ALLWAYS_INLINE int foo (void) > { > // ... > } > > I've tried it with -Os and foo() is still called. Ah, yes, optimisation needs to be used for inline to work. If the above fails on a small test case, "avr-gcc -v" and the command-line don't show a lurking "-fno-inline", and "-Wall -Wextra" doesn't provide any clues either, I'd pretty soon be tempted to report it as a bug, unless a magic method is revealed on the list. You've probably tried other optimisations? (Just in case the size optimisation is absolute in its approach.) > As you can see it receives in the list. But with 1/2 hour delay. Oh goody, it works again! :-) Erik _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Joerg Desch wrote:
> Hi David, > > On Wed, 28 Oct 2009 11:02:35 +0100 > David Brown <david@...> wrote: > >> Joerg Desch wrote: > >> Have you checked things like the direction setting for the pin, or if >> it is used by a peripheral? That might sound obvious, but sometimes >> the little things get forgotten. > > Yes, I know. But all this is working fine. Using -Os had solved the > problem. > > >> The normal practice is to paste the snippet into the text of the email. > > Without the Makefile is would be a snippet. ;-) > > For now I have the problem, that I can't reproduce the code which leads > to the missing code. I've worked on the project after posting here. The > code snippet I had extracted this morning doesn't show the problem too. > > So I have to play with it in order to get the same effects. > > I've talked to an colleague this morning. He had the same problems with > WinAVR a few months ago. His solution was adding a asm volatile("nop") > between cbi() and sbi(). He had to generate a bus timing by software. > > At the end, I don't have a snippet. But I'm trying to reproduce the effect. > In my experience, when code works or fails to work depending on the optimisation flags, it is the source code that is wrong - it is very rare that it is the compiler that is the problem. avr-gcc is not perfect, but incorrect code bugs are uncommon. But it's difficult to judge until you are able to isolate the problem code. You could also try to get a copy of this colleague's problem code. If it turns out to be a bug in the compiler, most people on this list would like to hear about it. And if it's a bug or misunderstanding in the source code, it could also be interesting - we can all learn from other people's mistakes. _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
RE: Re: optimizer removes volatile pin access code. why?David Brown wrote:
> And if it's > a bug or misunderstanding in the source code, it could also > be interesting - we can all learn from other people's mistakes. "Good Judgment comes from Experience. Experience often comes from Bad Judgment" Corollary: It does not need to be *your* Bad Judgment. Best regards, Stu Bell DataPlay (DPHI, Inc.) _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Erik Christiansen wrote:
> On Wed, Oct 28, 2009 at 02:08:05PM +0100, Joerg Desch wrote: >> I've played with "inline" and with "__attribute__((gnu_inline, >> always_inline))" to avoid this overhead, but it doesn't work as expected. >> >> #if defined(__GNUC__) >> # define ALLWAYS_INLINE inline __attribute__((gnu_inline, always_inline)) >> #endif >> ALLWAYS_INLINE int foo (void) >> { >> // ... >> } >> >> I've tried it with -Os and foo() is still called. > Was this from a mail from Joerg Desch that did not make it to the mailing list? It is hard for others to comment - perhaps you or Joerg could re-post the problem code. > Ah, yes, optimisation needs to be used for inline to work. If the above > fails on a small test case, "avr-gcc -v" and the command-line don't show > a lurking "-fno-inline", and "-Wall -Wextra" doesn't provide any clues > either, I'd pretty soon be tempted to report it as a bug, unless a magic > method is revealed on the list. You've probably tried other > optimisations? (Just in case the size optimisation is absolute in its > approach.) > I believe you need the -Winline to get a warning about functions declared "inline" that could not be inlined. And an __attribute_((always_inline)) function will be inlined, regardless of the optimisation levels. > >> As you can see it receives in the list. But with 1/2 hour delay. > > Oh goody, it works again! :-) > > Erik _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
RE: Re: optimizer removes volatile pin access code. why?David Brown wrote:
> And an __attribute_((always_inline)) function will be > inlined, regardless of the optimisation levels. Sorry, compiler breath -- this is not always true. If you call an "always_inline" function from inside another "always_inline" function, with optimization turned off, the compiler throws a fit. Example -- WinAVR 20090313, file compiled with -O0. Inline function is: static void FcsStartUtilTimer( uint16_t Wait ) __attribute__((always_inline)); static void FcsStartUtilTimer( uint16_t Wait ) { /* Shut the timer down, make sure interrupts are all off */ UTL_TIMER_TCCRA = 0; UTL_TIMER_TCCRB = 0; UTL_TIMER_TIMSK = 0; /* Set the wait into the counter - this value must be pre-computed * using the WAIT_TIMER_US_TO_TCNT macro! */ UTL_TIMER_TCNT = Wait; /* set up the utility timer: * Source clock: System clock / 1 * Mode: Normal * Output: none * Interrupt: on nothing */ UTL_TIMER_TCCRA = 0; UTL_TIMER_TCCRB = ( UTL_TIMER_CS0 ); /* Clear the overflow flag */ UTL_TIMER_TIFR = UTL_TIMER_TOVF; } And is used as: static bool FcsAcquireLookForSumOKDeassert( void ) __attribute__((always_inline)); static bool FcsAcquireLookForSumOKDeassert( void ) { /* Wait for SumOK to deassert */ while ( ( FCS_SUMOK_PIN & FCS_SUMOK_H ) && ! g_DacRampCompleteFlag ) { /* Delay for 1uS (use _delay_loop_1 so optimization does not affect this) */ _delay_loop_1( FCS_GENERIC_1uS_LOOP_WAIT ); } /* Set up debounce */ FcsStartUtilTimer( WAIT_TIMER_US_TO_TCNT( FCS_SIGNAL_DEASSERT_DEBOUNCE ) ); /* Debounce SumOK */ while ( ! ( UTL_TIMER_TIFR & UTL_TIMER_TOVF ) && ! g_DacRampCompleteFlag ) { if ( FCS_SUMOK_PIN & FCS_SUMOK_H ) { /* HMMMMmmm.. Went high - reset the counter */ FcsResetUtilTimer( WAIT_TIMER_US_TO_TCNT( FCS_SIGNAL_DEASSERT_DEBOUNCE ) ); } } return (! g_DacRampCompleteFlag); } Returns the following error: CmdFocus.c: In function 'FcsAcquireLookForSumOKDeassert': CmdFocus.c:4020: sorry, unimplemented: inlining failed in call to 'FcsStartUtilTimer': function body not available CmdFocus.c:4152: sorry, unimplemented: called from here ... The above code compiles fine if the optimizer is turned on (-Os). Of course, I guess the real question (which I have not investigated) is whether it compiles *correctly* with -Os. :-/ It functions correctly, so I presume it is inlining correctly. Best regards, Stu Bell DataPlay (DPHI, Inc.) _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: Re: optimizer removes volatile pin access code. why?Hello,
I'm mainly an assembly language user and not a heavy weight C user but this thread has peaked my interest. I'm currently working with the ATmega 2561 and in the course or reading and re-reading the data sheet I found an example on page 72,73 and an example on page 74 showing that there are some issues with the IO Ports that may be part of the issue here. the discussion is in section 13.2.4 "Reading the Pin Value" starting on page 72 of the 2549L–AVR–08/07 preliminary data sheet. Basically as shown below in the Data sheet excerpt, a NOP is necessary following a write to DDRB(n), and prior to seeing the change on pin(n). I'm not sure that this extends to the entire 8 bit family but it might be worth looking at. Excerpt follows ========================================== The following code example shows how to set port B pins 0 and 1 high, 2 and 3 low, and define the port pins from 4 to 7 as input with pull-ups assigned to port pins 6 and 7. The resulting pin values are read back again, but as previously discussed, a NOP instruction is included to be able to read back the value recently assigned to some of the pins. Assembly Code Example(1) ======================================== ... ; Define pull-ups and set outputs high ; Define directions for port pins ldi r16,(1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0) ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0) out PORTB,r16 out DDRB,r17 ; Insert NOP for synchronization nop ; Read port pins in r16,PINB ... ======================================= C Code Example ------------------------------------ unsigned char i; ... /* Define pull-ups and set outputs high */ /* Define directions for port pins */ PORTB = (1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0); DDRB = (1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0); /* Insert nop for synchronization*/ __no_operation(); /* Read port pins */ i = PINB; ... Note: 1. For the assembly program, two temporary registers are used to minimize the time from pullups are set on pins 0, 1, 6, and 7, until the direction bits are correctly set, defining bit 2 and 3 as low and redefining bits 0 and 1 as strong high drivers. 13.2.5 Digital Input Enable and Sleep Modes As shown in Figure 13-2, the digital input signal can be clamped to ground Hope this sheds some light on what is going on. Dan welch ============================================================ David Brown wrote: > Erik Christiansen wrote: >> On Wed, Oct 28, 2009 at 02:08:05PM +0100, Joerg Desch wrote: >>> I've played with "inline" and with "__attribute__((gnu_inline, >>> always_inline))" to avoid this overhead, but it doesn't work as >>> expected. >>> >>> #if defined(__GNUC__) >>> # define ALLWAYS_INLINE inline __attribute__((gnu_inline, >>> always_inline)) >>> #endif >>> ALLWAYS_INLINE int foo (void) >>> { >>> // ... >>> } >>> >>> I've tried it with -Os and foo() is still called. >> > > Was this from a mail from Joerg Desch that did not make it to the > mailing list? It is hard for others to comment - perhaps you or Joerg > could re-post the problem code. > >> Ah, yes, optimisation needs to be used for inline to work. If the above >> fails on a small test case, "avr-gcc -v" and the command-line don't show >> a lurking "-fno-inline", and "-Wall -Wextra" doesn't provide any clues >> either, I'd pretty soon be tempted to report it as a bug, unless a magic >> method is revealed on the list. You've probably tried other >> optimisations? (Just in case the size optimisation is absolute in its >> approach.) >> > > I believe you need the -Winline to get a warning about functions > declared "inline" that could not be inlined. > > And an __attribute_((always_inline)) function will be inlined, > regardless of the optimisation levels. > >> >>> As you can see it receives in the list. But with 1/2 hour delay. >> >> Oh goody, it works again! :-) >> >> Erik > > > > _______________________________________________ > AVR-GCC-list mailing list > AVR-GCC-list@... > http://lists.nongnu.org/mailman/listinfo/avr-gcc-list > > > ------------------------------------------------------------------------ > > > No virus found in this incoming message. > Checked by AVG - www.avg.com > Version: 8.5.423 / Virus Database: 270.14.34/2463 - Release Date: 10/27/09 15:50:00 > _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: Re: optimizer removes volatile pin access code. why?Joerg Desch <jd.vvd@...> wrote:
> Give me some time. I try to put it in a simple snippet. Is it OK to > attach it as tgz to this mailing list? Attachments of MIME type application/octet-stream used to be dropped (although I'm not sure whether this has been turned off now), anything else should be fine. For just a simple example, you'd better attach them as text/plain files (just strip down the Makefile to a few lines as well), that way, most mailers / news readers will be able to display them inline. >> So if your oscilloscope is too slow, you might not notice >> the pin actually becoming high for one clock period. > Tektroniks TDS784 with 4GS/s ;-) Unless you accidentally enable something like a low-pass filter in the trigger system, that should of course work. -- cheers, J"org .-.-. --... ...-- -.. . 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@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: Re: optimizer removes volatile pin access code. why?On Wed, Oct 28, 2009 at 04:51:23PM +0100, David Brown wrote:
> Was this from a mail from Joerg Desch that did not make it to the mailing > list? It is hard for others to comment - perhaps you or Joerg could > re-post the problem code. Checking, I find that the mail was "To: avr-gcc-list@..." and CCed to me. If it didn't reach the list, then I'm not the only one who has had mails swallowed silently. (Ah, I'd thought it was just my filtering of duplicate mails which left me with only the direct copy, but I see now that a list copy was not received.) > Erik Christiansen wrote: >> Ah, yes, optimisation needs to be used for inline to work. If the above >> fails on a small test case, "avr-gcc -v" and the command-line don't show >> a lurking "-fno-inline", and "-Wall -Wextra" doesn't provide any clues >> either, I'd pretty soon be tempted to report it as a bug, unless a magic >> method is revealed on the list. You've probably tried other >> optimisations? (Just in case the size optimisation is absolute in its >> approach.) > > I believe you need the -Winline to get a warning about functions declared > "inline" that could not be inlined. The extremes apparently needed to achieve a genuine and complete -Wall seem to gradually increase. Thanks for the "heads up". > And an __attribute_((always_inline)) function will be inlined, regardless > of the optimisation levels. Oh-oh, I do need to update. My avr-gcc is still 4.2.1, and the manpage still says: "Note that if you are not optimizing, no functions can be expanded inline" but the current http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Function-Attributes.html#index-g_t_0040code_007balways_005finline_007d-function-attribute-2190 clarifies: always_inline Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level was specified. Erik _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?Stu Bell wrote:
> David Brown wrote: > >> And an __attribute_((always_inline)) function will be >> inlined, regardless of the optimisation levels. > > Sorry, compiler breath -- this is not always true. If you call an > "always_inline" function from inside another "always_inline" function, > with optimization turned off, the compiler throws a fit. > > Example -- WinAVR 20090313, file compiled with -O0. Inline function is: > > static void > FcsStartUtilTimer( uint16_t Wait ) __attribute__((always_inline)); > static void > FcsStartUtilTimer( uint16_t Wait ) > { <snip> > > Returns the following error: > > CmdFocus.c: In function 'FcsAcquireLookForSumOKDeassert': > CmdFocus.c:4020: sorry, unimplemented: inlining failed in call to > 'FcsStartUtilTimer': function body not available > CmdFocus.c:4152: sorry, unimplemented: called from here > ... > That's hardly "throwing a fit" - it's simply telling you it can't obey the "always_inline" attribute. However, I think the problem stems from a misunderstanding about "always_inline" - it's an /additional/ request to the compiler that you can use for /inline/ functions. From the gcc documentation: always_inline Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level was specified. If you declare your functions "inline", it should work as you desire even with -O0: static inline void FcsStartUtilTimer( uint16_t Wait ) __attribute__((always_inline)); static inline void FcsStartUtilTimer( uint16_t Wait ) mvh., David > The above code compiles fine if the optimizer is turned on (-Os). Of > course, I guess the real question (which I have not investigated) is > whether it compiles *correctly* with -Os. :-/ It functions correctly, > so I presume it is inlining correctly. > > Best regards, > > Stu Bell > DataPlay (DPHI, Inc.) _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: optimizer removes volatile pin access code. why?df_welch wrote:
> Hello, > I'm mainly an assembly language user and not a heavy weight C user > but this thread has peaked my interest. I'm currently working with the > ATmega 2561 and in the course or reading and re-reading the data sheet I > found an example on page 72,73 and an example on page 74 showing that > there are some issues with the IO Ports that may be part of the issue > here. the discussion is in section 13.2.4 "Reading the Pin Value" > starting on page 72 of the 2549L–AVR–08/07 preliminary data sheet. > > Basically as shown below in the Data sheet excerpt, a NOP is necessary > following a write to DDRB(n), and prior to seeing the change on pin(n). > > I'm not sure that this extends to the entire 8 bit family but it might > be worth looking at. > > Excerpt follows ========================================== > The following code example shows how to set port B pins 0 and 1 high, 2 > and 3 low, and define > the port pins from 4 to 7 as input with pull-ups assigned to port pins 6 > and 7. The resulting pin > values are read back again, but as previously discussed, a NOP > instruction is included to be able > to read back the value recently assigned to some of the pins. > > Assembly Code Example(1) > ======================================== > ... > ; Define pull-ups and set outputs high > ; Define directions for port pins > ldi r16,(1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0) > ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0) > out PORTB,r16 > out DDRB,r17 > ; Insert NOP for synchronization > nop > ; Read port pins > in r16,PINB > ... > ======================================= > C Code Example > ------------------------------------ > unsigned char i; > ... > /* Define pull-ups and set outputs high */ > /* Define directions for port pins */ > PORTB = (1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0); > DDRB = (1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0); > /* Insert nop for synchronization*/ > __no_operation(); > /* Read port pins */ > i = PINB; > ... > > > Note: 1. For the assembly program, two temporary registers are used to > minimize the time from pullups > are set on pins 0, 1, 6, and 7, until the direction bits are correctly > set, defining bit 2 and 3 > as low and redefining bits 0 and 1 as strong high drivers. > 13.2.5 Digital Input Enable and Sleep Modes > As shown in Figure 13-2, the digital input signal can be clamped to ground > > Hope this sheds some light on what is going on. > This is, I think, a very different situation. What you are seeing here is the pipelining and clocking effects when you set a pin and then try to read a pin to see the effects - the pin write has an extra cycle of latency, so if you follow a pin write by a pin read, you'll get the read from the same clock cycle as the write takes place, rather than the cycle after it. If you've got pin IO that is affected by such timing issues, then you need to make sure there is a delay between the pin write and the pin read, regardless of any optimisation issues. _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: Re: optimizer removes volatile pin access code. why?On Wed, Oct 28, 2009 at 11:14:08AM -0700, df_welch wrote:
> I'm mainly an assembly language user and not a heavy weight C user but > this thread has peaked my interest. I must admit to having a similar relationship with the AVR, thus far. So much can be done with macros that it isn't always necessary to use C. > Basically as shown below in the Data sheet excerpt, a NOP is necessary > following a write to DDRB(n), and prior to seeing the change on pin(n). That sounds very plausible. Having mostly set direction in an .init section, and then used the port much later, I've not experienced it though. If Joerg Desch could possibly post the relevant assembler snippet, either from an objdump or list file, the risk of that could be seen. A dump would also confirm that the expected instructions are there at all. > I'm not sure that this extends to the entire 8 bit family but it might be > worth looking at. ISTR seeing something related in other AVR datasheets, even if only vaguely. Placing a few nops between sbi and cbi also makes it easier to see the output pulse with less sophisticated equipment than Joerg has [1], and could speed up finding the assembler code snippet if no labels exist in the vicinity. [1] I remember doing that on my first AVR project, even at 1MHz, just to give it every chance of working the first time. Erik _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
RE: Re: optimizer removes volatile pin access code. why?David Brown wrote:
> > Returns the following error: > > > > CmdFocus.c: In function 'FcsAcquireLookForSumOKDeassert': > > CmdFocus.c:4020: sorry, unimplemented: inlining failed in call to > > 'FcsStartUtilTimer': function body not available > > CmdFocus.c:4152: sorry, unimplemented: called from here ... > > > > That's hardly "throwing a fit" - it's simply telling you it > can't obey the "always_inline" attribute. Okay, bad humor day. Sorry. > However, I think the problem stems from a misunderstanding > about "always_inline" - it's an /additional/ request to the > compiler that you can use for /inline/ functions. From the > gcc documentation: > > always_inline > Generally, functions are not inlined unless optimization > is specified. For functions declared inline, this attribute > inlines the function even if no optimization level was specified. > > > If you declare your functions "inline", it should work as you > desire even with -O0: > > static inline void > FcsStartUtilTimer( uint16_t Wait ) > __attribute__((always_inline)); static inline void > FcsStartUtilTimer( uint16_t Wait ) Ah ha, that's it! I read that description several times and never quite got it. Thanks for setting me straight, Dave! Best regards, Stu Bell DataPlay (DPHI, Inc.) _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
|
|
Re: Re: optimizer removes volatile pin access code. why?Erik Christiansen <dvalin@...> wrote:
>> I've tried it with -Os and foo() is still called. > Ah, yes, optimisation needs to be used for inline to work. This contradicts the documentation though: `always_inline' Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level was specified. As such, it might be worth a bug report. -- cheers, J"org .-.-. --... ...-- -.. . 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@... http://lists.nongnu.org/mailman/listinfo/avr-gcc-list |
| < Prev | 1 - 2 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |