You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
These couple of C++20 headers provide a new, more flexible way of manipulating bit-fields.
3
+
This header-only C++20 library provides a new, portable and more flexible way of manipulating bit-fields.
4
4
While the current codebase is functional, it is overall still in the concept development phase,
5
-
with important features on the horizon. Feedback is very welcome!
5
+
with important features on the horizon. [Feedback](https://github.com/IntergatedCircuits/bitfilled/discussions) is very welcome!
6
6
7
7
## Introduction
8
8
9
-
Let's look at the C(++) language's [built-in bit field][stdbitfield] first:
9
+
What makes bitfilled different from the language standard's [bit fields][stdbitfield]?
10
+
11
+
1.**Portability** - regardless of platform or toolchain, the code behavior is the same (**except MSVC**, as it refuses to implement `[[no_unique_address]]`)
12
+
2.**Performance** - optimized binary is identical to standard bit fields
13
+
3.**Flexibility** - allows bit fields on custom types, bit field arrays, and customizing bit operations (e.g. bit-banding)
14
+
15
+
## Containing types
16
+
17
+
One key thing to note in advance is that bitfilled fields are closely tied with their containing class,
18
+
as it defines the available memory size and alignment, and bit field operations.
19
+
Therefore let's go through these types first:
20
+
21
+
### 1. Host integers
22
+
23
+
The `host_integer` type is simply encapsulating an integral type, forwarding all operations to it,
24
+
and provides the necessary scope information to the bitfilled member fields:
Our `nextgen` type's bit-fields work with the exact same syntax as their `legacy` counterparts.
44
-
The difference here is that a `nextgen` object can be converted to and from any `uint8_t` type,
45
-
no more explicit casting necessary to get the underlying integer type.
46
-
One thing to note is that the nextgen fields have absolute bit offsets, as opposed to the legacy
47
-
fields (which in turn only have a bit size specifier).
48
-
This characteristic of the behavior also means that nextgen's bit-fields can be made to overlap one another.
95
+
These fields can be accesses as regular members, however their value is stored inside the containing class's (superclass's) memory. Bit field set elements are accessible via `operator[]`.
96
+
97
+
I encourage everyone to try it online:
98
+
https://godbolt.org/z/bba7a8sTT
99
+
100
+
### Register bit fields
101
+
102
+
Let's look at a more advanced use-case, memory-mapped register definition.
103
+
We will use the SysTick timer, found in most popular ARM MCUs:
104
+
105
+
```cpp
106
+
#include<bitfilled/bitfilled.hpp>
107
+
structsystick {
108
+
struct csr : BF_MMREG(std::uint32_t, rw) {
109
+
BF_COPY_SUPERCLASS(csr)
110
+
BF_MMREGBITS(bool, r, 16) COUNTFLAG;
111
+
BF_MMREGBITS(bool, rw, 2) CLKSOURCE;
112
+
BF_MMREGBITS(bool, rw, 1) TICKINT;
113
+
BF_MMREGBITS(bool, rw, 0) ENABLE;
114
+
} CSR;
115
+
struct rvr : BF_MMREG(std::uint32_t, rw) {
116
+
BF_COPY_SUPERCLASS(rvr)
117
+
BF_MMREGBITS(bool, rw, 0, 23) RELOAD; // optional, same as accessing the register itself
118
+
} RVR;
119
+
struct cvr : BF_MMREG(std::uint32_t, rw) {
120
+
BF_COPY_SUPERCLASS(cvr)
121
+
BF_MMREGBITS(bool, rw, 0, 23) CURRENT; // any write clears the field and COUNTFLAG to 0
The code is self-explanatory, and provides an accurate interface to the hardware, by accessing the `SYSTICK` reference. As an example, the `COUNTFLAG` bit is read-only in an otherwise read-write register, which is reflected in its definition, and consequently assigning a value to this member is a compile-time error. The same is true for the `CALIB` register, and all its fields.
133
+
134
+
A fully functional MM I/O example is available [here][bitfilled-stm32f4],
135
+
where the **significant** code size savings are also illustrated.
136
+
137
+
The project also comes with a [python code generator](tools/svd2mmregmap.py) (draft version),
138
+
that let's you create register map definition out of CMSIS SVD files.
49
139
50
140
## Theory of operation
51
141
@@ -70,16 +160,11 @@ but rather whichever member is preceeding them in the encapsulating type layout.
70
160
Therefore the encapsulating type must have a preceeding member variable for bit-field use,
71
161
and the bitfilled members must be made aware of this member variable's type - this is what the operators are achieving.
72
162
Mismatches between the storage member variable and the operators type is impossible to catch at compile time,
73
-
therefore it is recommended to use predefined helper base classes such as `bitfilled::host_integer` and `bitfilled::mmreg`,
163
+
therefore it is necessary to use predefined helper base classes such as `bitfilled::host_integer` and `bitfilled::mmreg`,
74
164
instead of defining the storage member variable and the operators independently.
75
165
76
-
## Memory mapped registers
77
-
78
-
This library goes beyond simple bit-field manipulation by providing an accurate and easy-to-use API
79
-
for memory-mapped register and bit-field manipulation, including access limitations on all levels,
0 commit comments