Hi, 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? Thank you. Kind regards, jupiter -- "A man can fail many times, but he isn't a failure until he begins to blame somebody else." -- John Burroughs
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.
Thanks Gavin,
Right, it is to read and to write STPM32 chipset via UART, definitely
to use a wrapper class to define each register value, each bit field
can be hidden inside shift functions to increase visibility of the
variables.
Thank you.
jupiter
On 7/2/20, Gavin Lambert via Boost
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.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- "A man can fail many times, but he isn't a failure until he begins to blame somebody else." -- John Burroughs
On Thu, 2 Jul 2020 at 11:02, Jupiter via Boost
Thanks Gavin,
Right, it is to read and to write STPM32 chipset via UART, definitely to use a wrapper class to define each register value, each bit field can be hidden inside shift functions to increase visibility of the variables.
Why would you do this? C and C++ already has a language mechanism for this: struct UART { int reg_a : 8; int reg_b : 8; int reg_c : 8; // etc }; #define my_uart (*(UART *)0xaddress) // perform read auto data = my_uart.reg_a;
Thank you.
jupiter
On 7/2/20, Gavin Lambert via Boost
wrote: 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.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- "A man can fail many times, but he isn't a failure until he begins to blame somebody else." -- John Burroughs
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Richard Hodges hodges.r@gmail.com office: +442032898513 home: +376841522 mobile: +376380212
Hi Richard,
On 7/2/20, Richard Hodges via Boost
Why would you do this?
C and C++ already has a language mechanism for this:
struct UART { int reg_a : 8; int reg_b : 8; int reg_c : 8; // etc };
#define my_uart (*(UART *)0xaddress)
// perform read auto data = my_uart.reg_a;
Is that simple? Or are we doing something stupid? Our read / write functions are based on STPM32 document communication protocol, it is very complicated, we have to open driver and fd, we have to rung CRC check, we have to run ByteSwap, are those steps unnecessary and can be replaced by a single a single read line auto data = my_uart.reg_a;? Will be very grateful if we are missed C++ or boost functions call and if there is way to simplify our code. Thank you. jupiter -
Thank you.
jupiter
On 7/2/20, Gavin Lambert via Boost
wrote: 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.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- "A man can fail many times, but he isn't a failure until he begins to blame somebody else." -- John Burroughs
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Richard Hodges hodges.r@gmail.com office: +442032898513 home: +376841522 mobile: +376380212
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- "A man can fail many times, but he isn't a failure until he begins to blame somebody else." -- John Burroughs
participants (3)
-
Gavin Lambert
-
Jupiter
-
Richard Hodges