What is the most efficient way to work with large amount of bits on ESP32?

djixon
Posts: 113
Joined: Sun Oct 01, 2023 7:48 pm

What is the most efficient way to work with large amount of bits on ESP32?

Postby djixon » 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

User avatar
ok-home
Posts: 78
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: What is the most efficient way to work with large amount of bits on ESP32?

Postby ok-home » Thu Oct 26, 2023 8:09 pm

hi
something similar to standard С
https://github.com/espressif/esp-idf/bl ... o_struct.h

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: What is the most efficient way to work with large amount of bits on ESP32?

Postby MicroController » Thu Oct 26, 2023 9:29 pm

Yes, standard C has bit-fields. And the "packed" attribute coerces gcc to pack multiple bits into each byte.

Like

Code: Select all

#include <stdint.h>
#include <stdbool.h>

#define PCKD __attribute__((packed))

typedef struct PCKD  {
    uint32_t bit1 : 1; // 1-bit value
    uint32_t bit2 : 1; // 1-bit value
    uint32_t bit3 : 1; // 1-bit value
    // etc.
} my_bits_t;


typedef struct PCKD {
    union PCKD {
        my_bits_t bits;
        uint32_t u32;
    };
} my_bit_values_t;

void clear(my_bit_values_t* const bv) {
    bv->u32 = 0;
}

void setBit_3(my_bit_values_t* const bv, const bool value) {
    bv->bits.bit3 = value;
}

djixon
Posts: 113
Joined: Sun Oct 01, 2023 7:48 pm

Re: What is the most efficient way to work with large amount of bits on ESP32?

Postby djixon » Thu Oct 26, 2023 11:30 pm

Well, 6 assembler instructions just for setting a single bit is far away from efficient.
https://godbolt.org/z/K9jzfYT5s

But it looks it can't be improved more due to non implemented assembly instructions for direct bit manipulation.

Thx anyway.

EDIT:
@microcontroller: I thought there are asm instructions for direct bit manipulation but after checking asm manuals for LX6 and LX7 I realized that those don't exist. So compiler generate code for proper masking (memw for committing any changes, fetching variable, fetching mask, ORring/ANDing, another committing and finally storing back register to variable location)

Who is online

Users browsing this forum: No registered users and 72 guests