elasticsearch入門系列">elasticsearch入門系列
753
2022-05-29
在進一步分析之前,本文我們先來熟悉下LiteOS提供的輔助功能模塊–位操作,在互斥鎖等模塊對位操作有使用。位操作是指對二進制數的bit位進行操作。程序可以設置某一變量為狀態字,狀態字中的每一bit位(標志位)可以具有自定義的含義。文中所涉及的源代碼,均可以在LiteOS開源站點https://gitee.com/LiteOS/LiteOS 獲取。位操作模塊源代碼、開發文檔如下:
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開發指南位操作文檔。
LiteOS位操作模塊提供對32位無符號整數數值的bit位操作,bit位取值為0-31,以0開始計算,從左向右,第0位,第1位。。。第31位等。定義的宏OS_BITMAP_MASK如下,也就是十進制31。如果傳入的bit為大于31,會通過邏輯與運算截斷(pos & OS_BITMAP_MASK),只取低5位,確保不會大于31,避免溢出。
#define OS_BITMAP_MASK 0x1FU
Huawei LiteOS的位操作模塊提供標志位的置1和清0操作,可以改變標志位的內容,同時還提供獲取狀態字中標志位為1的最高位和最低位的功能。用戶也可以對系統的寄存器進行位操作。
下面,我們剖析下位操作的源代碼。
位操作常用功能
位操作提供了4個API,進行置1、清0、獲取為1的最高、最低位等操作,如下:
LOS_BitmapSet()對狀態字的某一標志位進行置1操作
對狀態字的某一標志位進行置1操作。我們先看看傳入的參數,需要的2個參數分別是:需要改變bit位內容的狀態字UINT32 *bitmap,需要改變的bit位位數UINT16 pos。
代碼很簡單,首先進行基礎的校驗,如果狀態字為空,則返回。然后計算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的最低位
代碼其中CTZ(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位操作模塊的源代碼,代碼非常簡單,參考官方示例程序代碼,實際編譯運行一下,加深理解。
感謝閱讀,如有任何問題、建議,都可以留言給我們: https://gitee.com/LiteOS/LiteOS/issues 。為了更容易找到LiteOS代碼倉,建議訪問 https://gitee.com/LiteOS/LiteOS ,關注Watch、Star、并Fork到自己賬戶下,如下圖,謝謝。
輕量級操作系統 LiteOS
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。