LiteOS內核源碼分析:位操做模塊

摘要:本文帶領你們一塊兒剖析了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位操做模塊的源代碼,代碼很是簡單,參考官方示例程序代碼,實際編譯運行一下,加深理解。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索