ビットマスクとは?
組み込みソフトをやっていると、ビット演算が必要なことが多々あります。
たとえば、ペリフェラルのレジスタを書き換えるとき。
上はxilinxのAXI UART liteのControl Registerです。
Rst Rx FIFOはUARTの受信fifoの中身をリセットするbitですが、ここにアクセスするためには、他のbitの設定は変えず、2bit目だけの設定を変更する必要があります。
つまり、ある特定のbitの設定のみを変えて他bitの設定はそのままにする という操作がよく出てきます。
そこで必要となるのがビットマスクです。
ビットマスクは文字通り、特定のビットに対してのみ操作を行いたいときに使うマスクのことです。
例えば、上の例で考えると0x00000002がビットマスクになります。
ビットマスクの使い方
それでは、具体的にビットマスクをどの様に使うか考えていきます。
特定のビットを操作する
ここでは例として
ビットマスクで指定されたbitを1にセットする関数(bitset())
ビットマスクで指定されたbitを0にする関数(bitclr())
を作ってみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <stdio.h> #define BITMASK1 0x0002 //2bit目のビットマスク #define BITMASK1 0x8000 //16bit目のビットマスク static uint16_t bitset(uint16_t data_i, uint16_t bitmask); static uint16_t bitclr(uint16_t data_i, uint16_t bitmask); int main(){ uint16_t data=0xAF14; data = bitset(data, BITMASK); printf("data is %04x.\n", data);//出力結果:data is 0xAF34 data = bitclr(data, BITMASK); printf("data is %04x.\n", data);//出力結果:data is 0x2F34 return 0; } static uint16_t bitset(uint16_t data_i, uint16_t bitmask){ data_i |= bitmask; return data_i; } static uint16_t bitclr(uint16_t data_i, uint16_t bitmask){ data_i &= ~bitmask; return data_i; } |
複数のビットを操作する
ここまでの例ではある特定のbitのみを操作していましたが、複数のbitを操作することもできます。
これは、一番最初に示したような特定のレジスタフィールドを操作するときに役立ちます。
次のような例を考えます。
16bitのデータのうち、data[12:10]の3bitの領域のみの値を更新します。
このように複数のbitを操作する場合にも、先ほどと同じようにbitmaskを使用します。
今回の場合はビットマスクは0x1C00(16’b0001_1100_0000_0000)となります。
以下に data[12:10] の値を0x6(3’b110)に更新する例を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <stdio.h> #define BITMASK 0x1C00 //[12:10]のビットマスク static uint16_t field_set(uint16_t data_i, uint16_t new_val, uint16_t bitmask); int main(){ uint16_t data = 0x01FA; uint16_t new_val = 0x6; data = field_set(data, new_val<<10, BITMASK); printf("data is %04x.\n", data);//出力結果:data is 0x19FA return 0; } static uint16_t field_set(uint16_t data_i, uint16_t new_val, uint16_t bitmask){ data_i = (data_i & ~bitmask) | (new_val & bitmask); return data_i; } |
bitフィールドの更新関数bit_field()の処理について詳しく見てみます。