摘要:本文帶領你們一塊兒剖析了LiteOS位操做模塊的源代碼,代碼很是簡單,參考官方示例程序代碼,實際編譯運行一下,加深理解。
本文分享自華爲雲社區《LiteOS內核源碼分析系列五 LiteOS內核源碼分析--位操做模塊》,原文做者:zhushy 。git
在進一步分析以前,本文咱們先來熟悉下LiteOS提供的輔助功能模塊–位操做,在互斥鎖等模塊對位操做有使用。位操做是指對二進制數的bit位進行操做。程序能夠設置某一變量爲狀態字,狀態字中的每一bit位(標誌位)能夠具備自定義的含義。文中所涉及的源代碼, 都可以在LiteOS
開源站點https://gitee.com/LiteOS/LiteOS 獲取。位操做模塊源代碼、開發文檔以下:ide
- LiteOS內核位操做源代碼
位操做模塊功能比較簡單,包括位操做的頭文件kernel\include\los_bitmap.h、C源代碼文件kernel\base\los_bitmap.c。函數
- 開發指南位操做文檔
在線文檔https://gitee.com/LiteOS/LiteOS/blob/master/doc/LiteOS_Kernel_Developer_Guide.md#%E4%BD%8D%E6%93%8D%E4%BD%9C。源碼分析
咱們先看看位操做的概念核使用場景,詳細的介紹及相關的示例,請參考LiteOS開發指南位操做文檔。ui
LiteOS位操做模塊提供對32位無符號整數數值的bit位操做,bit位取值爲0-31,以0開始計算,從左向右,第0位,第1位。。。第31位等。定義的宏OS_BITMAP_MASK以下,也就是十進制31。若是傳入的bit爲大於31,會經過邏輯與運算截斷(pos & OS_BITMAP_MASK),只取低5位,確保不會大於31,避免溢出。url
#define OS_BITMAP_MASK 0x1FU
Huawei LiteOS的位操做模塊提供標誌位的置1和清0操做,能夠改變標誌位的內容,同時還提供獲取狀態字中標誌位爲1的最高位和最低位的功能。用戶也能夠對系統的寄存器進行位操做。spa
下面,咱們剖析下位操做的源代碼。.net
位操做經常使用功能
位操做提供了4個API,進行置一、清0、獲取爲1的最高、最低位等操做,以下:code
LOS_BitmapSet()對狀態字的某一標誌位進行置1操做
對狀態字的某一標誌位進行置1操做。咱們先看看傳入的參數,須要的2個參數分別是:須要改變bit位內容的狀態字UINT32 *bitmap,須要改變的bit位位數UINT16 pos。blog
代碼很簡單,首先進行基礎的校驗,若是狀態字爲空,則返回。而後計算pos & OS_BITMAP_MASK,只取二進制的低5位,最大位值爲31,避免左移的時候發生溢出。1U << (pos & OS_BITMAP_MASK)就是須要改變內容的狀態字的bit位,經過按位或運算設置狀態字UINT32 *bitmap的指定bit位的內容爲1。
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos) { if (bitmap == NULL) { return; } *bitmap |= 1U << (pos & OS_BITMAP_MASK); }
LOS_BitmapClr()對狀態字的某一標誌位進行清0操做
對狀態字的某一標誌位進行清0操做,代碼和置1操做對應,比較簡單,~(1U << (pos & OS_BITMAP_MASK))表示須要改變內容的狀態字的bit位爲0,其他位爲1,而後經過按位與運算設置狀態字UINT32 *bitmap的指定bit位的內容爲0。
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
{ if (bitmap == NULL) { return; } *bitmap &= ~(1U << (pos & OS_BITMAP_MASK)); }
LOS_HighBitGet()獲取狀態字中爲1的最高位
代碼中CLZ(bitmap)是宏,展開爲(__builtin_clz(bitmap)),這是編譯器內置的高效位運算的庫函數,clz是count leading zeros的縮寫,就是統計二進制數值中高位區開頭的全是0的數目。使用OS_BITMAP_MASK減去該值,結果就是狀態字中的1的最高位。
UINT16 LOS_HighBitGet(UINT32 bitmap) { if (bitmap == 0) { return LOS_INVALID_BIT_INDEX; } return (OS_BITMAP_MASK - CLZ(bitmap)); }
LOS_LowBitGet()獲取狀態字中爲1的最低位
代碼其中CLZ(bitmap)是宏,展開爲(__builtin_ctz(value)),這是編譯器內置的高效位運算的庫函數,ctz是count trailing zeros的縮寫,就是統計二進制數值中低位區結尾的全是0的數目,該結果就是狀態字中的1的最低位。
UINT16 LOS_LowBitGet(UINT32 bitmap) { if (bitmap == 0) { return LOS_INVALID_BIT_INDEX; } return CTZ(bitmap); }
小結
本文帶領你們一塊兒剖析了LiteOS位操做模塊的源代碼,代碼很是簡單,參考官方示例程序代碼,實際編譯運行一下,加深理解。