摘要:本文带领你们一块儿剖析了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位操做模块的源代码,代码很是简单,参考官方示例程序代码,实际编译运行一下,加深理解。