From: Gavin Lambert (boost_at_[hidden])
Date: 2020-07-02 03:22:08
On 2/07/2020 14:43, Jupiter wrote:
> I am working on an embedded system where I read hardware 32-bit
> register values represented variables in bits. Currently I am using
> bit shift to extract values, it is too vague to represent variables. I
> have been thinking to make overhaul of using dynamic bitset, is it a
> good idea or bad idea?
If you just want a name to give to each bit shift, you can use an enum.
Or better yet, consolidate all of your code that deals with that
register into a C++ class with named methods, and only manipulate the
register via those methods. That keeps all the shifting away from your
actual business logic. (And is a better encapsulated design anyway, and
can be just as fast if the method calls are inlined.)
The point of dynamic_bitset is if you don't know at compile time how
many total bits you want to represent.
If there are a fixed number of bits you're interested in then it doesn't
really gain you anything over bitshifting, since you still have to
identify the bits by number either way. (There are ways to give names
for those numbers, such as the aforementioned enum, but those are
equally applicable to both.)
It also introduces a storage indirection -- you can't read or write a
specific bit directly out of a register any more, you'd have to copy it
first. This is error prone, slower, and may not even be correct, as
some hardware registers have write-only bits or will react differently
to rewriting the same bit value than plain memory does.
So all around, no, that seems like a very bad idea.
If you really want to assign names to specific bits or bit ranges and
bit shifting isn't doing it for you (and you don't want to write that
wrapper class for whatever reason), then the best alternative would be
to use C/C++ bitfield structures. You need to be a bit careful with
these (always use an unsigned integer member type unless you really want
each member to have a sign bit), and be aware that they are not
considered portable, as different compilers and/or architectures may
order bits differently or have different rules for padding or when
crossing byte boundaries. But if you're targeting a single compiler and
architecture then this may work well for you, since it makes the
compiler do the shifting for you.
Assuming that you get the bitfield layout correctly matching your
hardware register, you can use a volatile* for your bitfield directly
pointing to the register, and it will just work ... unless the register
happens to be one of the ones that requires you to write to multiple
bitfields simultaneously, in which case things get trickier, and you
have to go even further into the unportable weeds.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk