From a5ed7a0caafd1f6e1e2a7a1caf1e3b1fd03eaf54 Mon Sep 17 00:00:00 2001 From: tree <1913915946@qq.com> Date: Mon, 27 Nov 2023 19:54:03 +0800 Subject: [PATCH 1/4] 11.27 --- src/kernel/base/los_bitmap.c | 12 ++++--- src/kernel/base/los_err.c | 8 +++-- src/kernel/base/los_event.c | 34 ++++++++++--------- src/kernel/base/los_exc.c | 51 ++++++++++++++++------------- src/kernel/base/los_hwi.c | 61 +++++++++++++++++++++++------------ src/kernel/base/los_lockdep.c | 25 +++++++------- src/kernel/base/los_misc.c | 42 ++++++++++++------------ src/kernel/base/los_mp.c | 20 ++++++------ src/kernel/base/los_mux.c | 25 +++++++------- src/kernel/base/los_percpu.c | 2 +- src/kernel/base/los_printf.c | 14 ++++---- 11 files changed, 170 insertions(+), 124 deletions(-) diff --git a/src/kernel/base/los_bitmap.c b/src/kernel/base/los_bitmap.c index 84a056a..8ac0390 100644 --- a/src/kernel/base/los_bitmap.c +++ b/src/kernel/base/los_bitmap.c @@ -26,6 +26,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ +/*这是一个位图(bitmap)的实现,用于对位图进行设置、清除和获取最高/最低位的操作。 +该位图使用一个32位无符号整数(UINT32)来表示,每一位都代表一个标记 +函数通过位运算来实现对位图的操作,其中包括左移、按位与、按位或、按位取反等操作。*/ + #include "los_bitmap.h" #include "los_toolchain.h" @@ -36,7 +40,7 @@ extern "C" { #endif /* __cplusplus */ #define OS_BITMAP_MASK 0x1FU - +//LOS_BitmapSet:将指定位置的位设置为1 VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos) { if (bitmap == NULL) { @@ -45,7 +49,7 @@ VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos) *bitmap |= 1U << (pos & OS_BITMAP_MASK); } - +//LOS_BitmapClr:将指定位置的位清除为0 VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos) { if (bitmap == NULL) { @@ -54,7 +58,7 @@ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos) *bitmap &= ~(1U << (pos & OS_BITMAP_MASK)); } - +//LOS_HighBitGet:获取位图中最高位(值为1的位置)的索引 UINT16 LOS_HighBitGet(UINT32 bitmap) { if (bitmap == 0) { @@ -63,7 +67,7 @@ UINT16 LOS_HighBitGet(UINT32 bitmap) return (OS_BITMAP_MASK - CLZ(bitmap)); } - +//LOS_LowBitGet:获取位图中最低位(值为1的位置)的索引 UINT16 LOS_LowBitGet(UINT32 bitmap) { if (bitmap == 0) { diff --git a/src/kernel/base/los_err.c b/src/kernel/base/los_err.c index 970015d..abcc40a 100644 --- a/src/kernel/base/los_err.c +++ b/src/kernel/base/los_err.c @@ -25,7 +25,8 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*这段代码是关于错误处理的相关功能,包括注册错误处理函数和执行错误处理的函数。 +通过以下接口,用户可以自定义错误处理函数,并在发生错误时进行相应的处理操作。这样可以增强系统的健壮性和容错性,更好地应对各种错误情况。*/ #include "los_err.h" #ifdef __cplusplus @@ -35,8 +36,9 @@ extern "C" { #endif /* __cplusplus */ /* Hook function for error handling. */ +//g_usrErrFunc:全局变量,用于保存用户注册的错误处理函数 LITE_OS_SEC_BSS LOS_ERRORHANDLE_FUNC g_usrErrFunc; - +//LOS_ErrHandle:用于执行错误处理的函数,当系统出现错误时会调用该函数来处理错误信息 LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo, UINT32 paraLen, VOID *para) { @@ -46,7 +48,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 return LOS_OK; } - +//LOS_RegErrHandle:用于注册错误处理函数的接口,用户可以通过该函数注册自定义的错误处理函数 LITE_OS_SEC_TEXT_INIT VOID LOS_RegErrHandle(LOS_ERRORHANDLE_FUNC func) { g_usrErrFunc = func; diff --git a/src/kernel/base/los_event.c b/src/kernel/base/los_event.c index b2fe8cb..3caadc8 100644 --- a/src/kernel/base/los_event.c +++ b/src/kernel/base/los_event.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*这段代码是关于事件管理的实现,包括事件的初始化、读取、写入、清除等操作。*/ #include "los_event_pri.h" #include "los_task_pri.h" #include "los_spinlock.h" @@ -38,7 +38,7 @@ extern "C" { #endif #endif /* __cplusplus */ - +//LOS_EventInit()函数用于初始化事件控制块(eventCB),并将事件ID、事件列表等属性设置为初始值 LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) { UINT32 intSave; @@ -55,7 +55,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) LOS_IntRestore(intSave); return LOS_OK; } - +//OsEventParamCheck()函数用于检查参数的有效性,包括事件掩码(eventMask)、模式(mode)等 LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode) { if (ptr == NULL) { @@ -75,16 +75,17 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMa !(mode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) { return LOS_ERRNO_EVENT_FLAGS_INVALID; } + //指针非空,事件掩码非0,事件掩码不包含LOS_ERRTYPE_ERROR标志位,模式合法 return LOS_OK; } - +//OsEventPoll()函数用于轮询事件,根据指定的事件掩码和模式判断是否满足条件 LITE_OS_SEC_TEXT STATIC UINT32 OsEventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode) { UINT32 ret = 0; LOS_ASSERT(ArchIntLocked()); LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); - + if (mode & LOS_WAITMODE_OR) { if ((*eventId & eventMask) != 0) { ret = *eventId & eventMask; @@ -101,7 +102,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventPoll(UINT32 *eventId, UINT32 eventMask, UI return ret; } - +//OsEventReadCheck()函数用于检查事件读取操作的参数有效性,包括事件控制块(eventCB)、事件掩码(eventMask)、模式(mode)等 LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode) { UINT32 ret; @@ -122,7 +123,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT3 } return LOS_OK; } - +//OsEventReadImp()函数是事件读取的实现,根据指定的事件掩码和模式进行轮询,并根据超时时间和是否只读取一次进行相应的操作 LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout, BOOL once, UINT32 *intSave) { @@ -165,7 +166,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM } return ret; } - +//OsEventRead()函数是对外提供的事件读取接口,调用OsEventReadCheck()和OsEventReadImp()实现事件的读取操作 LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout, BOOL once) { @@ -184,7 +185,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask SCHEDULER_UNLOCK(intSave); return ret; } - +//OsEventWrite()函数用于向事件控制块中写入指定的事件 LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once) { LosTaskCB *resumedTask = NULL; @@ -230,7 +231,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, } return LOS_OK; } - +//LOS_EventPoll()函数是对外提供的事件轮询接口,调用OsEventParamCheck()和OsEventPoll()实现事件的轮询操作 LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode) { UINT32 ret; @@ -246,17 +247,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 SCHEDULER_UNLOCK(intSave); return ret; } - +//LOS_EventRead()函数是对外提供的事件读取接口,调用OsEventRead()实现事件的读取操作 LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) { return OsEventRead(eventCB, eventMask, mode, timeout, FALSE); } - +//LOS_EventWrite()函数是对外提供的事件写入接口,调用OsEventWrite()实现事件的写入操作 LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) { return OsEventWrite(eventCB, events, FALSE); } - +//LOS_EventDestroy()函数用于销毁事件控制块,将事件ID设置为0 LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) { UINT32 intSave; @@ -279,7 +280,7 @@ OUT: LOS_TRACE(EVENT_DELETE, (UINTPTR)eventCB, ret); return ret; } - +//LOS_EventClear()函数用于清除指定的事件 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events) { UINT32 intSave; @@ -296,18 +297,19 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events) return LOS_OK; } - +//OsEventWriteOnce()函数是事件写入的实现,与OsEventWrite()类似,但只写入一次 LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events) { return OsEventWrite(eventCB, events, TRUE); } #ifdef LOSCFG_COMPAT_POSIX +//OsEventReadOnce()函数是事件读取的实现,与OsEventRead()类似,但只读取一次 LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) { return OsEventRead(eventCB, eventMask, mode, timeout, TRUE); } - +// /OsEventReadWithCond()函数用于根据条件读取事件,只有当条件满足时才进行事件读取操作 LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) { diff --git a/src/kernel/base/los_exc.c b/src/kernel/base/los_exc.c index 71970f0..3ea59a0 100644 --- a/src/kernel/base/los_exc.c +++ b/src/kernel/base/los_exc.c @@ -25,7 +25,8 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*这是关于LiteOS中异常处理的代码,其中包括记录异常信息、异常信息保存和读取等功能。 +同时还包括了一些与异常相关的函数,如打印异常信息、任务回溯等*/ #include "los_exc.h" #include "los_printf_pri.h" #include "los_task_pri.h" @@ -48,7 +49,7 @@ extern "C" { #endif #endif /* __cplusplus */ - +//ExcInfoDumpFormat的结构体类型,包含了用于存储异常信息的缓冲区指针、偏移量、长度和存储地址等信息 #ifdef LOSCFG_SHELL_EXCINFO_DUMP typedef struct { CHAR *buf; /* pointer to the buffer for storing the exception information */ @@ -56,11 +57,13 @@ typedef struct { UINT32 len; /* the size of storing the exception information */ UINTPTR dumpAddr; /* the address of storing the exception information */ } ExcInfoDumpFormat; - +//全局变量g_excInfoPool,用于存储异常信息的缓冲区和相关的信息 STATIC ExcInfoDumpFormat g_excInfoPool = {0}; /* the hook of read-writing exception information */ STATIC __attribute__((section(".data"))) LogReadWriteFunc g_dumpHook = NULL; - +//LOS_ExcInfoRegHook:注册异常信息读写钩子函数,用于设置异常信息的存储地址、长度以及缓冲区等信息 +//"钩子函数"是指在特定事件发生时会被调用的函数 +//通过使用钩子函数,可以在异常发生时灵活地执行特定的操作,例如记录异常信息、进行特定的处理或通知其他模块进行相应的操作 VOID LOS_ExcInfoRegHook(UINTPTR startAddr, UINT32 len, CHAR *buf, LogReadWriteFunc hook) { if ((hook == NULL) || (buf == NULL)) { @@ -78,57 +81,57 @@ VOID LOS_ExcInfoRegHook(UINTPTR startAddr, UINT32 len, CHAR *buf, LogReadWriteFu g_excInfoPool.buf = buf; g_dumpHook = hook; } - +//OsSetExcInfoRW:设置异常信息读写钩子函数 VOID OsSetExcInfoRW(LogReadWriteFunc func) { g_dumpHook = func; } - +//OsGetExcInfoRW:获取异常信息读写钩子函数 LogReadWriteFunc OsGetExcInfoRW(VOID) { return g_dumpHook; } - +//OsSetExcInfoBuf:设置异常信息的缓冲区 VOID OsSetExcInfoBuf(CHAR *buf) { g_excInfoPool.buf = buf; } - +//OsGetExcInfoBuf:获取异常信息的缓冲区 CHAR *OsGetExcInfoBuf(VOID) { return g_excInfoPool.buf; } - +//OsSetExcInfoOffset:设置异常信息的偏移量 VOID OsSetExcInfoOffset(UINT32 Offset) { g_excInfoPool.offset = Offset; } - +//OsGetExcInfoOffset:获取异常信息的偏移量 UINT32 OsGetExcInfoOffset(VOID) { return g_excInfoPool.offset; } - +//OsSetExcInfoDumpAddr:设置异常信息的存储地址 VOID OsSetExcInfoDumpAddr(UINTPTR addr) { g_excInfoPool.dumpAddr = addr; } - +//OsGetExcInfoDumpAddr:获取异常信息的存储地址 UINTPTR OsGetExcInfoDumpAddr(VOID) { return g_excInfoPool.dumpAddr; } - +//OsSetExcInfoLen:设置异常信息的长度 VOID OsSetExcInfoLen(UINT32 len) { g_excInfoPool.len = len; } - +//OsGetExcInfoLen:获取异常信息的长度 UINT32 OsGetExcInfoLen(VOID) { return g_excInfoPool.len; } - +//WriteExcBufVa:将格式化的字符串写入异常信息缓冲区 VOID WriteExcBufVa(const CHAR *format, va_list arglist) { errno_t ret; @@ -143,7 +146,7 @@ VOID WriteExcBufVa(const CHAR *format, va_list arglist) g_excInfoPool.offset += ret; } } - +//WriteExcInfoToBuf:将格式化的字符串写入异常信息缓冲区 VOID WriteExcInfoToBuf(const CHAR *format, ...) { va_list arglist; @@ -152,7 +155,7 @@ VOID WriteExcInfoToBuf(const CHAR *format, ...) WriteExcBufVa(format, arglist); va_end(arglist); } - +//OsRecordExcInfoTime:记录异常信息的时间 VOID OsRecordExcInfoTime(VOID) { #define NOW_TIME_LENGTH 24 @@ -169,7 +172,7 @@ VOID OsRecordExcInfoTime(VOID) #undef NOW_TIME_LENGTH PrintExcInfo("%s \n", nowTime); } - +//OsShellCmdReadExcInfo:读取并打印异常信息的Shell命令 #ifdef LOSCFG_SHELL INT32 OsShellCmdReadExcInfo(INT32 argc, const CHAR **argv) { @@ -200,6 +203,9 @@ SHELLCMD_ENTRY(readExcInfo_shellcmd, CMD_TYPE_EX, "excInfo", 0, (CmdCallBackFunc #endif #ifdef LOSCFG_EXC_INTERACTION +//OsCheckExcInteractionTask:检查任务是否为异常交互任务 +//异常交互任务通常指的是用于处理异常情况的特殊任务或线程 +//当系统发生严重的错误或异常时,需要立即采取相应的措施来处理异常情况,这就需要使用异常交互任务来处理 UINT32 OsCheckExcInteractionTask(const TSK_INIT_PARAM_S *initParam) { if ((initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellTask) || @@ -209,7 +215,7 @@ UINT32 OsCheckExcInteractionTask(const TSK_INIT_PARAM_S *initParam) } return LOS_NOK; } - +//OsKeepExcInteractionTask:保留异常交互任务,删除其他任务 VOID OsKeepExcInteractionTask(VOID) { LosTaskCB *taskCB = NULL; @@ -243,7 +249,7 @@ VOID OsKeepExcInteractionTask(VOID) } #endif - +//LOS_Panic:打印异常信息并停止CPU执行 VOID LOS_Panic(const CHAR *fmt, ...) { va_list ap; @@ -252,7 +258,7 @@ VOID LOS_Panic(const CHAR *fmt, ...) va_end(ap); ArchHaltCpu(); } - +//LOS_BackTrace:打印当前任务的运行信息和回溯堆栈 VOID LOS_BackTrace(VOID) { #ifdef LOSCFG_BACKTRACE @@ -262,7 +268,7 @@ VOID LOS_BackTrace(VOID) ArchBackTrace(); #endif } - +//LOS_TaskBackTrace:打印指定任务的运行信息和回溯堆栈 VOID LOS_TaskBackTrace(UINT32 taskID) { #ifdef LOSCFG_BACKTRACE @@ -289,6 +295,7 @@ VOID LOS_TaskBackTrace(UINT32 taskID) #ifdef __GNUC__ /* stack protector */ +//__stack_chk_fail:用于栈保护机制,当发现栈被破坏时触发异常处理 VOID __stack_chk_fail(VOID) { /* __builtin_return_address is a builtin function, building in gcc */ diff --git a/src/kernel/base/los_hwi.c b/src/kernel/base/los_hwi.c index 0adc4f4..c620a44 100644 --- a/src/kernel/base/los_hwi.c +++ b/src/kernel/base/los_hwi.c @@ -25,7 +25,9 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/* +关于LiteOS中硬件中断处理的部分,涉及了中断的注册、删除、触发、使能、禁止等操作 +*/ #include "los_hwi_pri.h" #include "los_hwi.h" #include "los_memory.h" @@ -61,7 +63,7 @@ const HwiControllerOps *g_hwiOps = NULL; typedef VOID (*HWI_PROC_FUNC0)(VOID); typedef VOID (*HWI_PROC_FUNC2)(INT32, VOID *); - +//OsIrqNestingActive:用于在处理中断期间激活中断嵌套计数器,避免在处理时钟中断时进行抢占 STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum) { #ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION @@ -71,7 +73,7 @@ STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum) } #endif } - +//OsIrqNestingInactive:用于在处理中断结束后禁用中断嵌套计数器 STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum) { #ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION @@ -80,17 +82,17 @@ STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum) } #endif } - +//OsIrqNestingCntGet:获取当前CPU的中断嵌套计数值 size_t OsIrqNestingCntGet(VOID) { return g_intCount[ArchCurrCpuid()]; } - +//OsIrqNestingCntSet:设置当前CPU的中断嵌套计数值 VOID OsIrqNestingCntSet(size_t val) { g_intCount[ArchCurrCpuid()] = val; } - +//InterruptHandle:处理中断的实际函数,根据中断号调用对应的中断处理函数 STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm) { hwiForm->respCount++; @@ -114,7 +116,7 @@ STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm) } #endif } - +//OsIntHandle:中断处理入口函数,负责处理中断前的一些准备工作,如调用中断处理前的钩子函数等 VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm) { size_t *intCnt = NULL; @@ -148,7 +150,7 @@ VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm) OsCpupIrqEnd(hwiNum); #endif } - +//OsIntEntry:中断向量入口函数,根据中断号调用对应的中断处理函数 VOID OsIntEntry(VOID) { if ((g_hwiOps != NULL) && (g_hwiOps->handleIrq != NULL)) { @@ -156,7 +158,7 @@ VOID OsIntEntry(VOID) } return; } - +//OsHwiCpIrqParam:根据传入的中断参数结构体分配内存,并将参数信息拷贝到新分配的内存中 STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam) { HWI_IRQ_PARAM_S *paramByAlloc = NULL; @@ -169,6 +171,7 @@ STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam) return (HWI_ARG_T)paramByAlloc; } #ifndef LOSCFG_SHARED_IRQ +//OsHwiDel:删除指定的中断处理函数 STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId) { UINT32 intSave; @@ -190,7 +193,7 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam, HWI_UNLOCK(intSave); return LOS_OK; } - +//OsHwiCreate:创建中断处理函数,并将其添加到中断处理链表中 STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler, const HWI_IRQ_PARAM_S *irqParam) { @@ -218,6 +221,7 @@ STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_F return LOS_OK; } #else /* LOSCFG_SHARED_IRQ */ +//函数OsFreeHwiNode:用于释放中断处理函数节点,并在需要时禁止该中断 STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm, UINT32 irqId) { UINT32 ret = LOS_OK; @@ -240,7 +244,8 @@ STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm, return ret; } - +//OsHwiDel:用于删除硬件中断处理函数,它首先判断中断是否是共享中断 +//如果不是,则直接释放该中断的处理函数节点;如果是共享中断,则遍历链表找到对应的设备ID,然后释放该中断的处理函数节点 STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId) { HwiHandleInfo *hwiFormPrev = NULL; @@ -290,7 +295,8 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UIN HWI_UNLOCK(intSave); return ret; } - +//OsHwiCreate:用于创建硬件中断处理函数,它首先判断中断是否是共享中断,并检查是否已经存在具有相同设备ID的中断处理函数节点,如果存在则返回错误 +//然后申请内存并初始化新的中断处理函数节点,将其添加到链表中 STATIC UINT32 OsHwiCreate(HwiHandleInfo *head, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler, const HWI_IRQ_PARAM_S *irqParam) { @@ -359,7 +365,9 @@ size_t IntActive() LOS_IntRestore(intSave); return intCount; } - +//LOS_HwiCreate 函数:用于创建硬件中断处理函数 +//它会注册一个中断处理函数,并将其与指定的硬件中断号相关联 +//可以设置中断的优先级、硬件中断模式和处理函数 LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, HWI_PRIOR_T hwiPrio, HWI_MODE_T hwiMode, @@ -396,7 +404,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, } return ret; } - +//LOS_HwiDelete 函数:用于删除已经创建的硬件中断处理函数 +//通过指定硬件中断号,可以将之前注册的中断处理函数从系统中删除 LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam) { UINT32 ret; @@ -417,7 +426,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqP return ret; } - +//LOS_HwiTrigger 函数:用于手动触发指定的硬件中断 +//调用该函数后,会立即触发对应的硬件中断,使得系统执行相应的中断处理函数 LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum) { if ((g_hwiOps == NULL) || (g_hwiOps->triggerIrq == NULL)) { @@ -427,7 +437,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum) return g_hwiOps->triggerIrq(hwiNum); } - +//LOS_HwiEnable 函数:用于使能指定的硬件中断 +//调用该函数后,系统将允许对应的硬件中断产生,并执行相应的中断处理函数 LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum) { if ((g_hwiOps == NULL) || (g_hwiOps->enableIrq == NULL)) { @@ -437,7 +448,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum) return g_hwiOps->enableIrq(hwiNum); } - +//LOS_HwiDisable 函数:用于禁止指定的硬件中断 +//调用该函数后,系统将阻止对应的硬件中断产生,屏蔽其影响 LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum) { if ((g_hwiOps == NULL) || (g_hwiOps->disableIrq == NULL)) { @@ -447,7 +459,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum) return g_hwiOps->disableIrq(hwiNum); } - +//LOS_HwiClear 函数:用于清除指定的硬件中断 +//在某些平台上,硬件中断发生后可能需要手动清除中断标志位,以便正确处理后续的中断 LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum) { if ((g_hwiOps == NULL) || (g_hwiOps->clearIrq == NULL)) { @@ -457,7 +470,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum) return g_hwiOps->clearIrq(hwiNum); } - +//LOS_HwiSetPriority 函数:用于设置硬件中断的优先级 +//通过指定硬件中断号和优先级,可以调整硬件中断的触发顺序 LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority) { if ((g_hwiOps == NULL) || (g_hwiOps->setIrqPriority == NULL)) { @@ -468,6 +482,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T prio return g_hwiOps->setIrqPriority(hwiNum, priority); } #ifdef LOSCFG_KERNEL_SMP +//LOS_HwiSetAffinity函数:用于设置硬件中断的处理CPU亲和性 +//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来设置中断的处理CPU亲和性 LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask) { if ((g_hwiOps == NULL) || (g_hwiOps->setIrqCpuAffinity == NULL)) { @@ -477,7 +493,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask) return g_hwiOps->setIrqCpuAffinity(hwiNum, cpuMask); } - +//LOS_HwiSendIpi函数:用于发送硬件中断处理请求给指定的CPU +//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来发送中断处理请求 LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask) { if ((g_hwiOps == NULL) || (g_hwiOps->sendIpi == NULL)) { @@ -490,6 +507,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask) #endif #ifdef LOSCFG_KERNEL_LOWPOWER +//LOS_IntWakeupHookReg函数:用于注册中断唤醒回调函数 +//它将传入的回调函数赋值给全局变量g_intWakeupHook,以便在中断唤醒时调用该回调函数 LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook) { g_intWakeupHook = hook; @@ -497,6 +516,8 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook) #endif /* Initialization of the hardware interrupt */ +//OsHwiInit函数:用于初始化硬件中断 +//它会调用具体的平台相关函数来进行硬件中断的初始化操作 LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID) { ArchIrqInit(); diff --git a/src/kernel/base/los_lockdep.c b/src/kernel/base/los_lockdep.c index 7c65cf1..b4826f0 100644 --- a/src/kernel/base/los_lockdep.c +++ b/src/kernel/base/los_lockdep.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*这段代码是关于锁依赖检查的实现。包含了一些头文件和函数的定义,用于在多核系统中检测锁的使用情况*/ #include "los_base.h" #include "los_spinlock.h" #include "los_task_pri.h" @@ -47,6 +47,8 @@ extern "C" { STATIC Atomic g_lockdepAvailable = 1; /* atomic insurance for lockdep check */ +//OsLockDepRequire:该函数用于获取锁依赖检查的原子操作,确保在进行锁依赖检查时不会被中断 +//原子操作是指在计算机科学中,不会被中断的操作 STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave) { *intSave = LOS_IntLock(); @@ -54,13 +56,13 @@ STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave) /* busy waiting */ } } - +//OsLockDepRelease:释放锁依赖检查的原子操作,用于在完成锁依赖检查后恢复正常的中断状态 STATIC INLINE VOID OsLockDepRelease(UINT32 intSave) { LOS_AtomicSet(&g_lockdepAvailable, 1); LOS_IntRestore(intSave); } - +//OsLockDepGetCycles:获取当前 CPU 的周期计数器的值,用于记录锁请求和释放时的时间戳 STATIC INLINE UINT64 OsLockDepGetCycles(VOID) { UINT32 high, low; @@ -69,7 +71,7 @@ STATIC INLINE UINT64 OsLockDepGetCycles(VOID) /* combine cycleHi and cycleLo into 8 bytes cycles */ return (((UINT64)high << 32) + low); } - +//OsLockDepErrorStringGet:根据错误类型返回对应的错误字符串,用于打印错误信息 STATIC INLINE CHAR *OsLockDepErrorStringGet(enum LockDepErrType type) { CHAR *errorString = NULL; @@ -94,7 +96,7 @@ STATIC INLINE CHAR *OsLockDepErrorStringGet(enum LockDepErrType type) return errorString; } - +//OsLockDepPanic:当发生严重错误时触发系统的崩溃,通常在检测到死锁等无法修复的情况下调用 WEAK VOID OsLockDepPanic(enum LockDepErrType errType) { /* halt here */ @@ -103,7 +105,7 @@ WEAK VOID OsLockDepPanic(enum LockDepErrType errType) OsBackTrace(); while (1) {} } - +//OsLockDepDumpLock:输出锁依赖检查失败时的调试信息,包括任务名、任务 ID、CPU 号等,并最终触发崩溃 STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock, const VOID *requestAddr, enum LockDepErrType errType) { @@ -143,7 +145,7 @@ STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock, OsLockDepPanic(errType); } - +//OsLockDepCheckDependancy:检查当前任务与锁的所有者之间是否存在依赖关系,以避免死锁 STATIC BOOL OsLockDepCheckDependancy(const LosTaskCB *current, const LosTaskCB *lockOwner) { BOOL checkResult = TRUE; @@ -164,7 +166,7 @@ STATIC BOOL OsLockDepCheckDependancy(const LosTaskCB *current, const LosTaskCB * return checkResult; } - +//OsLockDepCheckIn:在请求锁时进行依赖检查,记录锁的请求地址和等待时间,如检查失败则触发崩溃 VOID OsLockDepCheckIn(const SPIN_LOCK_S *lock) { UINT32 intSave; @@ -217,7 +219,7 @@ OUT: OsLockDepRelease(intSave); } - +//OsLockDepRecord:记录成功获取锁的时间戳和持有者信息,并更新锁的所有者和 CPU 号等信息 VOID OsLockDepRecord(SPIN_LOCK_S *lock) { UINT32 intSave; @@ -250,7 +252,7 @@ VOID OsLockDepRecord(SPIN_LOCK_S *lock) OsLockDepRelease(intSave); } - +//OsLockDepCheckOut:在释放锁时进行依赖检查,记录持有时间并清除相关信息,如检查失败则触发崩溃 VOID OsLockDepCheckOut(SPIN_LOCK_S *lock) { UINT32 intSave; @@ -302,7 +304,8 @@ VOID OsLockDepCheckOut(SPIN_LOCK_S *lock) OUT: OsLockDepRelease(intSave); } - +//OsLockdepClearSpinlocks:清除当前任务持有的所有自旋锁,通常在系统处于异常状态下调用以确保解锁 +//自旋锁是一种用于多线程同步的机制。在使用自旋锁时,线程会反复检查锁是否被释放,如果锁已经被占用,线程就会一直循环等待,直到锁被释放为止 VOID OsLockdepClearSpinlocks(VOID) { LosTaskCB *task = OsCurrTaskGet(); diff --git a/src/kernel/base/los_misc.c b/src/kernel/base/los_misc.c index 3cbe7fc..6e495c5 100644 --- a/src/kernel/base/los_misc.c +++ b/src/kernel/base/los_misc.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +//操作系统的基础函数 #include "los_task_pri.h" #include "los_misc_pri.h" #include "los_memory_pri.h" @@ -48,23 +48,23 @@ extern "C" { #endif /* __cplusplus */ #ifdef LOSCFG_LIB_CONFIGURABLE -LITE_OS_SEC_BSS UINT32 g_osSysClock; -LITE_OS_SEC_BSS UINT32 g_semLimit; -LITE_OS_SEC_BSS UINT32 g_muxLimit; -LITE_OS_SEC_BSS UINT32 g_queueLimit; - -LITE_OS_SEC_BSS UINT32 g_swtmrLimit; -LITE_OS_SEC_BSS UINT32 g_taskLimit; -LITE_OS_SEC_BSS UINT32 g_minusOneTickPerSecond; -LITE_OS_SEC_BSS UINT32 g_taskMinStkSize; -LITE_OS_SEC_BSS UINT32 g_taskIdleStkSize; -LITE_OS_SEC_BSS UINT32 g_taskSwtmrStkSize; -LITE_OS_SEC_BSS UINT32 g_taskDfltStkSize; -LITE_OS_SEC_BSS UINT32 g_timeSliceTimeOut; - -LITE_OS_SEC_DATA BOOL g_nxEnabled = FALSE; -LITE_OS_SEC_BSS UINTPTR g_dlNxHeapBase; -LITE_OS_SEC_BSS UINT32 g_dlNxHeapSize; +LITE_OS_SEC_BSS UINT32 g_osSysClock; //操作系统的系统时钟频率 +LITE_OS_SEC_BSS UINT32 g_semLimit; //信号量的最大数量限制 +LITE_OS_SEC_BSS UINT32 g_muxLimit; //互斥锁的最大数量限制 +LITE_OS_SEC_BSS UINT32 g_queueLimit; //队列最大数量限制 + +LITE_OS_SEC_BSS UINT32 g_swtmrLimit; //软件定时器的最大数量限制 +LITE_OS_SEC_BSS UINT32 g_taskLimit; //任务的最大数量限制 +LITE_OS_SEC_BSS UINT32 g_minusOneTickPerSecond; //每秒减去的滴答数,用于时间戳计算 +LITE_OS_SEC_BSS UINT32 g_taskMinStkSize;//任务的最小堆栈大小 +LITE_OS_SEC_BSS UINT32 g_taskIdleStkSize; //空闲任务的堆栈大小 +LITE_OS_SEC_BSS UINT32 g_taskSwtmrStkSize; //软件定时器任务的堆栈大小 +LITE_OS_SEC_BSS UINT32 g_taskDfltStkSize; //默认任务的堆栈大小 +LITE_OS_SEC_BSS UINT32 g_timeSliceTimeOut; //时间片的超时时间 + +LITE_OS_SEC_DATA BOOL g_nxEnabled = FALSE; //是否启用了内存保护机制 +LITE_OS_SEC_BSS UINTPTR g_dlNxHeapBase; //动态加载库的内存堆起始地址 +LITE_OS_SEC_BSS UINT32 g_dlNxHeapSize; //动态加载库的内存堆大小 #endif #ifdef LOSCFG_KERNEL_TRACE @@ -77,11 +77,12 @@ LMS_INIT_HOOK g_lmsMemInitHook = NULL; LMS_FUNC_HOOK g_lmsMallocHook = NULL; LMS_FUNC_HOOK g_lmsFreeHook = NULL; #endif +//LOS_Align:用于将给定的地址按指定的边界对齐,返回对齐后的地址 LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary) { return (addr + boundary - 1) & ~((UINTPTR)(boundary - 1)); } - +//OsDumpMemByte:用于以字节为单位打印内存中的数据 LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs) { UINT32 interval; @@ -97,7 +98,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs) (VOID)LOS_TaskDelay(interval); } - +//OsDumpMemByte:用于以字节为单位打印内存中的数据 VOID OsDumpMemByte(size_t length, UINTPTR addr) { size_t dataLen; @@ -141,6 +142,7 @@ VOID OsDumpMemByte(size_t length, UINTPTR addr) } #if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_DEBUG_MUTEX) || defined(LOSCFG_DEBUG_QUEUE) +//OsArraySort:快速排序 VOID OsArraySort(UINT32 *sortArray, UINT32 start, UINT32 end, const SortParam *sortParam, OsCompareFunc compareFunc) { diff --git a/src/kernel/base/los_mp.c b/src/kernel/base/los_mp.c index d176a17..ba29cd8 100644 --- a/src/kernel/base/los_mp.c +++ b/src/kernel/base/los_mp.c @@ -25,7 +25,8 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*针对多处理器(SMP)系统的操作系统内核部分的实现 +主要包括了多处理器调度、任务管理和中断处理等功能*/ #include "los_mp_pri.h" #include "los_task_pri.h" #include "los_percpu_pri.h" @@ -45,7 +46,7 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_mpCallSpin); #define MP_CALL_LOCK(state) LOS_SpinLockSave(&g_mpCallSpin, &(state)) #define MP_CALL_UNLOCK(state) LOS_SpinUnlockRestore(&g_mpCallSpin, (state)) #endif - +//LOS_MpSchedule:多处理器调度函数,用于向指定的处理器发送调度中断 VOID LOS_MpSchedule(UINT32 target) { UINT32 ret; @@ -57,12 +58,12 @@ VOID LOS_MpSchedule(UINT32 target) } return; } - +//OsMpWakeHandler:多处理器唤醒处理函数,目前为空实现,无特定操作 VOID OsMpWakeHandler(VOID) { /* generic wakeup ipi, do nothing */ } - +//OsMpScheduleHandler:多处理器调度处理函数,设置调度标志以触发调度器在中断结束时执行调度 VOID OsMpScheduleHandler(VOID) { /* @@ -71,7 +72,7 @@ VOID OsMpScheduleHandler(VOID) */ OsPercpuGet()->schedFlag = INT_PEND_RESCH; } - +//OsMpHaltHandler:多处理器停机处理函数,将当前处理器标记为已停机状态,并进入死循环 VOID OsMpHaltHandler(VOID) { (VOID)LOS_IntLock(); @@ -79,7 +80,7 @@ VOID OsMpHaltHandler(VOID) while (1) {} } - +//OsMpCollectTasks:多处理器任务回收函数,用于递归检查所有可用任务,并删除标记为需要销毁的任务 VOID OsMpCollectTasks(VOID) { LosTaskCB *taskCB = NULL; @@ -109,6 +110,7 @@ VOID OsMpCollectTasks(VOID) } #ifdef LOSCFG_KERNEL_SMP_CALL +//OsMpFuncCall:多处理器函数调用函数,用于向指定的处理器发送函数调用请求 VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) { UINT32 index; @@ -144,7 +146,7 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) } return; } - +//OsMpFuncCallHandler:多处理器函数调用处理函数,从本处理器的函数调用队列中取出并执行函数调用请求 VOID OsMpFuncCallHandler(VOID) { UINT32 intSave; @@ -166,7 +168,7 @@ VOID OsMpFuncCallHandler(VOID) } MP_CALL_UNLOCK(intSave); } - +//OsMpFuncCallInit:多处理器函数调用初始化函数,用于初始化每个核心的函数调用队列 VOID OsMpFuncCallInit(VOID) { UINT32 index; @@ -176,7 +178,7 @@ VOID OsMpFuncCallInit(VOID) } } #endif /* LOSCFG_KERNEL_SMP_CALL */ - +//OsMpInit:多处理器初始化函数,包括创建周期性软件定时器和初始化函数调用队列等 UINT32 OsMpInit(VOID) { UINT16 swtmrId; diff --git a/src/kernel/base/los_mux.c b/src/kernel/base/los_mux.c index 25dbacc..31bb6df 100644 --- a/src/kernel/base/los_mux.c +++ b/src/kernel/base/los_mux.c @@ -25,7 +25,8 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*代码实现了一个简单的互斥锁(Mutex),用于保护共享资源的访问 +互斥锁的主要功能是确保在同一时间只有一个线程可以访问被保护的代码块或共享资源,从而避免并发访问引发的数据竞争和不一致性*/ #include "los_mux_pri.h" #include "los_mux_debug_pri.h" #include "los_bitmap.h" @@ -49,6 +50,7 @@ LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedMuxList; * Description : Initializes the mutex * Return : LOS_OK on success, or error code on failure */ +//OsMuxInit:Mutex初始化函数,用于初始化Mutex数据结构并设置初始状态 LITE_OS_SEC_TEXT UINT32 OsMuxInit(VOID) { LosMuxCB *muxNode = NULL; @@ -74,7 +76,7 @@ LITE_OS_SEC_TEXT UINT32 OsMuxInit(VOID) } return LOS_OK; } - +//LOS_MuxCreate:创建Mutex函数,用于创建一个新的Mutex对象,并返回其句柄 LITE_OS_SEC_TEXT UINT32 LOS_MuxCreate(UINT32 *muxHandle) { UINT32 intSave; @@ -113,7 +115,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxCreate(UINT32 *muxHandle) ERR_HANDLER: OS_RETURN_ERROR_P2(errLine, errNo); } - +//LOS_MuxDelete:删除Mutex函数,用于删除指定的Mutex对象及其相关资源 LITE_OS_SEC_TEXT UINT32 LOS_MuxDelete(UINT32 muxHandle) { UINT32 intSave; @@ -154,7 +156,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxDelete(UINT32 muxHandle) ERR_HANDLER: OS_RETURN_ERROR_P2(errLine, errNo); } - +//OsMuxParaCheck 函数主要用于验证互斥量操作的参数是否有效,包括互斥量是否被正确创建和传入的句柄是否有效,以及当前是否处于中断上下文 LITE_OS_SEC_TEXT STATIC UINT32 OsMuxParaCheck(const LosMuxCB *muxCB, UINT32 muxHandle) { if ((muxCB->muxStat == LOS_UNUSED) || (muxCB->muxId != muxHandle)) { @@ -168,7 +170,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsMuxParaCheck(const LosMuxCB *muxCB, UINT32 muxH } return LOS_OK; } - +//OsMuxBitmapSet 函数用于在互斥量等待队列中设置任务的优先级位图,并根据需要调整任务的优先级,以确保任务在等待互斥量时能够正确反映其优先级关系 LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapSet(const LosTaskCB *runTask, const MuxBaseCB *muxPended) { if (muxPended->owner->priority > runTask->priority) { @@ -176,7 +178,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapSet(const LosTaskCB *runTask, const MuxB OsTaskPriModify(muxPended->owner, runTask->priority); } } - +//OsMuxBitmapRestore 函数用于恢复任务的优先级位图,并根据需要更新拥有者任务的优先级 LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapRestore(const LosTaskCB *runTask, LosTaskCB *owner) { UINT16 bitMapPri; @@ -244,7 +246,8 @@ LITE_OS_SEC_TEXT STATIC LOS_DL_LIST *OsMuxPendFindPos(const LosTaskCB *runTask, return node; } #endif - +//总体来说,OsMuxPostOp 函数用于处理 Mutex 的释放操作,包括唤醒等待任务、更新 Mutex 状态和持有者等 +//确保 Mutex 能够按照预期的方式被正确释放和传递给下一个任务 LITE_OS_SEC_TEXT UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UINT32 timeout, UINT32 *intSave) { @@ -270,7 +273,7 @@ LITE_OS_SEC_TEXT UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UI return ret; } - +//LOS_MuxPend:等待Mutex函数,用于尝试获取指定Mutex的访问权限。如果Mutex已被其他任务持有,则当前任务会被挂起,直到Mutex可用 LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout) { UINT32 ret; @@ -332,7 +335,7 @@ OUT_UNLOCK: } return ret; } - +//OsMuxPostOpSub:通过比较当前任务和 Mutex 等待队列中的任务的优先级,来调整当前任务的优先级位图,并将 Mutex 持有者的优先级提升 LITE_OS_SEC_TEXT STATIC VOID OsMuxPostOpSub(LosTaskCB *runTask, MuxBaseCB *muxPosted) { LosTaskCB *pendedTask = NULL; @@ -350,7 +353,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsMuxPostOpSub(LosTaskCB *runTask, MuxBaseCB *muxPo LOS_BitmapClr(&runTask->priBitMap, bitMapPri); OsTaskPriModify(muxPosted->owner, bitMapPri); } - +// LITE_OS_SEC_TEXT UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted) { LosTaskCB *resumedTask = NULL; @@ -386,7 +389,7 @@ LITE_OS_SEC_TEXT UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted) return MUX_SCHEDULE; } - +//LOS_MuxPost:释放Mutex函数,用于释放当前任务对指定Mutex的访问权限,以便其他任务可以获取该Mutex LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 muxHandle) { UINT32 ret; diff --git a/src/kernel/base/los_percpu.c b/src/kernel/base/los_percpu.c index 7110c08..c7e0782 100644 --- a/src/kernel/base/los_percpu.c +++ b/src/kernel/base/los_percpu.c @@ -33,7 +33,7 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - +//定义全局变量数组,用于存储每个CPU核心的私有数据 Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; #ifdef __cplusplus diff --git a/src/kernel/base/los_printf.c b/src/kernel/base/los_printf.c index 6457a4d..7974cb3 100644 --- a/src/kernel/base/los_printf.c +++ b/src/kernel/base/los_printf.c @@ -32,7 +32,7 @@ * It should not add OS inner invocation, which is not allowed to be accessed in user space. * But it's allowed to invoke syscall interface. *---------------------------------------------------------------------------- */ - +/*这段代码是一个输出控制模块,根据不同的输出类型将字符串输出到不同的设备上*/ #ifdef LOSCFG_LIB_LIBC #include "unistd.h" #endif @@ -62,13 +62,13 @@ typedef enum { CONSOLE_OUTPUT = 2, EXC_OUTPUT = 3 } OutputType; - +//ErrorMsg:用于输出错误信息,当字符串输出非法或者vsnprintf_s函数失败时调用 STATIC VOID ErrorMsg(VOID) { const CHAR *p = "Output illegal string! vsnprintf_s failed!\n"; UartPuts(p, (UINT32)strlen(p), UART_WITH_LOCK); } - +//UartOutput:实际将字符串输出到串口的函数,根据配置可能会进行一些额外的处理 STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock) { #ifdef LOSCFG_SHELL_DMESG @@ -82,7 +82,7 @@ STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock) UartPuts(str, len, isLock); #endif } - +//OutputControl:根据输出类型选择相应的输出设备,并调用对应的输出函数 STATIC VOID OutputControl(const CHAR *str, UINT32 len, OutputType type) { switch (type) { @@ -105,14 +105,14 @@ STATIC VOID OutputControl(const CHAR *str, UINT32 len, OutputType type) } return; } - +//OsVprintfFree:释放动态分配的缓冲区内存 STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen) { if (bufLen != SIZEBUF) { (VOID)LOS_MemFree(m_aucSysMem0, buf); } } - +//OsVprintf:核心函数,根据给定的格式化字符串和可变参数,进行字符串格式化并输出到相应的设备 STATIC VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type) { INT32 len; @@ -156,7 +156,7 @@ STATIC VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type) OutputControl(bBuf, len, type); OsVprintfFree(bBuf, bufLen); } - +//UartVprintf、ConsoleVprintf、UartPrintf、dprintf、LkDprintf、DmesgPrintf、ExcPrintf、PrintExcInfo:这些函数都是对OsVprintf的封装,提供了不同的输出接口,在不同的场景下调用OsVprintf来完成字符串的格式化和输出 VOID UartVprintf(const CHAR *fmt, va_list ap) { OsVprintf(fmt, ap, UART_OUTPUT); From 4e5ee91f58e1cdca3fd6e256e1490b2a3c8cabf5 Mon Sep 17 00:00:00 2001 From: tree <1913915946@qq.com> Date: Mon, 27 Nov 2023 20:05:17 +0800 Subject: [PATCH 2/4] test --- src/kernel/base/los_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/base/los_queue.c b/src/kernel/base/los_queue.c index f6804c0..3b217ed 100644 --- a/src/kernel/base/los_queue.c +++ b/src/kernel/base/los_queue.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +//队列 #include "los_queue_pri.h" #include "los_queue_debug_pri.h" #include "los_task_pri.h" From cc2b0861fede0dffb70842cadac3f5f6926426ba Mon Sep 17 00:00:00 2001 From: tree <1913915946@qq.com> Date: Sun, 3 Dec 2023 23:46:09 +0800 Subject: [PATCH 3/4] 2 --- src/kernel/base/los_queue.c | 39 +++++++++++++++++++-------------- src/kernel/base/los_ringbuf.c | 19 ++++++++-------- src/kernel/base/los_sem.c | 23 ++++++++++--------- src/kernel/base/los_sortlink.c | 32 +++++++++++++-------------- src/kernel/base/los_stackinfo.c | 10 ++++----- src/kernel/base/los_swtmr.c | 25 +++++++++++++-------- src/kernel/base/los_tick.c | 23 +++++++++---------- 7 files changed, 95 insertions(+), 76 deletions(-) diff --git a/src/kernel/base/los_queue.c b/src/kernel/base/los_queue.c index 3b217ed..3a7e9a6 100644 --- a/src/kernel/base/los_queue.c +++ b/src/kernel/base/los_queue.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ -//队列 +//实现了一个基于轻量级操作系统的队列管理模块,提供了队列的创建、读写、删除以及信息获取等功能 #include "los_queue_pri.h" #include "los_queue_debug_pri.h" #include "los_task_pri.h" @@ -53,6 +53,7 @@ LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList; * Description : queue initial * Return : LOS_OK on success or error code on failure */ +//初始化队列,返回成功或失败错误码 LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) { LosQueueCB *queueNode = NULL; @@ -78,7 +79,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) } return LOS_OK; } - +//OsQueueCreateParameterCheck函数用于检查创建队列时传入的参数是否合法 STATIC INLINE UINT32 OsQueueCreateParameterCheck(UINT16 len, const UINT32 *queueId, UINT16 maxMsgSize) { if (queueId == NULL) { @@ -94,7 +95,7 @@ STATIC INLINE UINT32 OsQueueCreateParameterCheck(UINT16 len, const UINT32 *queue } return LOS_OK; } - +//OsQueueCreateInternal函数用于创建队列,包括在队列控制块中记录队列长度、消息大小等信息 LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsQueueCreateInternal(UINT16 len, UINT32 *queueId, UINT16 msgSize, UINT8 *queue, UINT8 queueMemType) { @@ -165,7 +166,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreateStatic(const CHAR *queueName, return OsQueueCreateInternal(len, queueId, msgSize, queueMem, OS_QUEUE_ALLOC_STATIC); } #endif - +//创建队列 LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(const CHAR *queueName, UINT16 len, UINT32 *queueId, UINT32 flags, UINT16 maxMsgSize) { @@ -198,7 +199,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(const CHAR *queueName, UINT16 len, return LOS_OK; } - +//OsQueueReadParameterCheck和OsQueueWriteParameterCheck分别用于检查读和写操作的参数合法性 LITE_OS_SEC_TEXT STATIC UINT32 OsQueueReadParameterCheck(UINT32 queueId, const VOID *bufferAddr, const UINT32 *bufferSize, UINT32 timeout) { @@ -248,7 +249,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsQueueWriteParameterCheck(UINT32 queueId, const } return LOS_OK; } - +//实现了队列的读取和写入操作,并对可能出现的错误进行了处理 STATIC UINT32 OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize) { UINT8 *queueNode = NULL; @@ -296,7 +297,7 @@ STATIC UINT32 OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID } return LOS_OK; } - +//用于处理队列操作函数 OsQueueBufferOperate 返回的错误码,使得在发生错误时能够打印相应的错误信息 STATIC VOID OsQueueBufferOperateErrProcess(UINT32 errorCode) { switch (errorCode) { @@ -336,7 +337,7 @@ STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueId } return LOS_OK; } - +//OsQueueOperate:实现了对队列的操作,包括参数检查、任务挂起与唤醒以及错误处理等功能 STATIC UINT32 OsQueueOperate(UINT32 queueId, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout) { LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueId); @@ -400,7 +401,7 @@ QUEUE_END: OsQueueBufferOperateErrProcess(errorCode); return ret; } - +//LOS_QueueReadCopy:从队列中读取数据,通过参数检查后调用OsQueueOperate函数进行实际的读取操作 LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueId, VOID *bufferAddr, UINT32 *bufferSize, @@ -417,7 +418,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueId, operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD); return OsQueueOperate(queueId, operateType, bufferAddr, bufferSize, timeout); } - +//LOS_QueueWriteHeadCopy:向队列的头部写入数据,通过参数检查后调用OsQueueOperate函数进行实际的写入操作 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, @@ -434,7 +435,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueId, operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD); return OsQueueOperate(queueId, operateType, bufferAddr, &bufferSize, timeout); } - +//LOS_QueueWriteCopy:向队列的尾部写入数据,通过参数检查后调用OsQueueOperate函数进行实际的写入操作 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, @@ -451,12 +452,12 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueId, operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL); return OsQueueOperate(queueId, operateType, bufferAddr, &bufferSize, timeout); } - +//LOS_QueueRead:从队列中读取数据的简化接口,直接调用LOS_QueueReadCopy函数 LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) { return LOS_QueueReadCopy(queueId, bufferAddr, &bufferSize, timeout); } - +//LOS_QueueWrite:向队列中写入数据的简化接口,先进行参数检查,然后调用LOS_QueueWriteCopy函数 LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) { if (bufferAddr == NULL) { @@ -465,7 +466,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize = sizeof(CHAR *); return LOS_QueueWriteCopy(queueId, &bufferAddr, bufferSize, timeout); } - +//LOS_QueueWriteHead:向队列头部写入数据的简化接口,先进行参数检查,然后调用LOS_QueueWriteHeadCopy函数 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, @@ -477,7 +478,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueId, bufferSize = sizeof(CHAR *); return LOS_QueueWriteHeadCopy(queueId, &bufferAddr, bufferSize, timeout); } - +//LOS_QueueDelete:删除队列的函数 +//首先检查队列是否存在,如果存在则检查是否有任务正在使用队列或者队列中还有未释放的内存块,如果满足条件则释放队列所占用的资源 LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueId) { LosQueueCB *queueCB = NULL; @@ -537,7 +539,7 @@ QUEUE_END: SCHEDULER_UNLOCK(intSave); return ret; } - +//LOS_QueueInfoGet:获取指定队列的相关信息,包括队列ID、队列长度、队列大小、队列头尾指针、等待读取和写入的任务数等 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueId, QUEUE_INFO_S *queueInfo) { UINT32 intSave; @@ -595,6 +597,9 @@ QUEUE_END: * : timeout --- Expiry time. The value range is [0,LOS_WAIT_FOREVER] * Return : pointer if success otherwise NULL */ +//OsQueueMailAlloc函数用来从邮件池中分配一个邮件内存块 +//如果没有可用的内存块,则根据超时时间挂起当前任务,并将其加入到等待内存块的任务链表中 +//当有内存块可用时,会将任务从任务链表中移除,并返回分配的内存块指针 LITE_OS_SEC_TEXT VOID *OsQueueMailAlloc(UINT32 queueId, VOID *mailPool, UINT32 timeout) { VOID *mem = NULL; @@ -663,6 +668,8 @@ END: * : mailMem --- The mail memory block address * Return : LOS_OK on success or error code on failure */ +//OsQueueMailFree函数用来释放指定的邮件内存块,并将其加入到邮件池的空闲链表中 +//如果有任务在等待内存块,则会从任务链表中唤醒一个任务,并将其从任务链表中移除 LITE_OS_SEC_TEXT UINT32 OsQueueMailFree(UINT32 queueId, VOID *mailPool, VOID *mailMem) { VOID *mem = NULL; diff --git a/src/kernel/base/los_ringbuf.c b/src/kernel/base/los_ringbuf.c index c33ea3f..524cea8 100644 --- a/src/kernel/base/los_ringbuf.c +++ b/src/kernel/base/los_ringbuf.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*实现环形缓冲区。环形缓冲区是一种循环使用固定大小存储空间的数据结构,常用于解决生产者-消费者问题*/ #include "los_ringbuf.h" #ifdef __cplusplus @@ -33,7 +33,7 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - +//LOS_RingbufUsedSize:获取环形缓冲区已使用的大小 UINT32 LOS_RingbufUsedSize(Ringbuf *ringbuf) { UINT32 size; @@ -56,6 +56,7 @@ UINT32 LOS_RingbufUsedSize(Ringbuf *ringbuf) * | * endIdx */ +//OsRingbufWriteLinear:线性写入数据到环形缓冲区 STATIC UINT32 OsRingbufWriteLinear(Ringbuf *ringbuf, const CHAR *buf, UINT32 size) { UINT32 cpSize; @@ -77,7 +78,7 @@ STATIC UINT32 OsRingbufWriteLinear(Ringbuf *ringbuf, const CHAR *buf, UINT32 siz return cpSize; } - +//OsRingbufWriteLoop:循环写入数据到环形缓冲区 STATIC UINT32 OsRingbufWriteLoop(Ringbuf *ringbuf, const CHAR *buf, UINT32 size) { UINT32 right, cpSize; @@ -105,7 +106,7 @@ STATIC UINT32 OsRingbufWriteLoop(Ringbuf *ringbuf, const CHAR *buf, UINT32 size) return cpSize; } - +//LOS_RingbufWrite:向环形缓冲区写入数据 UINT32 LOS_RingbufWrite(Ringbuf *ringbuf, const CHAR *buf, UINT32 size) { UINT32 cpSize = 0; @@ -130,7 +131,7 @@ EXIT: LOS_SpinUnlockRestore(&ringbuf->lock, intSave); return cpSize; } - +//OsRingbufReadLinear:线性读取环形缓冲区中的数据 STATIC UINT32 OsRingbufReadLinear(Ringbuf *ringbuf, CHAR *buf, UINT32 size) { UINT32 cpSize, remain; @@ -153,7 +154,7 @@ STATIC UINT32 OsRingbufReadLinear(Ringbuf *ringbuf, CHAR *buf, UINT32 size) return cpSize; } - +//OsRingbufReadLoop:循环读取环形缓冲区中的数据 STATIC UINT32 OsRingbufReadLoop(Ringbuf *ringbuf, CHAR *buf, UINT32 size) { UINT32 right, cpSize; @@ -179,7 +180,7 @@ STATIC UINT32 OsRingbufReadLoop(Ringbuf *ringbuf, CHAR *buf, UINT32 size) return cpSize; } - +//LOS_RingbufRead:从环形缓冲区读取数据 UINT32 LOS_RingbufRead(Ringbuf *ringbuf, CHAR *buf, UINT32 size) { UINT32 cpSize; @@ -205,7 +206,7 @@ EXIT: LOS_SpinUnlockRestore(&ringbuf->lock, intSave); return cpSize; } - +//LOS_RingbufInit:初始化环形缓冲区 UINT32 LOS_RingbufInit(Ringbuf *ringbuf, CHAR *fifo, UINT32 size) { if ((ringbuf == NULL) || (fifo == NULL) || @@ -221,7 +222,7 @@ UINT32 LOS_RingbufInit(Ringbuf *ringbuf, CHAR *fifo, UINT32 size) ringbuf->status = RBUF_INITED; return LOS_OK; } - +//LOS_RingbufReset:重置环形缓冲区 VOID LOS_RingbufReset(Ringbuf *ringbuf) { UINT32 intSave; diff --git a/src/kernel/base/los_sem.c b/src/kernel/base/los_sem.c index 8703827..867babf 100644 --- a/src/kernel/base/los_sem.c +++ b/src/kernel/base/los_sem.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*实现信号量的操作系统内核代码,主要包括信号量的创建、删除、等待(Pend)和释放(Post)等操作*/ #include "los_sem_pri.h" #include "los_sem_debug_pri.h" #include "los_err_pri.h" @@ -49,7 +49,7 @@ STATIC_INLINE VOID OsSemNodeRecycle(LosSemCB *semNode) semNode->semStat = LOS_UNUSED; LOS_ListTailInsert(&g_unusedSemList, &semNode->semList); } - +//OsSemInit()函数:用于初始化信号量管理模块,包括申请创建信号量所需要的内存空间、将信号量结构体加入到未使用链表中等 LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) { LosSemCB *semNode = NULL; @@ -74,7 +74,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) } return LOS_OK; } - +//OsSemCreate函数:用于创建一个信号量,并将其加入到已使用信号量列表中 +//参数count表示信号量的初始值,type表示信号量的类型(计数信号量或二进制信号量),semHandle用于返回创建的信号量的句柄 LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsSemCreate(UINT16 count, UINT8 type, UINT32 *semHandle) { UINT32 intSave; @@ -109,7 +110,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsSemCreate(UINT16 count, UINT8 type, UINT32 LOS_TRACE(SEM_CREATE, semCreated->semId, type, count); return LOS_OK; } - +//LOS_SemCreate:对外部提供的接口函数,用于创建一个计数信号量 LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle) { if (count > LOS_SEM_COUNT_MAX) { @@ -117,7 +118,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle) } return OsSemCreate(count, OS_SEM_COUNTING, semHandle); } - +//LOS_BinarySemCreate:对外部提供的接口函数,用于创建一个二进制信号量 LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle) { if (count > OS_SEM_BINARY_COUNT_MAX) { @@ -125,7 +126,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle } return OsSemCreate(count, OS_SEM_BINARY, semHandle); } - +//OsSemStateVerify:用于验证信号量的状态是否有效 +//参数semId表示要验证的信号量的ID,semNode是指向信号量控制块的指针 STATIC_INLINE UINT32 OsSemStateVerify(UINT32 semId, const LosSemCB *semNode) { #ifndef LOSCFG_RESOURCE_ID_NOT_USE_HIGH_BITS @@ -137,7 +139,8 @@ STATIC_INLINE UINT32 OsSemStateVerify(UINT32 semId, const LosSemCB *semNode) } return LOS_OK; } - +//OsSemGetCBWithCheck:用于根据信号量句柄获取信号量的控制块 +//参数semHandle表示信号量的句柄,semCB是一个指向指针的指针,用于返回获取到的信号量控制块 STATIC UINT32 OsSemGetCBWithCheck(UINT32 semHandle, LosSemCB **semCB) { if (GET_SEM_INDEX(semHandle) >= (UINT32)KERNEL_SEM_LIMIT) { @@ -147,7 +150,7 @@ STATIC UINT32 OsSemGetCBWithCheck(UINT32 semHandle, LosSemCB **semCB) *semCB = GET_SEM(semHandle); return LOS_OK; } - +//LOS_SemDelete:用于删除指定句柄的信号量,如果有任务正在等待该信号量,则删除失败 LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) { UINT32 intSave; @@ -184,7 +187,7 @@ OUT: LOS_TRACE(SEM_DELETE, semHandle, ret); return ret; } - +//LOS_SemPend:用于等待(Pend)一个信号量,如果信号量不可用,则阻塞当前任务直到信号量可用或超时。timeout表示超时时间 LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) { UINT32 intSave; @@ -252,7 +255,7 @@ OUT: SCHEDULER_UNLOCK(intSave); return ret; } - +//LOS_SemPost:用于释放(Post)一个信号量,使其变为可用状态,并唤醒等待该信号量的任务中的第一个任务 LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) { UINT32 intSave; diff --git a/src/kernel/base/los_sortlink.c b/src/kernel/base/los_sortlink.c index e39fdbc..e934398 100644 --- a/src/kernel/base/los_sortlink.c +++ b/src/kernel/base/los_sortlink.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*嵌入式操作系统中与任务调度相关的排序链表管理代码。包括了对排序链表的初始化、向排序链表中添加节点、从排序链表中删除节点、获取下一个超时时间等操作*/ #include "los_sortlink_pri.h" #include "los_memory.h" #include "los_exc.h" @@ -39,7 +39,7 @@ extern "C" { #define OS_INVALID_VALUE 0xFFFFFFFF #ifdef LOSCFG_BASE_CORE_USE_MULTI_LIST - +//OsSortLinkInit:初始化排序链表,为排序链表的头节点分配内存,并进行初始化 LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { UINT32 size; @@ -60,7 +60,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) } return LOS_OK; } - +//OsAdd2SortLink:将一个节点添加到排序链表中,根据节点的超时时间计算节点在排序链表中的位置,然后插入到相应位置 LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { SortLinkList *listSorted = NULL; @@ -106,7 +106,7 @@ LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, So LOS_ListTailInsert(&listSorted->sortLinkNode, &sortList->sortLinkNode); } } - +//OsCheckSortLink:检查排序链表是否合法,排除循环引用和无效节点 LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const LOS_DL_LIST *listNode) { LOS_DL_LIST *tmp = listNode->pstPrev; @@ -122,7 +122,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const /* delete invalid sortlink node */ OsBackTrace(); } - +//OsDeleteSortLink:从排序链表中删除一个节点,然后更新相邻节点的超时时间 LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { LOS_DL_LIST *listObject = NULL; @@ -141,7 +141,7 @@ LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, } LOS_ListDelete(&sortList->sortLinkNode); } - +//OsCalcExpierTime:根据当前的排序链表游标和节点的位置计算超时时间 LITE_OS_SEC_TEXT STATIC INLINE UINT32 OsCalcExpierTime(UINT32 rollNum, UINT32 sortIndex, UINT16 curSortIndex) { UINT32 expireTime; @@ -154,7 +154,7 @@ LITE_OS_SEC_TEXT STATIC INLINE UINT32 OsCalcExpierTime(UINT32 rollNum, UINT32 so expireTime = ((rollNum - 1) << OS_TSK_SORTLINK_LOGLEN) + sortIndex; return expireTime; } - +//OsSortLinkGetNextExpireTime:获取排序链表中下一个超时时间最小的节点的超时时间 LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) { UINT16 cursor; @@ -184,7 +184,7 @@ LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sor return expireTime; } - +//OsSortLinkUpdateExpireTime:更新排序链表中所有节点的超时时间,并更新游标 LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader) { SortLinkList *sortList = NULL; @@ -215,7 +215,7 @@ LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttr } sortLinkHeader->cursor = (sortLinkHeader->cursor + sleepTicks - 1) % OS_TSK_SORTLINK_LEN; } - +//OsSortLinkGetTargetExpireTime:获取目标节点的超时时间 LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader, const SortLinkList *targetSortList) { @@ -235,7 +235,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttrib } #else /* LOSCFG_BASE_CORE_USE_SINGLE_LIST */ - +//OsSortLinkInit:初始化排序链表头部 LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { UINT32 size; @@ -252,7 +252,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) LOS_ListInit(listObject); return LOS_OK; } - +//OsAdd2SortLink:向排序链表中添加元素 LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { SortLinkList *listSorted = NULL; @@ -286,7 +286,7 @@ LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, So LOS_ListTailInsert(&listSorted->sortLinkNode, &sortList->sortLinkNode); } } - +//OsCheckSortLink:检查排序链表的有效性,用于内部调用 LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const LOS_DL_LIST *listNode) { LOS_DL_LIST *tmp = listNode->pstPrev; @@ -302,7 +302,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const /* delete invalid sortlink node */ OsBackTrace(); } - +//OsDeleteSortLink:从排序链表中删除指定元素 LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { LOS_DL_LIST *listObject = NULL; @@ -319,7 +319,7 @@ LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, } LOS_ListDelete(&sortList->sortLinkNode); } - +//OsSortLinkGetNextExpireTime:获取排序链表中下一个到期的时间 LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) { UINT32 expireTime = OS_INVALID_VALUE; @@ -333,7 +333,7 @@ LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sor } return expireTime; } - +//OsSortLinkUpdateExpireTime:更新排序链表中到期时间 LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader) { SortLinkList *sortList = NULL; @@ -349,7 +349,7 @@ LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttr ROLLNUM_SUB(sortList->idxRollNum, sleepTicks - 1); } } - +//OsSortLinkGetTargetExpireTime:获取指定排序链表元素的到期时间 LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader, const SortLinkList *targetSortList) { diff --git a/src/kernel/base/los_stackinfo.c b/src/kernel/base/los_stackinfo.c index 9f90a6c..feb3da6 100644 --- a/src/kernel/base/los_stackinfo.c +++ b/src/kernel/base/los_stackinfo.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +//栈 #include "securec.h" #include "los_stackinfo_pri.h" #ifdef LOSCFG_SHELL @@ -35,7 +35,7 @@ const StackInfo *g_stackInfo = NULL; UINT32 g_stackNum; - +//OsStackWaterLineGet:获取栈的使用情况 UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed) { UINT32 size; @@ -53,20 +53,20 @@ UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, return LOS_NOK; } } - +//OsExcStackInfoReg:注册异常栈信息 VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum) { g_stackInfo = stackInfo; g_stackNum = stackNum; } - +//OsStackInit:初始化任务栈 VOID OsStackInit(VOID *stacktop, UINT32 stacksize) { /* initialize the task stack, write magic num to stack top */ (VOID)memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize); *((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD; } - +//OsGetStackInfo:获取栈信息 VOID OsGetStackInfo(const StackInfo **stackInfo, UINT32 *stackNum) { *stackInfo = g_stackInfo; diff --git a/src/kernel/base/los_swtmr.c b/src/kernel/base/los_swtmr.c index 052e6ff..393f3d7 100644 --- a/src/kernel/base/los_swtmr.c +++ b/src/kernel/base/los_swtmr.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*软件定时器的实现,涉及软件定时器的创建、启动、停止、删除等操作*/ #include "los_swtmr_pri.h" #include "los_sortlink_pri.h" #include "los_queue_pri.h" @@ -52,6 +52,7 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin); * Description: Start Software Timer * Input : swtmr --- Need to start software timer */ +//OsSwtmrStart:启动软件定时器 LITE_OS_SEC_TEXT VOID OsSwtmrStart(LosSwtmrCB *swtmr) { if ((swtmr->overrun == 0) && ((swtmr->mode == LOS_SWTMR_MODE_ONCE) || @@ -75,13 +76,14 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(LosSwtmrCB *swtmr) * Description: Delete Software Timer * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL. */ +//OsSwtmrDelete:删除软件定时器 STATIC INLINE VOID OsSwtmrDelete(LosSwtmrCB *swtmr) { /* insert to free list */ LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->sortList.sortLinkNode); swtmr->state = OS_SWTMR_STATUS_UNUSED; } - +//OsSwtmrUpdate:更新软件定时器 STATIC INLINE VOID OsSwtmrUpdate(LosSwtmrCB *swtmr) { if (swtmr->mode == LOS_SWTMR_MODE_ONCE) { @@ -101,6 +103,7 @@ STATIC INLINE VOID OsSwtmrUpdate(LosSwtmrCB *swtmr) } #ifndef LOSCFG_BASE_CORE_SWTMR_IN_ISR +//OsSwtmrTask:软件定时器任务处理函数,用于处理定时器超时事件 LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) { UINT32 ret, swtmrHandlerQueue; @@ -136,7 +139,7 @@ BOOL IsSwtmrTask(UINT32 taskId) return FALSE; } #endif - +//OsSwtmrTaskCreate:创建软件定时器任务 LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) { UINT32 ret, swtmrTaskId; @@ -161,7 +164,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) return ret; } #endif - +//OsSwtmrInit:软件定时器初始化 LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) { UINT32 size; @@ -209,6 +212,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) * Description: Tick interrupt interface module of software timer * Return : LOS_OK on success or error code on failure */ +//OsSwtmrScan:扫描软件定时器 LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) { SortLinkList *sortList = NULL; @@ -277,6 +281,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) * Description: Get next timeout * Return : Count of the Timer list */ +//OsSwtmrGetNextTimeout:获取下一个超时时间 LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) { return OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink); @@ -286,6 +291,7 @@ LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) * Description: Stop of Software Timer interface * Input : swtmr --- the software timer control handler */ +//OsSwtmrStop:停止软件定时器 LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(LosSwtmrCB *swtmr) { SortLinkAttribute *sortLinkHeader = NULL; @@ -309,6 +315,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(LosSwtmrCB *swtmr) * Description: Get next software timer expiretime * Input : swtmr --- the software timer control handler */ +//获取指定软件定时器的剩余时间 LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const LosSwtmrCB *swtmr) { SortLinkAttribute *sortLinkHeader = NULL; @@ -325,7 +332,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const LosSwtmrCB *swtmr) return OsSortLinkGetTargetExpireTime(sortLinkHeader, &swtmr->sortList); } - +//创建一个软件定时器 LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, @@ -377,7 +384,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, return LOS_OK; } - +//启动一个软件定时器 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrId) { LosSwtmrCB *swtmr = NULL; @@ -421,7 +428,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrId) LOS_TRACE(SWTMR_START, swtmr->timerId, swtmr->mode, swtmr->overrun, swtmr->interval, swtmr->expiry); return ret; } - +//停止一个软件定时器 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId) { LosSwtmrCB *swtmr = NULL; @@ -461,7 +468,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId) LOS_TRACE(SWTMR_STOP, swtmr->timerId); return ret; } - +//获取一个软件定时器的剩余时间 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrId, UINT32 *tick) { LosSwtmrCB *swtmr = NULL; @@ -502,7 +509,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrId, UINT32 *tick) SWTMR_UNLOCK(intSave); return ret; } - +//删除一个软件定时器 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrId) { LosSwtmrCB *swtmr = NULL; diff --git a/src/kernel/base/los_tick.c b/src/kernel/base/los_tick.c index c1d2db8..09c598b 100644 --- a/src/kernel/base/los_tick.c +++ b/src/kernel/base/los_tick.c @@ -25,7 +25,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +/*时钟模块:主要包括系统时钟的初始化、时钟中断处理函数、获取系统tick数等功能*/ #include "los_tick_pri.h" #include "los_swtmr_pri.h" #include "los_task_pri.h" @@ -52,6 +52,7 @@ STATIC WAKEUPFROMINTHOOK g_tickWakeupHook = NULL; /* * Description : Tick interruption handler */ +//OsTickHandler函数:时钟中断处理函数,用于处理时钟中断事件。 LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) { UINT32 intSave; @@ -76,7 +77,7 @@ LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) OsSwtmrScan(); #endif } - +//OsTickInit:初始化系统时钟 LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond) { if ((systemClock == 0) || @@ -88,12 +89,12 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond return LOS_OK; } - +//启动系统时钟 LITE_OS_SEC_TEXT_INIT VOID OsTickStart(VOID) { HalClockStart(); } - +//LOS_TickCountGet函数:获取系统tick数 LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID) { UINT32 intSave; @@ -109,12 +110,12 @@ LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID) return tick; } - +//LOS_CyclePerTickGet函数:获取每个tick所对应的CPU周期数 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID) { return g_sysClock / KERNEL_TICK_PER_SECOND; } - +//LOS_GetCpuCycle函数:获取CPU周期数 LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt) { UINT64 cycle; @@ -129,7 +130,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt) /* get the low 32 bits */ *lowCnt = (UINT32)(cycle & 0xFFFFFFFFULL); } - +//LOS_CurrNanosec函数:获取当前的纳秒数 LITE_OS_SEC_TEXT_MINOR UINT64 LOS_CurrNanosec(VOID) { UINT64 nanos; @@ -137,7 +138,7 @@ LITE_OS_SEC_TEXT_MINOR UINT64 LOS_CurrNanosec(VOID) nanos = HalClockGetCycles() * (OS_SYS_NS_PER_SECOND / OS_SYS_NS_PER_MS) / (g_sysClock / OS_SYS_NS_PER_MS); return nanos; } - +//LOS_MS2Tick函数:将毫秒转换为tick数 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec) { UINT64 delaySec; @@ -149,17 +150,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec) delaySec = (UINT64)millisec * KERNEL_TICK_PER_SECOND; return (UINT32)((delaySec + OS_SYS_MS_PER_SECOND - 1) / OS_SYS_MS_PER_SECOND); } - +//LOS_Tick2MS函数:将tick数转换为毫秒数 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick) { return (UINT32)(((UINT64)tick * OS_SYS_MS_PER_SECOND) / KERNEL_TICK_PER_SECOND); } - +//LOS_Udelay函数:微秒级延迟函数 LITE_OS_SEC_TEXT_MINOR VOID LOS_Udelay(UINT32 usecs) { HalDelayUs(usecs); } - +//LOS_Mdelay函数:毫秒级延迟函数 LITE_OS_SEC_TEXT_MINOR VOID LOS_Mdelay(UINT32 msecs) { UINT32 delayUs = (UINT32_MAX / OS_SYS_US_PER_MS) * OS_SYS_US_PER_MS; From 3e1c0beb7b72618478e67f78b2132acedc27bf3e Mon Sep 17 00:00:00 2001 From: tree <1913915946@qq.com> Date: Mon, 4 Dec 2023 20:05:08 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/用例_oujiashu.docx | Bin 0 -> 14253 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/用例_oujiashu.docx diff --git a/doc/用例_oujiashu.docx b/doc/用例_oujiashu.docx new file mode 100644 index 0000000000000000000000000000000000000000..80b0ece3233084e8e246b655c5949b1cb04eb7eb GIT binary patch literal 14253 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 literal 0 HcmV?d00001