C/C++
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
Go Back   Web Development Archives FAQs C/C++

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Web Development Archives Sponsor:
  #1  
Old July 31st, 2008, 07:01 AM
Ark Khasin
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

I have a memory-mapped peripheral with a mapping like, say,
struct T {uint8_t read, write, status, forkicks;};

If I slap a volatile on an object of type struct T, does it guarantee
that all accesses to the members are byte-wide, or is the compiler free
to read or read-modify-write in any data width it chooses?

Is slapping a volatile on each member of the struct definition any
different? better? worse?

Thank you,
Ark

Reply With Quote
  #2  
Old July 31st, 2008, 07:01 AM
Gordon Burditt
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

>I have a memory-mapped peripheral with a mapping like, say,
>struct T {uint8_t read, write, status, forkicks;};
>
>If I slap a volatile on an object of type struct T, does it guarantee
>that all accesses to the members are byte-wide, or is the compiler free
>to read or read-modify-write in any data width it chooses?


I don't believe that anything in the standard guarantees the right
thing for memory-mapped I/ (the vague promises aren't good enough),
but if the compiler for your system supports memory-mapped I/ and
is used to actually compile drivers using memory-mapped I/, chances
are much better that it will work using volatile than not. Read
the specific documentation that should come with your compiler.

If your system actually has to deal with getting the width of I/
correct, chances are the compiler will also.

>Is slapping a volatile on each member of the struct definition any
>different? better? worse?


It depends entirely on your compiler.


Reply With Quote
  #3  
Old July 31st, 2008, 07:01 AM
Flash Gordon
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Ark Khasin wrote, 31/07/08 06:23:
I have a memory-mapped peripheral with a mapping like, say,
struct T {uint8_t read, write, status, forkicks;};

Be aware that the compiler is allowed to put in padding. Since this is
obviously for non-portable code it might be sufficient to just put in a
comment in the code stating that you are relying on the compiler not
putting in any padding.

If I slap a volatile on an object of type struct T, does it guarantee
that all accesses to the members are byte-wide, or is the compiler free
to read or read-modify-write in any data width it chooses?

The requirements on the compiler for volatile are quite lax and even
leave is up to the implementation to define what counts as accessing a
variable. So you should read your compiler documentation.

Imagine a processor which can physically only read/write in chunks of 64
bits but which nevertheless has a compiler with a "normal" 8 bit byte.
such an implementation if the structure did not have any padding the
compiler would not be able to prevent all bytes being added.

Having said that, I would *expect* the compiler to "do the right
thing"(tm) in your case. I would expect this because by not doing so on
what I'm guessing is a compiler targeting a small embedded device would
make it hard to use.

Is slapping a volatile on each member of the struct definition any
different? better? worse?

It could be inconvenient. thing I've sometimes wanted to do was use
a structure of that general type both for some in-normal-memory stuff
(without the volatile qualifier) and for the memory-mapped device.
volatile-qualifying the members would make this awkward.

There is also an argument that you should not use a struct for this
purpose *because* it could have padding, but if your code for
interfacing to the HW is nicely isolated and the compiler documentation
says it will work, then as it is highly system specific anyway I don't
see a real problem.

Sorry that the best advise is to read the compiler documentation, but it
really is your best chance to ensure it works correctly. The next best
advice would be asking in a group dedicated to your specific
implementation or in comp.arch.embedded where there are a lot more
people who are regularly doing this kind of thing than there are in this
group.

Note your question *is* topical here since volatile *is* part of the
standard language, it's just that to achieve your aims you need to go
beyond the guarantees of the language to things guaranteed by your
specific implementation.
--
Flash Gordon

Reply With Quote
  #4  
Old July 31st, 2008, 07:01 AM
Ark Khasin
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Gordon Burditt wrote:
>I have a memory-mapped peripheral with a mapping like, say,
>struct T {uint8_t read, write, status, forkicks;};
>>

>If I slap a volatile on an object of type struct T, does it guarantee
>that all accesses to the members are byte-wide, or is the compiler free
>to read or read-modify-write in any data width it chooses?
>

I don't believe that anything in the standard guarantees the right
thing for memory-mapped I/ (the vague promises aren't good enough),
What if it is not an I/ but a normal memory location with intended
byte-size members? (BTW, why the difference?)

Thanks,
Ark


Reply With Quote
  #5  
Old July 31st, 2008, 07:01 AM
Ark Khasin
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Flash Gordon wrote:
Be aware that the compiler is allowed to put in padding. Since this is
obviously for non-portable code it might be sufficient to just put in a
comment in the code stating that you are relying on the compiler not
putting in any padding.
I was under the impression that if a struct contains only uint8_t and
arrays thereof, there is no padding. Is it wrong?
>

Imagine a processor which can physically only read/write in chunks of 64
bits but which nevertheless has a compiler with a "normal" 8 bit byte.
such an implementation if the structure did not have any padding the
compiler would not be able to prevent all bytes being added.
Is such a compiler allowed to define uint8_t? Hmm I guess it is

Thanks,
Ark

Reply With Quote
  #6  
Old July 31st, 2008, 07:01 AM
santosh
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Ark Khasin wrote:

Flash Gordon wrote:
>Be aware that the compiler is allowed to put in padding. Since this
>is obviously for non-portable code it might be sufficient to just put
>in a comment in the code stating that you are relying on the compiler
>not putting in any padding.

I was under the impression that if a struct contains only uint8_t and
arrays thereof, there is no padding. Is it wrong?

The [u]intN_t types are specified to contain any padding bits, but
padding between structure members of these types in still allowed.

<snip>


Reply With Quote
  #7  
Old July 31st, 2008, 07:02 AM
Ark Khasin
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Flash Gordon wrote:
Imagine a processor which can physically only read/write in chunks
of 64
bits but which nevertheless has a compiler with a "normal" 8 bit byte.
such an implementation if the structure did not have any padding the
compiler would not be able to prevent all bytes being added.
This is true for any implementation of any language; the peripherals
must be designed to be accessible via CPU instructions, so my
struct T {uint8_t read, write, status, forkicks;};
doesn't describe a peripheral on such a platform.
TH, it can be a normal memory object (+ consider a "normal" platform
with a volatile bitfield member of a struct). The closest thing to "the
right thing" would be to disable the interrupts while reading/writing.
Will a(ny) compiler do this?

Reply With Quote
  #8  
Old July 31st, 2008, 07:02 AM
santosh
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

santosh wrote:

Ark Khasin wrote:
>
>Flash Gordon wrote:

Be aware that the compiler is allowed to put in padding. Since this
is obviously for non-portable code it might be sufficient to just
put in a comment in the code stating that you are relying on the
compiler not putting in any padding.
>I was under the impression that if a struct contains only uint8_t and
>arrays thereof, there is no padding. Is it wrong?
>

The [u]intN_t types are specified to contain any padding bits, but
^
add a "not" here.

padding between structure members of these types in still allowed.
>

<snip>


Reply With Quote
  #9  
Old July 31st, 2008, 07:39 AM
Ark Khasin
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

santosh wrote:
Ark Khasin wrote:
>I was under the impression that if a struct contains only uint8_t and
>arrays thereof, there is no padding. Is it wrong?
>

The [u]intN_t types are specified to contain any padding bits, but
padding between structure members of these types in still allowed.
>

course struct {uint8_t a; uint32_t b; uint8_t c;} is likely to have
padding somewhere. But uint8_t alone?



Reply With Quote
  #10  
Old July 31st, 2008, 07:39 AM
santosh
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Ark Khasin wrote:

santosh wrote:
>Ark Khasin wrote:

I was under the impression that if a struct contains only uint8_t
and arrays thereof, there is no padding. Is it wrong?
>>

>The [u]intN_t types are specified to contain any padding bits, but
>padding between structure members of these types in still allowed.
>>

course struct {uint8_t a; uint32_t b; uint8_t c;} is likely to have
padding somewhere. But uint8_t alone?

I think you are conflating padding bits (which the [u]intN_t types
cannot have) with padding bytes, which are allowed between any two
structure members. It is not allowed between elements of an array.


Reply With Quote
  #11  
Old July 31st, 2008, 06:00 PM
Gordon Burditt
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

I have a memory-mapped peripheral with a mapping like, say,
struct T {uint8_t read, write, status, forkicks;};

If I slap a volatile on an object of type struct T, does it guarantee
that all accesses to the members are byte-wide, or is the compiler free
to read or read-modify-write in any data width it chooses?
>>

>I don't believe that anything in the standard guarantees the right
>thing for memory-mapped I/ (the vague promises aren't good enough),
>What if it is not an I/ but a normal memory location with intended
>byte-size members? (BTW, why the difference?)


RAM does not care about the number of accesses or the width
of accesses. What you write can be read back. RAM doesn't
usually NEED volatile unless there is some asynchronous code (signal
handler, interrupt routine, etc.) that can change the contents
without the compiler knowing about it.

With memory-mapped I/, reading or writing a register may trigger
an action (clearing a "data ready" flag, fetching the next set of
data, launching a missile, etc. What you read (the "status" register)
may have nothing to do with what you write (the "command" register)
except they share the same address (so turning a byte write into a
word fetch, replace a byte, write a word may be a disaster, even
though it's not an issue with ordinary RAM). Accessing the register
with the wrong I/ width may cause malfunctions or access something
entirely different. The contents of a memory-mapped I/ device
register may change on its own (e.g. data ready or status flags,
or a clock).


Reply With Quote
  #12  
Old July 31st, 2008, 06:00 PM
Joe Wright
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Ark Khasin wrote:
I have a memory-mapped peripheral with a mapping like, say,
struct T {uint8_t read, write, status, forkicks;};
>

If I slap a volatile on an object of type struct T, does it guarantee
that all accesses to the members are byte-wide, or is the compiler free
to read or read-modify-write in any data width it chooses?
>

Is slapping a volatile on each member of the struct definition any
different? better? worse?

I guess you don't have a decent C book. The point of 'volatile' is to
tell the compiler that this variable might be modified by forces outside
this program's scope. Think memory-mapped I/

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
Albert Einstein

Reply With Quote
  #13  
Old July 31st, 2008, 07:19 PM
Ark Khasin
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
A basic question question about volatile use

Eric Sosman wrote:
It might appear that by qualifying each element
>

struct T {
volatile uint8_t read;
volatile uint8_t write;

};
>

one could tell the compiler not to meddle with the `read' element
while accessing the adjacent `write'. The argument might hold that
`volatile' warns the compiler that each access to the variable is a
side-effect, so that touching `read' while fiddling with `write'
would cause a side-effect in the real machine that is not present in
the abstract machine. The argument sounds pretty good, but the last
sentence of 6.7.3p6 torpedoes it: "What constitutes an access to an
object that has volatile-qualified type is implementation-defined."
This sentence -- which might as well be named the Mack Truck Clause,
because it's a hole wide enough to drive a Mack truck through -- is
the Standard's concession that C is implemented on real machines that
may not always be capable of following the abstract machine's rules
quite that scrupulously. (For example, others have mentioned real
machines that are unable to access bytes in isolation, but always
deal with larger assemblages.)
>

Ark's case is not hopeless, though. The MTC says "implementation-
*defined*," which means that the implementation is required to define
what it means to access a volatile object. Somewhere in his compiler's
documentation there should be a description of how volatile accesses
are carried out, and perhaps the compiler's promises -- which are
specific to that particular compiler, of course -- will suffice for
Ark's purposes. In fact, there's an excellent chance that they will,
because if the machine has arranged its I/ registers in this manner,
it's highly likely that the hardware is able to generate the accesses
they need, and there's a reasonable chance that the C compiler can
create code that generates those accesses. It's not certain -- on
some machines you may need to resort to assembly -- but the odds are
fairly good.
>

Thank you, Eric and all.
The code is working fine; my inquiry was about how much RTFM I need to
do if I am to replace the compiler. Turns out the whole volatile
business is implementation-dependent (perhaps actually -defined with any
luck). It would be nice at least to have a machine-defined set of atomic
types and a guarantee that an atomic volatile type is accessed
atomically and without molesting its neighbors. Alas, even that isn't
true: ARM has an instruction to access (volatile) 64-bit (and wider)
objects atomically but my compiler (IAR) doesn't seem to always bother.

- Ark

Reply With Quote
Reply

Viewing: Web Development Archives FAQs C/C++ > A basic question question about volatile use


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2009 by Developer Shed. All rights reserved. DS Cluster 5 Hosted by Hostway
For more Enterprise Application Development news, visit eWeek