James Kanze
11/18/2008 9:14:00 AM
On Nov 17, 10:48 am, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Nov 17, 1:53 am, ma740988 <ma740...@gmail.com> wrote:
> > I often peruse source that use memory mapped registers as a
> > configuration and/or command and status interface between
> > embedded software and FPGA logic. In doing so you're given
> > a register name accompanied by descriptions and a location
> > in memory for reading/ writing data.
> > For ex:.
> > Revision Register - Location 0x0000
> > [31...15] spare
> > [14...00] number
> > Control Register - Location 0x0001
> > [31..3] -- Spare
> > [2] -- Address Line 3
> > [1] -- Address Line 2
> > [0] -- Address Line 1
> > To describe these registers in source one could do:
> > struct RevisionRegister {
> > unsigned short number : 16;
> > unsigned short spare : 16;
> > };
> > struct ControlRegister {
> > unsigned int Spare : 29;
> > unsigned short AddressLine3 : 1;
> > unsigned short AddressLine2 : 1;
> > unsigned short AddressLine1 : 1 ;
> > } ;
Maybe. How a compiler lays out bitfields is implementation
defined.
> > The trouble with the composite type ControlRegister is sizeof
> > (ControlRegister) is not 32 bits.
It is with my compilers. But it definitely depends on the
compiler; a compiler for a 16 bit machine is likely to
systematically put any bit field greater or equal to 16 bits in
a separate word.
> It is because bit-fields of different type can not be merged.
Since when? Both g++ and Sun CC merge them, under Solaris.
> Fix:
> struct ControlRegister {
> unsigned Spare : 29;
> unsigned AddressLine3 : 1;
> unsigned AddressLine2 : 1;
> unsigned AddressLine1 : 1 ;
> } ;
It would be a pretty poor implementation which generated a
different layout for these two. I'm not even sure it's legal.
(The actual layout is implementation defined, and the standard
isn't really clear about the restrictions, if any. But laying
out these two differently certainly violates the spirit of the
standard, if not the actual wording.)
> > That said, its not possible to receive ControlRegister in
> > it's current form from an end user and overlay it at the
> > appropriate location. The fundamental issue surrounds the
> > use of bitfields and implementation defined nature of POD
> > types. The question: What are some of the - if you will -
> > tips for dealing with this issue?
>
> Another issue is that bit-field bit order can be little or
> big-endian depending on the platform and the compiler.
The layout is implementation defined, with very few
restrictions. But if you're reading and writing memory mapped
registers, portability is presumably not a concern. And
implementation defined means documented, so you know what the
compiler does. For any one particular version of the compiler,
of course, but from a QoI point of view, no reasonable compiler
will change the basic principles from one version to the next.
(Although... I've seen changes more radical than that, like the
byte order in a long. From a QoI point of view, the quality
wasn't there, but it was still the compiler we had to use.)
> A portable way to read mapped registers is to read the
> register, convert it from the byte order of the hardware that
> exposes that register into the byte order of the cpu (if byte
> orders are the same this is a noop), and then apply mask by
> using bitwise and operator to extract the interesting bits.
> This way you don't depend on the bit-field bit order.
"A portable way to read mapped registers"? Sounds like an
oxymoron to me.:-)
Seriously, of course, such problems don't affect just mapped
registers, and this is the way to solve them portably in other
cases (transmission protocols, etc.). The register is slightly
different, in that you can (maybe) read and write words, and not
just bytes, but other than that, the principles are the same.
Using bit fields results in less and cleaner code, but it only
works for mapped registers, and only then if your compiler does
something reasonable, and documents it. (If it doesn't, he
might want to consider changing compilers; under Windows, VC++
is more or less broken with regards to bit fields, but g++ works
fine.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34