What is the most efficient way to work with large amount of bits on ESP32?
Posted: Thu Oct 26, 2023 5:31 pm
For example in Microchip C99 compiler you can declare something like this:
volatile uint8_t VAL @ (0x600)
volatile bit SomeBit0 @ (0x600 << 3 + 0)
volatile bit SomeBit1 @ (0x600 << 3 + 1)
volatile bit SomeBit2 @ (0x600 << 3 + 2)
volatile bit SomeBit3 @ (0x600 << 3 + 1)
...
(don't be confused with those shifting. Think about it just like if whole RAM is an array of bits, then index of any bit in whole RAM could be calculated as ADRESS * 8 + BitIndexWithinByte. Well, that expression is exactly that calculation)
C99 compiler doesn't care how many "names" you assign to some address.
Such declaration allows accessing a byte at address 0x600 on usual way, for example,
VAL = 15;
but it also allows accessing a bits at the same address like
if(SomeBit2) { ....}
or
SomeBit3 = true;
Sure, it is because at assembly level, there are instructions capable to access to a single bit at any location in RAM.
Is there an efficient way to do similar things on ESP32? I understand that I can always access whole 32 bit word, do proper masking to isolate any specific bit, but question is related actually to avoid that if possible.
Is there a way to make packed struct something like:
typedef packed struct {
bit bit0;
bit bit1;
bit bit2;
...
bit bit31;
} bitfield_t;
so C compiler becomes aware of it and allocate JUST ONE 32bit word in memory when some variable is declared of bitfield_t type? In such a case you would be able to declare something like
bitfield_t VAL;
VAL.bit5 = true;
or
if(! VAL.bit8) { ...}
but also
*((uint32_t *) (& VAL)) = 0; to clear all bits at once
or use any other value to set/clear specific bits
*((uint32_t *) (& VAL)) = 0x03030303
volatile uint8_t VAL @ (0x600)
volatile bit SomeBit0 @ (0x600 << 3 + 0)
volatile bit SomeBit1 @ (0x600 << 3 + 1)
volatile bit SomeBit2 @ (0x600 << 3 + 2)
volatile bit SomeBit3 @ (0x600 << 3 + 1)
...
(don't be confused with those shifting. Think about it just like if whole RAM is an array of bits, then index of any bit in whole RAM could be calculated as ADRESS * 8 + BitIndexWithinByte. Well, that expression is exactly that calculation)
C99 compiler doesn't care how many "names" you assign to some address.
Such declaration allows accessing a byte at address 0x600 on usual way, for example,
VAL = 15;
but it also allows accessing a bits at the same address like
if(SomeBit2) { ....}
or
SomeBit3 = true;
Sure, it is because at assembly level, there are instructions capable to access to a single bit at any location in RAM.
Is there an efficient way to do similar things on ESP32? I understand that I can always access whole 32 bit word, do proper masking to isolate any specific bit, but question is related actually to avoid that if possible.
Is there a way to make packed struct something like:
typedef packed struct {
bit bit0;
bit bit1;
bit bit2;
...
bit bit31;
} bitfield_t;
so C compiler becomes aware of it and allocate JUST ONE 32bit word in memory when some variable is declared of bitfield_t type? In such a case you would be able to declare something like
bitfield_t VAL;
VAL.bit5 = true;
or
if(! VAL.bit8) { ...}
but also
*((uint32_t *) (& VAL)) = 0; to clear all bits at once
or use any other value to set/clear specific bits
*((uint32_t *) (& VAL)) = 0x03030303