Page 1 of 1

Bitfields in data

Posted: Sun Jul 26, 2026 12:25 pm
by mnfisher
Currently I need to use bitfields in some code.

On a PIC I can do REGISTERbits.FIELD = value for register values. I wanted a simple way to do this for variables.

I could define two constants field_start, field_width

Code: Select all

.mask = pow(2,field_width) - 1 
.value = .value & .mask // Check the value will fit in the field
.mask = .mask << .field_start
.value = .value << field_start
.var = (.var & (~.mask)) | .value
An idea (which came to me as I drove home) to use just one constant....

Here the constant defines the field width and start
e.g. 0b00111100 would define a 4 bit field at position 2

The attached demonstrates this: It will be slower - it has to 'calculate' the shift needed by finding the start of the bitfield (on AVR and PIC this isn't too bad compared to .val = .val << .shift but other processors handle the multiple shifts in the same time as 1) Here I use 16 bit values (which is what I needed - but it could be modified for 8 or 32 bits.)
SetBitField modifies 'data' (it would probably be more correct to return the new value!)
Just added a GetBitfield too :-)

Modern processors (x86 etc) have an instruction that does this (and it allows masks such as 0b10101010)

An alternative:
The constant holds the field start and width - for example as 8 bits each in a 16 bit varIable.

Any thoughts / comments / ideas?

Martin

Re: Bitfields in data

Posted: Mon Jul 27, 2026 8:00 am
by mnfisher
And I went with 4 bits (nibbles) each for width and position.

Make every byte count :-)

Re: Bitfields in data

Posted: Mon Jul 27, 2026 9:14 am
by Steve-Matrix
Thanks for sharing, Martin. That's a useful technique, especially when ram is tight.

I wonder if this can be implemented within a component or in Flowcode itself.

Re: Bitfields in data

Posted: Mon Jul 27, 2026 3:48 pm
by mnfisher
I did a quick component - assuming unused macros are optimised away.

This supports SetBitfield8, 16 and 32 (on an 8 bit MCU 16 and 32 bit shifts are rather slower)
GetBitfield8,16 and 32
SetField4bit and GetField4bit - set or retrieve a field using a byte where upper nibble is position and lower nibble is width of the field (only 16 bit here - but 8 bit could be supported (32 bit would need a word descriptor))
SetBit8, 16, 32 - sets a bit in a byte, word or long

Note that the Set 'field' macros modify the value passed (which must be a lvalue not a constant) - rather than returning a value. SetBit returns a value - this isn't consistent - and suggestions as to which is preferred? (Returning a value is probably better?)

Could add GetBit macros.

SetField macros can also be used to write / read single bits (but slower)

All should work in simulation too - I've only tested the 16bit variants if any one would to have a play and try some more values?

Martin