1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-22 07:45:24 +03:00

Add a proper type for bit arrays

- Define type bitArrayElement_t as uint32_t.
- Add BITARRAY_DECLARE() macro, which declares a bit array given
the number of desired bits, taking care of aligment and rounding
up its size to a multiple of 32.
- Change bit array functions to accept bitarrayElement_t* rather
than void*.
- Replace bit array declarations with BITARRAY_DECLARE() macro
- Add BITARRAY_FIND_FIRST_SET() macro to call bitArrayFindFirstSet()
without explicitely specifying its size.
- Update comments in bitarray.h to reflect these changes.
This commit is contained in:
Alberto García Hierro 2017-09-15 09:53:53 +01:00
parent daa4c17c3b
commit 9fd3b4286f
6 changed files with 28 additions and 20 deletions

View file

@ -24,17 +24,17 @@
// to find set bits faster. // to find set bits faster.
#define BITARRAY_BIT_OP(array, bit, op) ((array)[(bit) / (sizeof((array)[0]) * 8)] op ((1u<<31) >> ((bit) % (sizeof((array)[0]) * 8)))) #define BITARRAY_BIT_OP(array, bit, op) ((array)[(bit) / (sizeof((array)[0]) * 8)] op ((1u<<31) >> ((bit) % (sizeof((array)[0]) * 8))))
bool bitArrayGet(const void *array, unsigned bit) bool bitArrayGet(const bitarrayElement_t *array, unsigned bit)
{ {
return BITARRAY_BIT_OP((uint32_t*)array, bit, &); return BITARRAY_BIT_OP((uint32_t*)array, bit, &);
} }
void bitArraySet(void *array, unsigned bit) void bitArraySet(bitarrayElement_t *array, unsigned bit)
{ {
BITARRAY_BIT_OP((uint32_t*)array, bit, |=); BITARRAY_BIT_OP((uint32_t*)array, bit, |=);
} }
void bitArrayClr(void *array, unsigned bit) void bitArrayClr(bitarrayElement_t *array, unsigned bit)
{ {
BITARRAY_BIT_OP((uint32_t*)array, bit, &=~); BITARRAY_BIT_OP((uint32_t*)array, bit, &=~);
} }
@ -52,7 +52,7 @@ __attribute__((always_inline)) static inline uint8_t __CLZ(uint32_t val)
#endif #endif
} }
int bitArrayFindFirstSet(const void *array, unsigned start, size_t size) int bitArrayFindFirstSet(const bitarrayElement_t *array, unsigned start, size_t size)
{ {
const uint32_t *ptr = (uint32_t*)array; const uint32_t *ptr = (uint32_t*)array;
const uint32_t *end = ptr + (size / 4); const uint32_t *end = ptr + (size / 4);

View file

@ -20,16 +20,22 @@
/* /*
* These functions expect array to be 4-byte aligned since they alias array * These functions expect array to be 4-byte aligned since they alias array
* to an uint32_t pointer in order to work fast. * to an uint32_t pointer in order to work fast. Use the BITARRAY_DECLARE()
* macro to declare a bit array that can be safely used by them.
*/ */
bool bitArrayGet(const void *array, unsigned bit); typedef uint32_t bitarrayElement_t;
void bitArraySet(void *array, unsigned bit);
void bitArrayClr(void *array, unsigned bit); #define BITARRAY_DECLARE(name, bits) bitarrayElement_t name[(bits + 31) / 32]
bool bitArrayGet(const bitarrayElement_t *array, unsigned bit);
void bitArraySet(bitarrayElement_t *array, unsigned bit);
void bitArrayClr(bitarrayElement_t *array, unsigned bit);
// Returns the first set bit with pos >= start_bit, or -1 if all bits // Returns the first set bit with pos >= start_bit, or -1 if all bits
// are zero. // are zero. Note that size must indicate the size of array in bytes.
// Note that size must indicate the size of array in bytes. // In most cases, you should use the BITARRAY_FIND_FIRST_SET() macro
// // to call this function.
// WARNING: This function only works for arrays where size is a multiple int bitArrayFindFirstSet(const bitarrayElement_t *array, unsigned start_bit, size_t size);
// of 4.
int bitArrayFindFirstSet(const void *array, unsigned start_bit, size_t size); #define BITARRAY_FIND_FIRST_SET(array, start_bit) bitArrayFindFirstSet(array, start_bit, sizeof(array))

View file

@ -183,7 +183,7 @@ uint16_t maxScreenSize = VIDEO_BUFFER_CHARS_PAL;
// in screenIsDirty to upgrade only changed chars this solution // in screenIsDirty to upgrade only changed chars this solution
// is faster than redrawing the whole screen on each frame // is faster than redrawing the whole screen on each frame
static uint8_t screenBuffer[VIDEO_BUFFER_CHARS_PAL] ALIGNED(4); static uint8_t screenBuffer[VIDEO_BUFFER_CHARS_PAL] ALIGNED(4);
static uint8_t screenIsDirty[VIDEO_BUFFER_CHARS_PAL/8] ALIGNED(4) = {0,}; static BITARRAY_DECLARE(screenIsDirty, VIDEO_BUFFER_CHARS_PAL);
//max chars to update in one idle //max chars to update in one idle
#define MAX_CHARS2UPDATE 5 #define MAX_CHARS2UPDATE 5

View file

@ -417,7 +417,7 @@ static void packBoxModeFlags(boxBitmask_t * mspBoxModeFlags)
memset(mspBoxModeFlags, 0, sizeof(boxBitmask_t)); memset(mspBoxModeFlags, 0, sizeof(boxBitmask_t));
for (uint32_t i = 0; i < activeBoxIdCount; i++) { for (uint32_t i = 0; i < activeBoxIdCount; i++) {
if (activeBoxes[activeBoxIds[i]]) { if (activeBoxes[activeBoxIds[i]]) {
bitArraySet(mspBoxModeFlags, i); bitArraySet(mspBoxModeFlags->bits, i);
} }
} }
} }

View file

@ -66,7 +66,7 @@ bool isUsingNavigationModes(void)
bool IS_RC_MODE_ACTIVE(boxId_e boxId) bool IS_RC_MODE_ACTIVE(boxId_e boxId)
{ {
return bitArrayGet(&rcModeActivationMask, boxId); return bitArrayGet(rcModeActivationMask.bits, boxId);
} }
void rcModeUpdate(boxBitmask_t *newState) void rcModeUpdate(boxBitmask_t *newState)
@ -124,13 +124,13 @@ void updateActivatedModes(void)
if (modeActivationOperatorConfig()->modeActivationOperator == MODE_OPERATOR_AND) { if (modeActivationOperatorConfig()->modeActivationOperator == MODE_OPERATOR_AND) {
// AND the conditions // AND the conditions
if (activeConditionCountPerMode[modeIndex] == specifiedConditionCountPerMode[modeIndex]) { if (activeConditionCountPerMode[modeIndex] == specifiedConditionCountPerMode[modeIndex]) {
bitArraySet(&newMask, modeIndex); bitArraySet(newMask.bits, modeIndex);
} }
} }
else { else {
// OR the conditions // OR the conditions
if (activeConditionCountPerMode[modeIndex] > 0) { if (activeConditionCountPerMode[modeIndex] > 0) {
bitArraySet(&newMask, modeIndex); bitArraySet(newMask.bits, modeIndex);
} }
} }
} }

View file

@ -19,6 +19,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "common/bitarray.h"
#include "config/parameter_group.h" #include "config/parameter_group.h"
typedef enum { typedef enum {
@ -58,7 +60,7 @@ typedef enum {
} boxId_e; } boxId_e;
// type to hold enough bits for CHECKBOX_ITEM_COUNT. Struct used for value-like behavior // type to hold enough bits for CHECKBOX_ITEM_COUNT. Struct used for value-like behavior
typedef struct boxBitmask_s { uint32_t bits[(CHECKBOX_ITEM_COUNT + 31) / 32]; } boxBitmask_t; typedef struct boxBitmask_s { BITARRAY_DECLARE(bits, CHECKBOX_ITEM_COUNT); } boxBitmask_t;
#define MAX_MODE_ACTIVATION_CONDITION_COUNT 20 #define MAX_MODE_ACTIVATION_CONDITION_COUNT 20