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
What is the most efficient way to work with large amount of bits on ESP32?
-
- 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?
Yes, standard C has bit-fields. And the "packed" attribute coerces gcc to pack multiple bits into each byte.
Like
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;
}
Re: What is the most efficient way to work with large amount of bits on ESP32?
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)
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