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

摘要:本文帶領大家一起剖析了LiteOS位操作模塊的源代碼,代碼非常簡單,參考官方示例程序代碼,實際編譯運行一下,加深理解。

本文分享自華爲雲社區《LiteOS內核源碼分析系列五 LiteOS內核源碼分析--位操作模塊》,原文作者:zhushy 。

在進一步分析之前,本文我們先來熟悉下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的最低位

代碼其中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位操作模塊的源代碼,代碼非常簡單,參考官方示例程序代碼,實際編譯運行一下,加深理解。

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章