View unanswered posts | View active topics It is currently Mon Dec 10, 2018 3:08 pm



Reply to topic  [ 12 posts ]  Go to page 1, 2  Next
Bit fields and (very)short integers! 
Author Message
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 15200
Location: Home sweet home!
Why didn't someone tell me about these things?!?! I was reading someone elses firmware code last night (GPL) and saw this :

Code:
   struct s_flags
   {
      unsigned inj_occurred   :1;
      unsigned cranking      :1;
      unsigned running      :1;
      unsigned asc         :1;
      unsigned roc_update      :1;
      unsigned iac_update      :1;
      unsigned iac_reset      :1;
      unsigned cts_update      :1;
   }


And when used they look like this :

Code:
status.flags.inj_occurred = TRUE;


And this :

Code:
if (status.flags.inj_occurred){//Do work}


I'm currently ashamed of and embarrassed by my code. I'll be converting it to use these in the nearish future...

It's night and day better...

THANK YOU cpuTorture!!!

Fred.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Tue Apr 20, 2010 12:11 am
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 15200
Location: Home sweet home!
Additionally, for shorter than one byte integers nested inside registers this is ideal. You can just use :2 instead and you've got yourself 0 - 3 or :3 for 0 - 7 etc!

Fred.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Tue Apr 20, 2010 12:15 am
Profile WWW
LQFP144 - On Top Of The Game
User avatar

Joined: Mon Feb 11, 2008 10:52 pm
Posts: 549
Location: Arizona
Sorry, I do remember bit fields from K&R.

_________________
You snooze, you lose!


Tue Apr 20, 2010 12:16 am
Profile YIM
LQFP144 - On Top Of The Game
User avatar

Joined: Mon Feb 11, 2008 10:52 pm
Posts: 549
Location: Arizona
I wonder if it's as fast though............... with bit fields inorder to "get" a bit from a byte it must do a bit-wise then use that value, not just use the value. What do you think ?

_________________
You snooze, you lose!


Tue Apr 20, 2010 12:18 am
Profile YIM
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 15200
Location: Home sweet home!
I think it's just going to mask it off as we do manually at the moment.

Each and every time I set a bit, I have to use or or and and a mask. It'll just be doing this behind the scenes. We can write some test code to try it out and compare the binary/assembly, but it'll probably be the same or better. Even if it's worse, it's going to clean up the code no end!

The code above runs on a 2mhz cpu... this guy cares about speed a LOT. So I doubt it's slow for that reason too!

I did try to search for boolean types early on, but I failed to find this, mostly because its not a boolean type, really.

I'm excited about doing the change :-)

Fred.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Tue Apr 20, 2010 12:36 am
Profile WWW
LQFP144 - On Top Of The Game
User avatar

Joined: Mon Feb 11, 2008 10:52 pm
Posts: 549
Location: Arizona
Sorry from your first post I thought you were using entire bytes for bits. I should have known better :)

_________________
You snooze, you lose!


Tue Apr 20, 2010 2:21 am
Profile YIM
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 15200
Location: Home sweet home!
I considered that early on too, but it was a factor of 8 too wasteful LOL :-)

Fred.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Tue Apr 20, 2010 2:38 am
Profile WWW
LQFP112 - Up with the play
User avatar

Joined: Thu Sep 10, 2009 9:23 am
Posts: 244
Location: Dayton, OH
thats the beauty of bitfield .. you lean on the compiler to do all the masking/shifting for you .. but I think each has their place.

'old-school' firmware folks that I know hate them with a passion .. because they 'can't trust the compiler'. When I point out all their masking/shifting screwups, they get even madder .. because they have never been able to point back and show me where the compiler has ever screwed up on me.

I make personal exceptions for clarity, here's an example from some code i just did a couple of days ago. it's for some dead simple pin setup code. this is just for a couple of simple single bit fields in a register (which has more fields) but I want to keep the example short:

#define OUTPUT_BUFFER_ENABLE ( 1 << 10 )
#define OUTPUT_MODE ( 1 << 10 )
#define INPUT_BUFFER_ENABLE ( 1 << 9 )
#define INPUT_MODE ( 1 << 9 )
#define READBACK_ENABLE ( 1 << 9 )

I can construct things like:
func( GPIO | OUTPUT_MODE | READBACK_ENABLE ); // 'descriptive'
vs
func( GPIO | OUTPUT_BUFFER_ENABLE | INPUT_BUFFER_ENABLE ); // 'dry'
which mean the same thing ...

as an alternative, using the bitstruct way, ponder this ... how would you handle r-m-w operations atomically on a register when you had to setup multiple fields (i can give an example of how I would do it) ? sometimes the code gets a bit longer than you anticipated .. but its safer since the compiler is working for you.

I also have some other things I do for multi-bit fields to get some asserts() and 'contract-like' programming into my code .. which all compiles out w/NDEBUG like all of the other asserts.

you MAY also run into ordering issues if you use different compilers within the same platform - its considered a highly unportable construct to be using .. so do you trade the danger of shifting/masking across platforms or do you just change the ordering of your struct ?? tradeoffs everywhere in C.


did I go way off track on this ? tell me where to expand if you're interested. I can throw in some 'non-sensitive' real world current examples.


Tue Apr 20, 2010 4:07 am
Profile
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 15200
Location: Home sweet home!
Hmmmmmmmmmmmmmmmmm

Mask:
Code:
.LSM189:
   ldd   coreStatusA
   anda   #2
   andb   #0
   tbeq   d,.L74


Bitfield:
Code:
.LSM189:
   ldab   coreStatusA+1
   rolb
   ldab   #0
   rolb
   beq   .L74


I'm unsure about the number of bus cycles those intructions take, but assuming its 1 each or equal between the two, bitfields are slower and regardless they are definitely bigger :-/

Code:
fred@roadeee [07:39:54]:src$ l masks/firmware/
total 900
-rwxr-xr-x 1 fred fred 150742 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-LT1-360-8.s19
-rwxr-xr-x 1 fred fred 150622 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-MiataNB.s19
-rwxr-xr-x 1 fred fred 151860 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-MissingTeeth.s19
-rwxr-xr-x 1 fred fred 153666 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-NipponDenso.s19
-rwxr-xr-x 1 fred fred 152220 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-Simple.s19
-rwxr-xr-x 1 fred fred 150622 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-Subaru-36-2-2-2.s19
fred@roadeee [07:39:55]:src$ l bitfield/firmware/
total 900
-rwxr-xr-x 1 fred fred 150768 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-LT1-360-8.s19
-rwxr-xr-x 1 fred fred 150634 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-MiataNB.s19
-rwxr-xr-x 1 fred fred 151872 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-MissingTeeth.s19
-rwxr-xr-x 1 fred fred 153754 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-NipponDenso.s19
-rwxr-xr-x 1 fred fred 152232 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-Simple.s19
-rwxr-xr-x 1 fred fred 150634 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-Subaru-36-2-2-2.s19


Granted, not much, but still...

A bit disappointing :-/

Fred.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Sun May 30, 2010 8:43 pm
Profile WWW
LQFP112 - Up with the play
User avatar

Joined: Thu Sep 10, 2009 9:23 am
Posts: 244
Location: Dayton, OH
Every single platform I've written to it always comes out bigger ... except for one .. if was on 8051. Mostly, I think its an optimization issue and the '51 compiler devs probably put the extra effort in to ensure it was still efficient.
I bet if you targeted a platform like ia32 .. someone has put the effort into the gcc optimizer.


Sun May 30, 2010 8:53 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 12 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software for PTF. ColorizeIt.