/* ---------------------------------------------------------------------------- * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. * Description: Basic definitions * Author: Huawei LiteOS Team * Create: 2013-01-01 * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * 3. Neither the name of the copyright holder nor the names of its contributors may be used * to endorse or promote products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ /** * @defgroup kernel Kernel * @defgroup los_base Basic definitions * @ingroup kernel */ #ifndef _LOS_BASE_H #define _LOS_BASE_H #include "los_builddef.h" #include "los_typedef.h" #include "los_config.h" #include "los_printf.h" #include "los_list.h" #include "los_err.h" #include "los_errno.h" #include "los_hw.h" #include "los_tick.h" #include "securec.h" #ifdef LOSCFG_LIB_LIBCMINI #include "stdarg.h" #endif #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ /** * @ingroup los_base * @brief Assertion. * * @par Description: * When the program runs to the assertion position, the corresponding expression should * be true. If the expression is not true, the program stops running and gives an error * message. The LOS_ASSERT_COND function is same with #LOS_ASSERT function. * * @attention * The function is effective only LOSCFG_DEBUG_VERSION is defined. * * @param expression [IN] The judgement expression of the assertion. * * @retval None. * @par Dependency: * * @see LOS_ASSERT * @since Huawei LiteOS V100R001C00 */ #define LOS_ASSERT_COND(expression) LOS_ASSERT(expression) //这是一个宏函数,它接受一个表达式作为参数,并将该表达式作为参数传递给另一个名为LOS_ASSERT的宏函数。它的作用是在满足给定条件时执行断言。 /** * @ingroup los_base * Define the timeout interval as LOS_NO_WAIT. */ #define LOS_NO_WAIT 0 //这是一个常量,被定义为0。它表示一个超时时间间隔,即表示不等待,立即返回。 /** * @ingroup los_base * Define the timeout interval as LOS_WAIT_FOREVER. */ #define LOS_WAIT_FOREVER 0xFFFFFFFF //这是另一个常量,被定义为0xFFFFFFFF。它表示一个超时时间间隔,即表示永远等待,直到条件满足或者被中断。 /** * @ingroup los_base * @brief Align the value (addr) by some bytes (boundary). * * @par Description: * Align the beginning of the object with the base address, with boundary bytes being * the smallest unit of alignment. The ALIGN function is same with #LOS_Align function. * * @attention * * * @param addr [IN] Type #UINTPTR The address you want to align. * @param boundary [IN] Type #UINT32 The alignment size. * * @retval #UINTPTR The address which have been aligned. * @par Dependency: * * @see LOS_Align | TRUNCATE * @since Huawei LiteOS V100R001C00 */ #ifndef ALIGN//判断ALIGN是否已经被定义过,如果没有被定义过,则执行接下来的代码。 #define ALIGN(addr, boundary) LOS_Align(addr, boundary)//分别表示需要对齐的地址和对齐边界。在函数体内部,它调用了LOS_Align函数进行地址对齐操作,将addr地址向上对齐到最接近的boundary的倍数。 #endif /** * @ingroup los_base * @brief Align the value (addr) by some bytes (size). * * @par Description: * Align the tail of the object with the base address, with size bytes being the * smallest unit of alignment. * * @attention * * * @param addr [IN] Type #UINTPTR The address you want to align. * @param size [IN] Type #UINT32 The alignment size. * * @retval #UINTPTR The address which have been aligned. * @par Dependency: * * @see LOS_Align | ALIGN * @since Huawei LiteOS V100R001C00 */ #define TRUNCATE(addr, size) ((UINTPTR)(addr) & ~((size) - 1)) //宏接受两个参数 addr 和 size,返回一个截断后的地址。具体而言,该宏将地址 addr 按照 size 的大小进行对齐,并将低位多余的位置为零。例如,如果 addr 是 0x12345678,size 是 4,则截断后的地址是 0x12345670。 /** * Read a UINT8 value from addr and stroed in value. */ /*READ_UINT8(value, addr)、READ_UINT16(value, addr) 和 READ_UINT32(value, addr) 分别用于从地址 addr 中读取 8 位、16 位和 32 位的数值, 并将结果存储到变量 value 中。这几个宏的实现方式类似, 都是通过指针间接读取内存中的数值,并使用 dsb() 函数进行数据同步操作, 以确保读取的数据正确。其中,dsb() 函数是一个汇编指令, 用于进行数据同步操作,防止出现数据不一致的情况。*/ #define READ_UINT8(value, addr) ({ (value) = *((volatile UINT8 *)((UINTPTR)(addr))); dsb(); }) /** * Read a UINT16 value from addr and stroed in addr. */ #define READ_UINT16(value, addr) ({ (value) = *((volatile UINT16 *)((UINTPTR)(addr))); dsb(); }) /** * Read a UINT32 value from addr and stroed in value. */ #define READ_UINT32(value, addr) ({ (value) = *((volatile UINT32 *)((UINTPTR)(addr))); dsb(); }) //判断编译环境是否为 64 位。如果是 64 位环境,则定义了 READ_UINT64 和 WRITE_UINT64 宏。否则,这两个宏将被忽略。 //宏用于从地址 addr 中读取一个 64 位的整数值,并将结果存储到变量 value 中。这里使用了和之前类似的操作,通过指针间接读取内存中的值,并使用 dsb() 函数进行数据同步操作。 #ifdef __LP64__ /** * Read a UINT64 value from addr and stroed in value. */ #define READ_UINT64(value, addr) ({ (value) = *((volatile UINT64 *)((UINTPTR)(addr))); dsb(); }) #endif /*WRITE_UINT8(value, addr)、WRITE_UINT16(value, addr) 和 WRITE_UINT32(value, addr) 宏 分别用于将 8 位、16 位和 32 位的整数值 value 写入到地址 addr 中。 这些宏也使用了和之前类似的操作,使用 dsb() 函数进行数据同步操作, 并通过指针间接写入内存中的值。*/ /** * Write a UINT8 value to addr. */ #define WRITE_UINT8(value, addr) ({ dsb(); *((volatile UINT8 *)((UINTPTR)(addr))) = (value); }) /** * Write a UINT16 value to addr. */ #define WRITE_UINT16(value, addr) ({ dsb(); *((volatile UINT16 *)((UINTPTR)(addr))) = (value); }) /** * Write a UINT32 value to addr. */ #define WRITE_UINT32(value, addr) ({ dsb(); *((volatile UINT32 *)((UINTPTR)(addr))) = (value); }) //在 64 位环境下,还定义了 WRITE_UINT64 宏,用于将 64 位的整数值 value 写入到地址 addr 中。 #ifdef __LP64__ /** * Write a UINT64 addr to addr. */ #define WRITE_UINT64(value, addr) ({ dsb(); *((volatile UINT64 *)((UINTPTR)(addr))) = (value); }) #endif /** * Get a UINT8 value from addr. */ //宏用于从地址 addr 中读取一个 8 位的无符号整数值,并返回读取到的结果。在读取之后,使用 dsb() 函数进行数据同步操作,以确保读取的数据正确。 #define GET_UINT8(addr) ({ UINT8 r = *((volatile UINT8 *)((UINTPTR)(addr))); dsb(); r; }) /** * Get a UINT16 value from addr. */ //GET_UINT16(addr) 和 GET_UINT32(addr) 宏分别用于从地址 addr 中读取 16 位和 32 位的无符号整数值,并返回读取到的结果。同样地,在读取之后也进行数据同步操作。 #define GET_UINT16(addr) ({ UINT16 r = *((volatile UINT16 *)((UINTPTR)(addr))); dsb(); r; }) /** * Get a UINT32 value from addr. */ #define GET_UINT32(addr) ({ UINT32 r = *((volatile UINT32 *)((UINTPTR)(addr))); dsb(); r; }) //在 64 位环境下,还定义了 GET_UINT64(addr) 宏,用于从地址 addr 中读取一个 64 位的无符号整数值,并返回读取到的结果。 #ifdef __LP64__ /** * Get a UINT64 value from addr. */ #define GET_UINT64(addr) ({ UINT64 r = *((volatile UINT64 *)((UINTPTR)(addr))); dsb(); r; }) #endif /** * @ingroup los_base * @brief Assertion. * * @par Description: * When the program runs to the assertion position, the corresponding expression should * be true. If the expression is not true, the program stops running and gives an error * message. The function is same with #LOS_ASSERT_COND function. * * @attention * The function is effective only LOSCFG_DEBUG_VERSION is defined. * * @param judge [IN] The judgement expression of the assertion. * * @retval None. * @par Dependency: * * @see LOS_ASSERT_COND * @since Huawei LiteOS V100R001C00 */ #ifdef LOSCFG_DEBUG_VERSION//首先,通过条件编译指令 #ifdef LOSCFG_DEBUG_VERSION 来判断是否处于调试版本。如果定义了 LOSCFG_DEBUG_VERSION 宏,则表示处于调试版本,代码块 #ifdef 和 #endif 之间的内容将会生效;否则,代码块 #else 和 #endif 之间的内容将会生效。 #define LOS_ASSERT(judge) do { \ if ((UINTPTR)(judge) == 0) { \ (VOID)LOS_IntLock(); \ PRINT_ERR("ASSERT ERROR! %s, %d, %s\n", __FILE__, __LINE__, __FUNCTION__); \ while (1) {} \ } \ } while (0) //在调试版本下,宏定义的代码块中,LOS_ASSERT 宏被定义为一个带有参数 judge 的宏函数。它的作用是进行断言检查,如果 judge 表达式的结果为零(即假),则执行以上操作 //调用 LOS_IntLock() 函数,该函数可能是一个用于禁止中断的操作,以确保在断言失败时不会中断处理。 //使用 PRINT_ERR 打印一条错误信息,其中包含了出错的文件名、行号和函数名。 //进入一个无限循环 while (1),程序会一直停留在这个循环中。 #else #define LOS_ASSERT(judge)//在非调试版本下,宏定义的代码块中,LOS_ASSERT 宏被定义为空,即不进行任何操作。 #endif /** * @ingroup los_base * @brief Align the address (addr) by some bytes (boundary) you specify. * * @par Description: * This API is used to align the address (addr) by some bytes (boundary) you specify. * * @attention * * * @param addr [IN] Type #UINTPTR The address you want to align. * @param boundary [IN] Type #UINT32 The alignment size. * * @retval #UINTPTR The address which have been aligned. * @par Dependency: * * @see ALIGN | TRUNCATE * @since Huawei LiteOS V100R001C00 */ extern UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary); //具体而言,函数的功能是将 addr 按照 boundary 边界进行对齐,并返回对齐后的地址。例如,如果 addr 是 12,boundary 是 8,那么对齐后的地址就是 16。 //extern 关键字表示该函数是在其他地方定义的,这里只是对其进行声明。这样做的目的是在当前文件中使用该函数时能够正确引用它,而不需要提供函数的具体实现。 /** * @ingroup los_base * @brief Sleep the current task. * * @par Description: * This API is used to delay the execution of the current task. The task is able to be scheduled after it is delayed * for a specified milliseconds. * * @attention * * * @param msecs [IN] Type #UINT32 Milliseconds for which the task is delayed. * * @retval None * @par Dependency: * * @see LOS_Mdelay | LOS_TaskDelay * @since Huawei LiteOS V100R001C00 */ extern VOID LOS_Msleep(UINT32 msecs); #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ #endif /* __cplusplus */ #endif /* _LOS_BASE_H */