http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000
Bit-field是C語言中比較低階的用法, 可以把一個structure中的bits做更細的切割來存取
比如以下的union / struct混合型
union { uint32_t packed; struct { uint8_t flag1: 1; uint8_t flag2: 1; uint8_t type: 4; } bits; } x;
通常會使用到bit-field的場合:
偷空間
這應該是最主要的理由
某些structure member的值範圍不大, 就可以用bit-field的方式, 將一些member合併在一起
特殊Header structure
以IPv4 header為例
http://en.wikipedia.org/wiki/IPv4#Header
可以用這樣的struct來存取
typedef struct { uint8_t ver: 4; uint8_t ihl: 4; uint8_t dcsp: 6; uint8_t ecn: 2; uint16_t total; ... } ipv4_header_t;PS: 這是big endian的寫法!
寫driver時
使用bit-field來寫就可以模擬成OOP的方式, 對programmer比較friendly
以8051 TMOD register為例 http://www.8052.com/tuttimer.phtml
可以用這樣的structe來存取
typedef struct { uint8_t t0m0: 1; uint8_t t0m1: 1; uint8_t t0: 1; uint8_t gate0: 1; uint8_t t1m0: 1; uint8_t t1m1: 1; uint8_t t1: 1; uint8_t gate1: 1; } tmod_t;PS: 這是little endian的寫法!
Boolean flags
通常程式中用的是Boolean flag, 也就是只有true/false兩種值, 但一個flag變數起碼會佔用1 byte的空間 利用bit-field可以合併不同的flag, 省下空間
特別是函數中的local flags, 用這個技巧, 還能降低CPU register使用量, 提高效率
例如:
int func (int arg) { union { uint8_t packed; struct { uint8_t isArgValid: 1; uint8_t isError: 1; uint8_t isDone: 1; }; } flags; flags.packed = 0; ... if (arg > 0) flags.isArgValid = 1; ... if (!flags.isArgValid) return 0; ... return 1; }
沒有留言:
張貼留言