EmbeddedRelated.com
Forums

UART TX FIFO and INTs problem

Started by forum_microbit February 17, 2004
> > There is no guarantee that those statements will be performed in the order
> > you might guess. The compiler may even optimize some of them away
> > entirely. If write_to_reg is a macro, the compiler may chose to remove
> > the first invocation as the second will just overwrite it. It may even
> > remove the delay if it can figure out that it's not effecting any
> > variables.
> >
> > [snip]
>
> If write_to_reg is a function, GCC will in NO WAY change the
> ordering. If they are macros, then unless the person who wrote the
> headers is a complete hack, they will contain volatile (and anyone smart
> enough to write header files knows this), and GCC will not reorder them.

What a tangled web we weave when first we practice *edit* to write system
code. All I can say in my defence is take a look at the Linux kernel code
and see how many places bariers are used to keep GCC from getting overly
agressive. Yes, there are ways to make sure it doesn't do it by using
volatile. Yes, procedure calls will not be removed or moved *unless*
they are inline. In which they're fair game. And, yes, I've seen GCC
figure out that delay inlines were nulls and remove them. There are a
few tricks in the Linux kernel to defeat that behavior while still allowing
the use of inline delays.

> I've used GCC on several architectures, and I have never seen it
> arbitrarily reorder code execution. While it depends on the
> optimization level selected, I've only ever seen GCC reorder items in
> registers, and only then when there was no visible effect, i.e.
>
> int a;
>
> a++;
> do_some_func ();
> a++;

Yes, *from the point of view of the CPU*. From the point of hardware, no,
that is not true. I have seen writes to memory squashed when the same
location was written again shortly after. I've seen writes delayed
for a long time--throwing code off. Proper use of volitile fixes almost
all of this, but compilers have failed to do the right thing with volatile
in the past.

> I use GCC on x86, MSP430, AVR frequently, and occasionally on 68K
> and Sparc, written interrupt routines purely in C on all of those except
> 68K, and never run into re-ordering issues. If anything, I tend to get
> bit by forgetting to declare a global as volatile, and run into the
> issue of the value being cached in a register, so things like queue
> incrementers don't behave as expected. And I've come to be able to
> recognize those pretty quickly :(

Yep. Once you know the kinds of things the compiler is allowed to do--
unless you tell it not to--you're in a better position to debug such
failures. I'm just trying to point out things that the compiler can
do to help others learn what you and I have learned--the very hard way.

> I usually use -Os optimization on AVRs, and -O2 or -O3 on x86 and
> MSP430. On Sparcs I usually use -O1, but that's because there's a
> particular bug in the revision of compiler I'm running on it.

:) He he. :) -Oinfinity and damn the torpedoes!

Cheers,
David



An Engineer's Guide to the LPC2100 Series

> I was certainly used to fairly aggressive and neat opts with IAR, but I've
> never seen it change the sequence of things, that seems a bit rich.
> Mind you, that was on MSP430 and on AVR mainly.

I wouldn't expect the same kinds of optimizations on uCs that you may see
on larger systems. IBMs xcc for the POWER arch does a lot of bizarre
stuff to code. If the compiler can tell what the inputs of a function
are and all the things it touches, then if this does not conflict with
other things happening in the code, there is no programmer visible
problem with the compiler moving the execution of that chunk of code
around. There are even compilers that will throw it off in another
thread automatically--should you have multiple CPUs, this can be a win.

> Now that I know these things can happen (moving code around), I know what to
> look for and can stop bugging you guys :-)
> Without knowing this things look daunting.
>
> Is there a specific include file to use barrier() ???

It may not even be called barrier on your system. It's a compiler
specific option, so I don't even know where to point you. Sorry.

Cheers,
David



At 03:55 PM 2/22/04 -0500, you wrote:
>You're right about the context of the processor status save. The only
>reason I can think of for modifying the PSW like that would be in a task
>switcher of some kind.

hmm, I don't yet see where that would be useful in a task switch but maybe
it can happen as a side effect. I've got a thread to worry at
anyway. Atmel went to a lot of trouble for a workaround so there must be
some reason to do it. Something to puzzle away at for a bit,

Robert

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III


The kernel of a preemptive RTOS might want to.

Bill
On Sun, 22 Feb 2004 14:32:55 -0500, Robert Adsett wrote:

At 02:22 PM 2/22/04 -0500, you wrote:
>At 10:13 AM 2/22/04 -0600, you wrote:
> >As a side note. The disabling and restoring of the global interrupt
> >flag in the cpsr can has a similar problem.

><snip>

> >For more info on this, Atmel has
> >an APP note discribing it on their web site in the AT91 ARM7 section.

>Thanks for the pointer.

I just had a chance to read the app note (I presume this is the one
http://www.atmel.com/dyn/resources/prod_documents/DOC1156.PDF) and it
appears to be warning about faults that can happen when using a style of
code I would consider very error prone to begin with. Unless I'm missing
something (I've only had a little while to consider it) the only time a
problem occurs if an interrupt routine actually modifies the cpu status of
the interrupted code. What would ever prompt anyone to do that in the
first place?

Robrt

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III Yahoo! Groups Links