EmbeddedRelated.com
Forums

UART stuck waiting for THRE

Started by mattwoolsey May 10, 2008
Paul Claessen wrote:

> As for your, in itself valuable, suggestion to read the standard isn't
> of much help here, since it
> states:
> "What constitutes an access to an object that has volatile-qualified
> type is
> implementation-defined."

Paul, I think that that's Paul Curtis' point exactly, and he's got
years of experience at a very high (low?) level with just this kind
of isssue.

Matt indicated that his problem "went away" when he used char instead
of int, but then reappeared when he added some code to the function.

He also indicated it went away when he went back to the default
optimization level instead of 0, which agin reduces code size...

Paul Curtis suggested a possible MAM issue, which is fairly easy to
check out.

Since the problem appears to come back when the object code size is
increased, my next step would be to get out the linker map file and
figure out what's close by the object code in question.

I'd also look at what's around the end of the code (like a stack).

Matt, are you running this code in RAM, by chance?

Cheers, Ralph

An Engineer's Guide to the LPC2100 Series

Ralph Hempel wrote:
> Paul Claessen wrote:
>
>> As for your, in itself valuable, suggestion to read the standard isn't
>> of much help here, since it
>> states:
>> "What constitutes an access to an object that has volatile-qualified
>> type is
>> implementation-defined."
>
> Paul, I think that that's Paul Curtis' point exactly, and he's got
> years of experience at a very high (low?) level with just this kind
> of isssue.
>
> Matt indicated that his problem "went away" when he used char instead
> of int, but then reappeared when he added some code to the function.
>
> He also indicated it went away when he went back to the default
> optimization level instead of 0, which agin reduces code size...
>
> Paul Curtis suggested a possible MAM issue, which is fairly easy to
> check out.
>
Hi Paul,

I agree with both Paul and Ralph on the MAM issue. Have seen this on a 2103 running thumb mode and found that just adding a NOP to the procedure everything worked just perfectly again. I switched from FULL ON to PARTIALLY ON and that fixed it for good. I do not see what processor type you are running but another issue for us was the core voltage to the processor was changed from 1.8VDC to 1.95VDC which also allowed us to run a 60MHz PLL.

regards,
Charles

To be clear, Paul's comment was on a side discussion Robert and I had, and didn't directly concern
Matt's original problem.
The MAM suggestion is indeed an interesting one, especially since we already had establised that a
hardware issue is, in this case, fairly likely.
Keep in mind that his program runs just fine in the emulator, so I think a stack issue is slightly
less likely.

But then again... you never know ;-)

~ Paul Claessen

(Btw, Matt mentioned the processor type to be a 2103)

----- Original Message -----
From: "Charles R. Grenz"
To:
Sent: Sunday, May 11, 2008 9:11 AM
Subject: Re: [lpc2000] Re: UART stuck waiting for THRE
>
> Ralph Hempel wrote:
>> Paul Claessen wrote:
>>
>>> As for your, in itself valuable, suggestion to read the standard isn't
>>> of much help here, since it
>>> states:
>>> "What constitutes an access to an object that has volatile-qualified
>>> type is
>>> implementation-defined."
>>
>> Paul, I think that that's Paul Curtis' point exactly, and he's got
>> years of experience at a very high (low?) level with just this kind
>> of isssue.
>>
>> Matt indicated that his problem "went away" when he used char instead
>> of int, but then reappeared when he added some code to the function.
>>
>> He also indicated it went away when he went back to the default
>> optimization level instead of 0, which agin reduces code size...
>>
>> Paul Curtis suggested a possible MAM issue, which is fairly easy to
>> check out.
>>
> Hi Paul,
>
> I agree with both Paul and Ralph on the MAM issue. Have seen this on a 2103 running thumb mode
> and found that just adding a NOP to the procedure everything worked just perfectly again. I
> switched from FULL ON to PARTIALLY ON and that fixed it for good. I do not see what processor type
> you are running but another issue for us was the core voltage to the processor was changed from
> 1.8VDC to 1.95VDC which also allowed us to run a 60MHz PLL.
>
> regards,
> Charles
>
Paul,

> > In general, if you are using the value of an assignment expression,
> you had
> > better know exactly what you've written and what the compiler *must*
> do in
> > that situation.
> >
> > --
> > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
> I'm not sure how this relates to the discussion.
>
> That an assignment expression has the value of the left operand after
> the assignment is not something that was disputed, in fact that was what
> Robert started the discussion with. (And, while
> interesting. the construct x =y = k never played a role in this
> discussion)

Indeed. However, "return (some_volatile = other_value)" is *exactly* the
same.

> Robert's argument was that 'the value stored' (value of assignment
> expression) should be read back from the memory location if it has been
deemed
> volatile, AFTER it has been stored.

No, This is not correct. A single write is required.

> So, for instance, the compiler generated code that came up with the
> value of the expression in a register, and as its last act it writes that
> register to memory (the lvalue). Now, Robert's argument
> was, that since that memory location was specified as volatile, the
> register cannot be used as the final expression value, but the memory
> should be read back. I objected to that notion.

Quite right to object. The result of the expression is the value of what
was written, nothing more, nothing less.

unsigned x;
volatile signed char c;

x = c = 0xff;

What's the value of x? Hmmm. 0xff as x is unsigned or ~0U because -1 is
stored in c? Or something else because c is volatile?

Doesn't matter a damn, the ISO standard specifies what happens: the value
stored should be used which precludes re-reading c in this case.

It's the same in the case of "return c = 0xff" in a function returning
unsigned. The value returned is not 0xff.

> As for your, in itself valuable, suggestion to read the standard isn't
> of much help here, since it states: "What constitutes an access to an
object
> that has volatile-qualified type is implementation-defined."

That *does* help. That's because implementation-defined means that the
implementation must specify what happens. Which means you need to do some
reading to see what it means.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

At 04:30 PM 5/11/2008 +0100, Paul Curtis wrote:
> >
> > I'm not sure how this relates to the discussion.
> >
> > That an assignment expression has the value of the left operand after
> > the assignment is not something that was disputed, in fact that was what
> > Robert started the discussion with. (And, while
> > interesting. the construct x =y = k never played a role in this
> > discussion)
>
>Indeed. However, "return (some_volatile = other_value)" is *exactly* the
>same.

Very similar any way. However the order of operations of the first is not
defined, is not the order of the second well defined?

Isn't the return statement more like

x = (y=k); ?

> > Robert's argument was that 'the value stored' (value of assignment
> > expression) should be read back from the memory location if it has been
>deemed
> > volatile, AFTER it has been stored.
>
>No, This is not correct. A single write is required.
>
> > So, for instance, the compiler generated code that came up with the
> > value of the expression in a register, and as its last act it writes that
> > register to memory (the lvalue). Now, Robert's argument
> > was, that since that memory location was specified as volatile, the
> > register cannot be used as the final expression value, but the memory
> > should be read back. I objected to that notion.
>
>Quite right to object. The result of the expression is the value of what
>was written, nothing more, nothing less.

Interesting. The references I was able to look up indicated the value of
an assignment expression was its left hand side. I'm quite willing to
believe you over them though. If anyone here is likely to know it's you.

I think this boils down to the question of what the 'value of the left
operand' is. In the case of c=x; I've been taking it to mean c. If I
understand you correctly you are saying it is the value of x after any
appropriate type conversions that is assigned to c. The two are close. I
think the only time they will differ is in the presence of volatile.

I do think that writing code that relies on this kind of detailed knowledge
is a bad idea when it is just as easy and far more clear to write in a
fashion that doesn't need to rely on this behaviour.
>unsigned x;
>volatile signed char c;
>
>x = c = 0xff;
>
>What's the value of x? Hmmm. 0xff as x is unsigned or ~0U because -1 is
>stored in c? Or something else because c is volatile?
>
>Doesn't matter a damn, the ISO standard specifies what happens: the value
>stored should be used which precludes re-reading c in this case.

Really? Isn't there a question of order of operations here. Every time
I've seen this construct (barring volatile) it is accompanied by notes that
the order of operations is undefined and that x could end up with the
either the value of c after the write or the value c had before the
write. PC-Lint certainly complains about it.

Surely this can be implemented as

x=c;
c=0xff;

which does imply a read.

Robert

"C is known as a language that gives you enough rope to shoot yourself in
the foot." -- David Brown in comp.arch.embedded
http://www.aeolusdevelopment.com/
At 04:01 AM 5/11/2008 +0000, mattwoolsey wrote:
>More info:
>
>The int vs. char parameter is not what fixes it. It apparently has to
>do with spacing of the code from the beginning of the function. Even
>with the char parameter, I added an if{ statement at the beginning of
>the function which checked for '\n' and then added a '\r' if it
>matched. This didn't work. So I added a couple dummy statements to
>the beginning and then it worked again. Very strange.

Another thought. Do you have any way of telling if you have triggered an
exception? Maybe set another output when you enter an exception?

Robert

http://www.aeolusdevelopment.com/

From the Divided by a Common Language File (Edited to protect the guilty)
ME - "I'd like to get Price and delivery for connector Part # XXXXX"
Dist./Rep - "$X.XX Lead time 37 days"
ME - "Anything we can do about lead time? 37 days seems a bit high."
Dist./Rep - "that is the lead time given because our stock is live.... we
currently have stock."
----- Original Message -----
From: "Robert Adsett"

--- snip ---

>>
>>Quite right to object. The result of the expression is the value of what
>>was written, nothing more, nothing less.
>
> Interesting. The references I was able to look up indicated the value of
> an assignment expression was its left hand side. I'm quite willing to
> believe you over them though. If anyone here is likely to know it's you.

==> You'r both talking about the same thing:
The left hand operand IS the value of what was written!
Same thing.

>>x = c = 0xff;
>>
>>What's the value of x? Hmmm. 0xff as x is unsigned or ~0U because -1 is
>>stored in c? Or something else because c is volatile?
>>
>>Doesn't matter a damn, the ISO standard specifies what happens: the value
>>stored should be used which precludes re-reading c in this case.
>
> Really? Isn't there a question of order of operations here.
==> Yes!
> Every time I've seen this construct (barring volatile) it is accompanied by notes that
> the order of operations is undefined

==> No, the order IS defined. You're probably referring to situations were pre-or suffix operators
(++,--) are involved, THEN and only THEN is the order undefined.
> and that x could end up with the either
> the value of c after the write or the value c had before the
> write. PC-Lint certainly complains about it.

==> No, you will NEVER end up with the value of c in x before 0xff is written to c.
Again the order IS specified: x = c = 0xff is an expression and the '=' operator has right to left
associativity.
No reason for PC-lint to complain about anything.
Again, it gets different when you sprinkle some ++ or -- around in such an expressions.

To Paul Curtis:
Were you claiming that (to simplify the case)
return 1;
is actually an assignment expression?
(something I'm not buying! ;-)

~ Paul
At 01:12 PM 5/11/2008 -0400, Paul Claessen wrote:

>----- Original Message -----
>From: "Robert Adsett" --- snip ---
>
> >>
> >>Quite right to object. The result of the expression is the value of what
> >>was written, nothing more, nothing less.
> >
> > Interesting. The references I was able to look up indicated the value of
> > an assignment expression was its left hand side. I'm quite willing to
> > believe you over them though. If anyone here is likely to know it's you.
>
>==> You'r both talking about the same thing:
>The left hand operand IS the value of what was written!
>Same thing.

Unless the left hand operand is volatile.

> > Every time I've seen this construct (barring volatile) it is
> accompanied by notes that
> > the order of operations is undefined
>
>==> No, the order IS defined. You're probably referring to situations were
>pre-or suffix operators
>(++,--) are involved, THEN and only THEN is the order undefined.
> > and that x could end up with the either
> > the value of c after the write or the value c had before the
> > write. PC-Lint certainly complains about it.
>
>==> No, you will NEVER end up with the value of c in x before 0xff is
>written to c.
>Again the order IS specified: x = c = 0xff is an expression and the '='
>operator has right to left
>associativity.
>No reason for PC-lint to complain about anything.

Oops, quite right. The complaint is about depending on the precedence, not
that it's undefined. My apologies.
>To Paul Curtis:
>Were you claiming that (to simplify the case)
>return 1;
>is actually an assignment expression?

Makes sense to me. How does it differ?

Robert

"C is known as a language that gives you enough rope to shoot yourself in
the foot." -- David Brown in comp.arch.embedded
http://www.aeolusdevelopment.com/
Hi,

> >unsigned x;
> >volatile signed char c;
> >
> >x = c = 0xff;
> >
> >What's the value of x? Hmmm. 0xff as x is unsigned or ~0U because -1
> is
> >stored in c? Or something else because c is volatile?
> >
> >Doesn't matter a damn, the ISO standard specifies what happens: the
> value
> >stored should be used which precludes re-reading c in this case.
>
> Really? Isn't there a question of order of operations here. Every
> time
> I've seen this construct (barring volatile) it is accompanied by notes
> that
> the order of operations is undefined and that x could end up with the
> either the value of c after the write or the value c had before the
> write. PC-Lint certainly complains about it.

No. Associativity of operators applies and, hence, x = c = 0xff is treated
as x = (c = 0xff) as associativity is right to left. The value of c = 0xff
is what is assigned to x. In this case, 0xff is assigned to c which is the
value 8-bit signed value -1. -1 is then converted from (signed char)-1 to
(signed int)-1 and ultimately to unsigned which yields 0xffffffffU for a
32-bit machine. Don't believe me? Go try it.

> Surely this can be implemented as
>
> x=c;
> c=0xff;
>
> which does imply a read.

That would be a broken compiler because it does not assign to c first as
required by the standard (associativity of operators). So no, it would be
quite wrong to re-write x = c = 0xff as (x = c), (c = 0xff) as reverses the
assignment order.

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Hi Paul,

> To Paul Curtis:
> Were you claiming that (to simplify the case)
> return 1;
> is actually an assignment expression?
> (something I'm not buying! ;-)

Yes, it's treated as an assignment to return value of the function. It has
*all* the traits of an assignment as the r-value is converted to the return
type of the function and then assigned to the "thing" that the function
returns.

Quoting form the ISO document: "If a return statement with an expression is
executed, the value of the expression is returned to the caller as the value
of the function call expression. If the expression has a type different from
the return type of the function in which it appears, the value is converted
***as if by assignment to an object having the return type of the
function***."

My emphasis, of course.

In the many compilers I have written and maintained, return statements are
best handled by assignment to an object that denotes return value of the
function. In most C languages this just happens to be the lowest register
(R0 on ARM) so the object is just something that sits in that hard register.
Or it's a register pair for doubles. Or it's a pointer to somewhere passed
in a register for structure returns. In essence "return x" is rewritten as
"return_value = x; goto function_exit" by the compiler with return_value
designated by a hard register.

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors