Bitmask is a technique that uses bitwise operations to store many true/false flags in a single integer with many advantages:
- Memory efficient: it only costs 1 bit per flag -> 32 flags for an integer
- Faster: Bitwise operations are faster than array operations
Let’s take some examples
1. Unix file permissions
On Unix-like systems, if we run ls -l on a file.
➜ ~ ls -l users.csv
-rw-r--r--@ 1 danieldang staff 5218 Sep 19 2024 users.csv
Notice the -rw-r--r-- Except for the first character which is the file type. The rest 9 characters are the file permissions.
That 9 characters are 3 sets of rwx of each user: owner, group, other. (Also 9 bits in binary)
| Character | Octal | Binary |
|---|---|---|
r | 4 | 100 |
w | 2 | 010 |
x | 1 | 001 |
rwx: 4+2+1 = 7 (octal) -> 100 | 010 | 001 = 111 (binary)
rw-: 4+2 = 6 (octal) -> 100 | 010 = 110 (binary)
r--: 4 (octal) -> 100 (binary)
If we use chmod 755 to set the file permissions, it will be:
7 = 111 = rwx (owner)
5 = 101 = r-x (group)
5 = 101 = r-x (others)
When the computer checks the write permissions of the owner, it will be something like:
111 & 010 = 010 -> true
2. MAVLink protocol
MAVLink is a protocol for communicating with drones. Many of the messages are using bitmask to store the drone status.
Take SYS_STATUS message as an example:
There are 3 fields in 32-bit integer:
| Field | Type | Description |
|---|---|---|
| onboard_control_sensors_present | uint32_t | Bitmap showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. |
| onboard_control_sensors_enabled | uint32_t | Bitmap showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. |
| onboard_control_sensors_health | uint32_t | Bitmap showing which onboard controllers and sensors have an error (or are operational). Value of 0: error. Value of 1: healthy. |
And the defined sensor map are (there are more):
| ID | Sensor | Hex | Description |
|---|---|---|---|
| 1 | MAV_SYS_STATUS_SENSOR_3D_GYRO | 0x00000001 | 3D gyro |
| 2 | MAV_SYS_STATUS_SENSOR_3D_ACCEL | 0x00000002 | 3D accelerometer |
| … | … | … | … |
| 32 | MAV_SYS_STATUS_SENSOR_GPS | 0x00000020 | GPS |
| 33554432 | MAV_SYS_STATUS_SENSOR_BATTERY | 0x2000000 | Battery |
| 268435456 | MAV_SYS_STATUS_PREARM_CHECK | 0x10000000 | pre-arm check status. Always healthy when armed |
| … | … | … | … |
Let’s take a real example:
{
"onboard_control_sensors_present": 325188671,
"onboard_control_sensors_enabled": 274857023,
"onboard_control_sensors_health": 57801791
}
present: 0001 0011 0110 0001 1111 1100 0011 1111
enabled: 0001 0000 0110 0001 1111 1100 0011 1111
health: 0000 1110 0001 0001 1111 1100 0011 1111
GPS:
present & 0x00000020 = 0x00000020 -> true
enabled & 0x00000020 = 0x00000020 -> true
health & 0x00000020 = 0x00000020 -> true
-> GPS is present, enabled, and healthy
Battery:
present & 0x2000000 = 0x2000000 -> true
enabled & 0x2000000 = 0x00000000 -> false
health & 0x2000000 = 0x2000000 -> true
-> Battery is present, NOT enabled, and healthy
Pre-arm check:
present & 0x10000000 = 0x10000000 -> true
enabled & 0x10000000 = 0x10000000 -> true
health & 0x10000000 = 0x00000000 -> false
-> Pre-arm check is present, enabled, and NOT healthy