diff --git a/fuaojia_branch.txt b/fuaojia_branch.txt new file mode 100644 index 0000000..e69de29 diff --git a/hjc/hjc.txt b/hjc/hjc.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/kernel/base/mem/bestfit_little/los_heap.c b/src/kernel/base/mem/bestfit_little/los_heap.c index 8bfa91c..3313db0 100644 --- a/src/kernel/base/mem/bestfit_little/los_heap.c +++ b/src/kernel/base/mem/bestfit_little/los_heap.c @@ -43,9 +43,9 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define HEAP_CAST(t, exp) ((t)(exp)) -#define HEAP_ALIGN sizeof(UINTPTR) -#define MALLOC_MAXSIZE (0xFFFFFFFF - HEAP_ALIGN + 1) +#define HEAP_CAST(t, exp) ((t)(exp))//这个宏定义是一个类型转换的快捷方式。它接受两个参数,t 表示目标类型,exp 是需要进行类型转换的表达式。这个宏最终会将 exp 转换为类型 t。 +#define HEAP_ALIGN sizeof(UINTPTR)//这个宏定义定义了 HEAP_ALIGN,它的值是 sizeof(UINTPTR)。sizeof 操作符用于返回其操作数的大小(以字节为单位),所以 HEAP_ALIGN 的值将取决于 UINTPTR 类型的大小。 +#define MALLOC_MAXSIZE (0xFFFFFFFF - HEAP_ALIGN + 1)//这个宏定义了 MALLOC_MAXSIZE,它的值是 0xFFFFFFFF - HEAP_ALIGN + 1。在这里,0xFFFFFFFF 表示一个32位无符号整数的最大值,HEAP_ALIGN 已经在上面定义过了。这个宏定义似乎是用来表示在分配内存时可能的最大尺寸。 /* * Description : look up the next memory node according to one memory node in the memory block list. @@ -53,13 +53,25 @@ extern "C" { * struct LosHeapNode *node --- Size of memory in bytes to allocate * Return : Pointer to next memory node */ + /*这个函数的作用是获取下一个堆节点的指针。具体实现过程如下: +如果当前节点已经是最后一个节点(即 node 等于堆管理器的尾节点),则返回 NULL。 +否则,计算出下一个节点的指针。根据结构体 LosHeapNode 的定义可知,每个节点都有一个 data 指针和一个 size 字段。为了得到下一个节点的指针,需要将当前节点的 data 指针加上当前节点的 size 字段。 +这个结果是一个地址,需要将其转换成 struct LosHeapNode* 类型的指针。可以通过先将地址转换为 UINTPTR 类型,再强制转换为 struct LosHeapNode* 来实现这一点。 +返回下一个节点的指针。*/ struct LosHeapNode* OsHeapPrvGetNext(struct LosHeapManager *heapMan, struct LosHeapNode *node) { return (heapMan->tail == node) ? NULL : (struct LosHeapNode *)(UINTPTR)(node->data + node->size); } #ifdef LOSCFG_MEM_TASK_STAT - +/*该函数接受两个参数:heapMan 表示堆管理器的指针,size 表示堆的初始大小。该函数的作用是初始化堆的统计信息, +即将 heapMan->stat 结构体清零, +并设置 heapMan->stat.memTotalUsed 和 heapMan->stat.memTotalPeak,表示内存使用情况的总量和峰值。 +具体实现过程如下: +首先调用 memset_s 函数将 heapMan->stat 清零,确保所有字段的值都为 0。 +接着,设置 heapMan->stat.memTotalUsed 的值为 sizeof(struct LosHeapNode) + sizeof(struct LosHeapManager),即堆管理器结构体和堆节点结构体的大小之和,这是堆使用的总 +将 heapMan->stat.memTotalPeak 的初始值也设为 heapMan->stat.memTotalUsed,表示在堆使用过程中的最高峰值。 +这段代码的前提条件是 LOSCFG_MEM_TASK_STAT 宏定义已经被定义,否则该函数不会被编译。*/ VOID OsHeapStatInit(struct LosHeapManager *heapMan, UINT32 size) { (VOID)memset_s(&heapMan->stat, sizeof(Memstat), 0, sizeof(Memstat)); @@ -67,7 +79,16 @@ VOID OsHeapStatInit(struct LosHeapManager *heapMan, UINT32 size) heapMan->stat.memTotalUsed = sizeof(struct LosHeapNode) + sizeof(struct LosHeapManager); heapMan->stat.memTotalPeak = heapMan->stat.memTotalUsed; } - +/*该函数的作用是向堆的统计信息中添加被使用的内存块。具体实现过程如下: +首先定义了两个变量 taskId 和 blockSize。taskId 用于记录当前任务的 ID,blockSize 表示要添加的内存块的大小, +包括堆节点结构体和节点存储的数据大小。 +然后,通过条件判断来确定 taskId 的值。如果当前任务不为空且处于非中断状态(OS_INT_INACTIVE), +则将 taskId 设置为当前任务的 ID(通过 LOS_CurTaskIDGet 函数获取)。否则,将 taskId 设置为 TASK_NUM - 1, +表示该内存块属于最后一个任务。 +将节点的 taskId 字段设置为 taskId,以便记录该内存块所属的任务。 +最后,调用 OS_MEM_ADD_USED 宏来更新堆的统计信息。该宏会将 blockSize 和 taskId 传递给堆管理器的 stat 结构体, +以便记录已使用内存的总量和各任务的内存使用情况。 +该函数的目的是在堆的统计信息中记录每个内存块的使用情况,以便进行内存管理和监控。*/ VOID OsHeapStatAddUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) { UINT32 taskId; @@ -87,7 +108,13 @@ VOID OsHeapStatAddUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) node->taskId = taskId; OS_MEM_ADD_USED(&heapMan->stat, blockSize, taskId); } - +/*该函数的作用是从堆的统计信息中减少被使用的内存块。具体实现过程如下: +首先定义了两个变量 taskId 和 blockSize。taskId 用于记录当前节点所属的任务 ID,该值在添加内存块时被设置; +blockSize 表示要减少的内存块的大小,包括堆节点结构体和节点存储的数据大小。 +调用 OS_MEM_REDUCE_USED 宏来更新堆的统计信息。该宏会将 blockSize 和 taskId 传递给堆管理器的 stat 结构体, +以便记录已使用内存的总量和各任务的内存使用情况。 +该函数的目的是在堆的统计信息中记录每个内存块的使用情况,以便进行内存管理和监控。和 OsHeapStatAddUsed 函数相反, +该函数的作用是将内存块从使用中状态转变为未使用状态。*/ VOID OsHeapStatDecUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) { UINT32 taskId = node->taskId; @@ -97,17 +124,25 @@ VOID OsHeapStatDecUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) } #else /* LOSCFG_MEM_TASK_STAT */ - +//函数用于初始化堆管理器的内存统计信息。它接受两个参数:heapMan 表示堆管理器的指针,size 表示堆的总大小。在这个备选实现中,该函数没有任何具体的实现操作,直接返回。 VOID OsHeapStatInit(struct LosHeapManager *heapMan, UINT32 size) { } - +//函数用于向堆的统计信息中添加被使用的内存块。它接受两个参数:heapMan 表示堆管理器的指针,node 表示要添加到统计信息中的堆节点指针。在这个备选实现中,该函数没有任何具体的实现操作,什么也不做。 VOID OsHeapStatAddUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) { } - +//函数用于从堆的统计信息中减少被使用的内存块。它接受两个参数:heapMan 表示堆管理器的指针,node 表示要从统计信息中减少使用的堆节点指针。在这个备选实现中,该函数没有任何具体的实现操作,什么也不做。 VOID OsHeapStatDecUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) { } #endif /* LOSCFG_MEM_TASK_STAT */ #ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK - +/*这段代码实现了一个堆完整性检查的函数 OsHeapIntegrityCheck,用于检查堆内存的完整性, +以确保堆管理器中的内存块没有被破坏或越界。让我逐步解释这段代码的功能: +首先,通过 (struct LosHeapNode *)(heap + 1) 的方式来获取第一个堆节点的地址,其中 heap 是指向堆管理器结构体的指针。 +然后,计算出堆的起始地址和结束地址,其中 heapStart 表示堆的起始地址,heapEnd 表示堆的结束地址。 +接下来进入循环,遍历堆中的每个节点。在循环内部,首先检查当前节点的地址是否位于堆的范围内,如果节点地址小于堆的起始地址或大于堆的结束地址, +则说明堆节点已经被破坏或越界,此时触发错误处理并返回 LOS_NOK 表示检查失败。 +如果当前节点的地址在合法范围内,则通过 OsHeapPrvGetNext 函数获取下一个节点的地址,继续进行下一轮的检查。 +当所有节点都通过合法性检查后,函数返回 LOS_OK 表示堆的完整性检查通过。 +总之,这段代码实现了对堆内存完整性的检查,避免了堆内存被破坏或越界,确保了堆管理器中的内存块的正确性。*/ UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap) { struct LosHeapNode *node = (struct LosHeapNode *)(heap + 1); @@ -127,7 +162,7 @@ UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap) } #else /* LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK */ - +//这段代码实现了一个名为 OsHeapIntegrityCheck 的函数,它接受一个指向 LosHeapManager 结构体的指针作为参数,并直接返回 LOS_OK。 UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap) { return LOS_OK; @@ -136,12 +171,16 @@ UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap) #endif /* LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK */ #ifdef LOSCFG_KERNEL_MEM_SLAB_EXTENTION - +/*接受一个指向内存池的指针 pool 和一个表示需要分配内存大小的参数 size。 +在函数内部,调用 OsHeapAlloc 函数将内存分配操作委托给堆内存管理器进行处理。 +最终将堆内存管理器返回的内存分配结果直接返回给调用者。*/ VOID *OsMemAlloc(VOID *pool, UINT32 size) { return OsHeapAlloc(pool, size); } - +/*接受一个指向内存池的指针 pool 和一个指向待释放内存块的指针 ptr。 +在函数内部,调用 OsHeapFree 函数将内存释放操作委托给堆内存管理器进行处理。 +检查堆内存管理器的释放操作是否成功,如果成功则返回 LOS_OK 表示释放成功,否则返回 LOS_NOK 表示释放失败。*/ UINT32 OsMemFree(VOID *pool, const VOID *ptr) { if (OsHeapFree(pool, ptr) == TRUE) { @@ -160,6 +199,19 @@ UINT32 OsMemFree(VOID *pool, const VOID *ptr) * UITN32 size --- size of the heap memory pool * Return : 1:success 0:error */ +/*这段代码实现了一个名为 OsHeapInit 的函数,用于初始化堆内存管理器。让我逐步解释这段代码的功能: +首先,函数接受一个指向内存池的指针 pool 和表示内存池大小的参数 size。 +接着,代码将 pool 指针强制类型转换为 struct LosHeapManager 类型的指针 heapMan,以便后续对堆管理器结构体成员的操作。 +然后,代码执行了一系列的条件检查: +检查 heapMan 是否为 NULL,或者内存池的大小是否小于等于堆管理器结构体和堆节点结构体所需的空间大小之和。 +如果满足其中任何一个条件,函数将返回 FALSE。 +如果条件检查通过,接下来的操作包括: +使用 memset_s 函数将整个内存池的内容初始化为 0。 +设置堆管理器结构体中的 size 成员为 size - sizeof(struct LosHeapManager)。 +将 head 和 tail 指针指向内存池中的起始位置,并初始化堆节点的相关属性,如 used、prev 和 size。 +调用 OsHeapStatInit 函数对堆内存管理器进行统计信息的初始化。 +最后,函数返回 TRUE 表示堆内存管理器初始化成功。 +总之,这段代码实现了对堆内存管理器的初始化操作,包括内存池的清零、设置管理器结构体的各个成员值,以及进行统计信息的初始化。这是堆内存分配器在启动阶段需要执行的关键操作,以确保后续的内存分配和释放能够正常进行。*/ BOOL OsHeapInit(VOID *pool, UINT32 size) { struct LosHeapNode *node = NULL; @@ -192,6 +244,33 @@ BOOL OsHeapInit(VOID *pool, UINT32 size) * UINT32 size --- size of the heap memory pool * Return : NULL:error, other value:the address of the memory we alloced */ +/*这段代码实现了一个名为 OsHeapAlloc 的函数,用于在堆内存管理器中分配指定大小的内存块。让我逐步解释这段代码的功能: + +首先,函数接受一个指向内存池的指针 pool 和表示要分配的内存块大小的参数 size。 + +接着,代码定义了一些局部变量,包括 node、next、best、ptr 和 alignSize,用于记录堆节点和其他临时数据。 + +heapMan 是将 pool 指针强制类型转换为 struct LosHeapManager 类型的指针,以便后续对堆管理器结构体成员的操作。 + +然后,代码执行了一系列的条件检查: + +检查 heapMan 是否为 NULL,或者要分配的内存块大小是否超过了最大允许的大小 MALLOC_MAXSIZE。如果满足其中任何一个条件,函数将返回 NULL。 +如果条件检查通过,接下来的操作包括: + +调用 OsHeapIntegrityCheck 函数对堆内存管理器进行完整性检查。如果检查失败(返回值不等于 LOS_OK),函数将返回 NULL。 +然后,代码从堆内存管理器的尾部开始遍历堆节点,寻找合适的空闲节点来分配内存块。具体过程如下: + +判断当前节点是否未被使用(node->used == 0)且大小足够容纳请求的对齐后的大小(node->size >= alignSize)。 +如果是,则更新 best 指针,选择找到的第一个合适的节点。 +如果找到的节点大小正好与请求的对齐后的大小相等(best->size == alignSize),跳转到 SIZE_MATCH 标签处。 +循环遍历完所有节点后,函数将根据找到的最佳节点进行不同的处理: + +如果找到了合适的节点(best != NULL),则继续下面的操作。 +如果找到的节点大小与对齐后的大小完全匹配(即跳转到 SIZE_MATCH 标签处),直接执行后续处理操作。 +否则,函数将在找到的节点上分割出一个大小为 alignSize 的内存块,并更新相关节点和管理器的属性值。 +最后,函数返回分配的内存块的起始地址 ptr。 + +总之,这段代码实现了在堆内存管理器中分配指定大小的内存块的功能。它会遍历堆节点,寻找满足条件的空闲节点,并根据需要进行内存分割,以满足对齐要求。如果分配失败或出现错误,函数将返回 NULL。*/ VOID *OsHeapAlloc(VOID *pool, UINT32 size) { struct LosHeapNode *node = NULL; @@ -222,11 +301,18 @@ VOID *OsHeapAlloc(VOID *pool, UINT32 size) } /* alloc failed */ + /*这是一个条件判断语句,如果找到的最佳节点为空(即没有足够大小的空闲节点),则执行花括号中的代码块。*/ if (best == NULL) { - PRINT_ERR("there's not enough mem to alloc 0x%x Bytes!\n", alignSize); - goto OUT; + PRINT_ERR("there's not enough mem to alloc 0x%x Bytes!\n", alignSize);//在没有足够空闲内存来分配请求大小的内存块时,打印错误信息,提示用户无法分配指定大小的内存。 + goto OUT;//跳转到标签 OUT 处,这通常是用于执行清理和释放资源的操作。 } - + /*这是另一个条件判断语句,用于判断是否有足够的空间将找到的节点分割为两部分,以满足请求的大小,并且保留一个足够大的空洞来放置下一个节点的元数据。*/ + /*node = (struct LosHeapNode*)(UINTPTR)(best->data + alignSize);:计算出新的节点的地址,该节点位于原节点的空闲空间之后,用于存放剩余的内存块。 +node->used = 0;:将新节点标记为未使用。 +node->size = best->size - alignSize - sizeof(struct LosHeapNode);:设置新节点的大小为原节点大小减去已分配内存大小和节点元数据大小的剩余空间。 +node->prev = best;:设置新节点的前驱节点为原节点。 +接下来的条件判断和操作用于更新堆管理器中的节点关系,确保堆的连续性。 +最后,best->size = alignSize;:更新原节点的大小为已分配大小,表示原节点存放了分配的内存块。*/ if ((best->size - alignSize) > sizeof(struct LosHeapNode)) { /* hole divide into 2 */ node = (struct LosHeapNode*)(UINTPTR)(best->data + alignSize); @@ -246,7 +332,11 @@ VOID *OsHeapAlloc(VOID *pool, UINT32 size) best->size = alignSize; } +/*这段代码可能是用于实现动态内存分配器的代码。具体来说,函数名称 SIZE_MATCH 可能代表了一种内存分配策略,即在进行内存分配时,选择最能够匹配请求大小的空闲内存块进行分配。 + +其中,代码中的 best 变量可能表示了符合请求大小的、最佳匹配的空闲内存块。代码将 best 的 align 属性设为 0,used 属性设为 1,表示该内存块已被使用。然后,代码通过指针 ptr 返回了该内存块的起始地址。最后,代码调用了 OsHeapStatAddUsed 函数,可能是用于统计内存分配情况的函数,将该内存块的使用信息记录到内存分配器的统计数据中。 +值得注意的是,代码中可能存在一些未给出的上下文信息,因此具体含义可能需要根据上下文和相关代码进行推断和理解。*/ SIZE_MATCH: best->align = 0; best->used = 1; @@ -264,6 +354,15 @@ OUT: * UINT32 boundary --- boundary the heap needs align * Return : NULL:error, other value:the address of the memory we alloced */ +/*这段代码是一个用于分配指定大小、指定对齐边界(alignment boundary)的内存块的函数。该函数的名称为 OsHeapAllocAlign。 + +代码首先进行了一些错误检查,确保传入的参数 pool 不为空、size 大于 0、boundary 大于等于 sizeof(VOID*)(VOID* 的大小,即指针大小),且 boundary 是对齐的。如果有任何一个条件不满足,则返回 NULL,表示内存分配失败。 + +接着,代码计算了需要分配的内存块的大小 useSize,并使用 OsHeapAlloc 函数在内存池 pool 中分配了 useSize 大小的内存块,并将其赋值给指针变量 ptr。 + +如果内存分配成功,则代码通过 OS_MEM_ALIGN 宏将 ptr 指针对齐到指定的边界 boundary。如果对齐后的指针地址与原始指针地址相同,则说明原始指针已经对齐,直接跳转到 OUT 标签处并返回 ptr 指针即可。否则,说明原始指针未对齐,需要在原始指针和对齐后的指针间填补一定的空隙(gap),并将 gap 的大小信息存储在对齐后的指针前 sizeof(UINTPTR) 个字节的位置。最后,代码返回对齐后的指针 alignedPtr。 + +需要注意的是,代码中可能存在一些未给出的宏定义和类型定义,具体含义可能需要根据上下文和相关代码进行推断和理解。*/ VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { UINT32 useSize; @@ -297,7 +396,15 @@ VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) OUT: return ptr; } +/*这段代码是一个用于释放内存的函数,名称为 OsHeapDoFree。该函数接收两个参数:一个是 LosHeapManager 结构体指针 heapMan,代表内存池管理器;另一个是 LosHeapNode 结构体指针 curNode,代表需要释放的内存块对应的内存池节点。 + +代码首先将 curNode 赋值给 node 变量,并将其 used 属性设为 0,表示该节点为未使用状态。 + +接着,代码使用 while 循环向前遍历链表,查找前面的空闲节点。具体来说,如果当前节点 node 的前一个节点存在且未被使用,则将 node 更新为前一个节点。这一步的目的是将 node 扩展到尽可能大的空闲区域。 +然后,代码使用 while 循环向后遍历链表,查找后面的空闲节点。具体来说,代码使用 OsHeapPrvGetNext 函数获取 node 的下一个节点 next,如果 next 存在且未被使用,则将 node 和 next 合并为一个新的节点,并更新 node 的 size 属性。如果合并后的节点是链表中的最后一个节点(也就是 heapMan->tail 指向该节点),则更新 heapMan->tail 为合并后的新节点。如果 next 不存在或已经被使用,则结束循环。 + +需要注意的是,代码中使用了 LosHeapManager 和 LosHeapNode 两个结构体,具体属性和方法的含义可能需要根据上下文和相关代码进行推断和理解。*/ STATIC VOID OsHeapDoFree(struct LosHeapManager *heapMan, struct LosHeapNode *curNode) { struct LosHeapNode *node = curNode; @@ -330,6 +437,15 @@ STATIC VOID OsHeapDoFree(struct LosHeapManager *heapMan, struct LosHeapNode *cur * VOID* ptr --- the pointer of heap memory we want to free * Return : 1:success 0:error */ +/*这段代码是用于释放指定内存块的函数 OsHeapFree。该函数接收两个参数:一个是 VOID 类型指针 pool,代表内存池;另一个是 const VOID 类型指针 ptr,代表需要释放的内存块的起始地址。 + +代码首先声明了一些变量和结构体指针,其中 node 是一个 LosHeapNode 结构体指针,用于表示需要释放的内存块对应的内存池节点。gapSize 是一个 UINT32 类型变量,用于记录内存块前面的空隙大小,ret 是一个 BOOL 类型变量,用于表示内存是否成功释放。 + +接着,代码通过将传入的 ptr 指针往前移动 sizeof(UINTPTR) 个字节,找到真正的内存块地址,并将其赋值给 ptr 变量。然后,代码判断 ptr 所指向的内存块地址是否在内存池的范围内,如果不在范围内,则返回 FALSE。 + +接下来,代码使用 ((struct LosHeapNode *)ptr) - 1 计算出内存块对应的内存池节点的地址,并将其赋值给 node 变量。然后,代码检查该节点是否已经被使用,以及它是否是链表中的一个节点。如果检查不通过,则将 ret 设置为 FALSE,并跳转到 OUT 标签处。 + +最后,代码调用 OsHeapStatDecUsed 函数将内存池管理器中 used 字段减一,然后调用 OsHeapDoFree 函数将 node 对应的内存块释放,并更新内存池管理器中的相关参数。最终返回 ret 表示操作是否成功。*/ BOOL OsHeapFree(VOID *pool, const VOID *ptr) { struct LosHeapNode *node = NULL; @@ -378,6 +494,19 @@ OUT: * Output : status --- heap statistics * Return : LOS_OK on success or error code on failure */ +/*这段代码是用于获取指定内存池的统计信息的函数 OsHeapStatisticsGet。该函数接收两个参数:一个是 VOID 类型指针 pool,代表内存池;另一个是 LosHeapStatus 结构体指针 status,用于保存内存池的统计信息。 + +函数中首先声明了一些变量,包括 heapUsed、maxFreeNodeSize、freeNodeNum、usedNodeNum 以及结构体指针 node 和 ramHeap。其中 heapUsed 表示已用内存大小,maxFreeNodeSize 表示最大可用内存块大小,freeNodeNum 表示空闲节点数量,usedNodeNum 表示已用节点数量。 + +然后,代码检查传入的内存池指针是否为空,如果为空,则返回 LOS_NOK。接着,代码检查传入的结构体指针 status 是否为空,如果为空,则返回 LOS_NOK。 + +之后,代码使用 sizeof(struct LosHeapManager) 计算出内存池管理器头部占用的空间大小,并将其加到 heapUsed 变量中。 + +接下来,代码使用指针 node 遍历整个内存池的节点链表,对每个节点进行处理。如果该节点已被使用,则将其大小和节点头部大小相加,并将结果累加到 heapUsed 中,并将 usedNodeNum 加一。否则,如果该节点未被使用,则更新 maxFreeNodeSize 和 freeNodeNum 的值。 + +最后,代码检查 heapUsed 是否超过了内存池总大小,如果超过,则返回 LOS_NOK。否则,将统计信息保存到结构体指针 status 中,并返回 LOS_OK。 + +需要注意的是,如果系统开启了 LOSCFG_MEM_TASK_STAT 宏定义,则代码还会更新 usageWaterLine 字段的值。*/ UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status) { UINT32 heapUsed = 0; @@ -435,6 +564,15 @@ UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status) * Input : pool --- Pointer to the manager, to distinguish heap * Return : max free block size */ +/*这段代码是用于获取指定内存池中最大可用块大小的函数 OsHeapGetMaxFreeBlkSize。该函数接收一个参数:一个 VOID 类型指针 pool,代表内存池。 + +函数中首先声明了一些变量,包括 size、temp、结构体指针 node 和 ramHeap。其中 size 表示最大可用块大小,temp 是一个临时变量,用于保存当前节点的大小。 + +然后,代码检查传入的内存池指针是否为空,如果为空,则返回 LOS_NOK。 + +之后,代码使用指针 node 遍历整个内存池的节点链表,对每个节点进行处理。如果该节点未被使用,则将其大小保存到 temp 变量中。如果 temp 的值比 size 大,则更新 size 的值为 temp。 + +最后,函数返回 size 变量的值,即内存池中最大可用块的大小。*/ UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool) { UINT32 size = 0; diff --git a/src/kernel/base/mem/bestfit_little/los_memory.c b/src/kernel/base/mem/bestfit_little/los_memory.c index cf9269d..53d9bd0 100644 --- a/src/kernel/base/mem/bestfit_little/los_memory.c +++ b/src/kernel/base/mem/bestfit_little/los_memory.c @@ -41,18 +41,40 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define POOL_ADDR_ALIGNSIZE 64 +#define POOL_ADDR_ALIGNSIZE 64//是一个宏,表示内存池地址对齐的大小,值为64。 -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memSpin); +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memSpin);//是一个修饰符,用于指定变量所属的段(section)为.bss.init,该变量在程序运行前会被初始化为0。 +//是一个宏,用于初始化自旋锁变量g_memSpin。 -UINT8 *m_aucSysMem0 = (UINT8 *)NULL; -UINT8 *m_aucSysMem1 = (UINT8 *)NULL; -__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end; +UINT8 *m_aucSysMem0 = (UINT8 *)NULL;//是一个指向UINT8类型的指针变量,初始值为NULL。 +UINT8 *m_aucSysMem1 = (UINT8 *)NULL;//是一个指向UINT8类型的指针变量,初始值为NULL。 +__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end;//是一个UINTPTR类型的变量,位于.data.init段,用于记录系统内存地址的末尾位置。 -#ifdef LOSCFG_EXC_INTERACTION -__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0; + +#ifdef LOSCFG_EXC_INTERACTION//表示如果定义了宏LOSCFG_EXC_INTERACTION,则编译以下代码块。 +__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0;//是一个UINTPTR类型的变量,位于.data.init段,用于记录异常交互内存的大小,初始值为0。 #endif + +/*这段代码是一个函数LOS_MemInit()的实现,用于初始化内存池。 + +LITE_OS_SEC_TEXT_INIT 是一个修饰符,用于指定函数所属的段(section)为.text.init,表示该函数在程序运行前会被初始化。 + +函数参数: + +pool 是一个指向内存池的指针,用于存储分配的内存块。 +size 是内存池的大小。 +函数内部逻辑: + +首先,函数会对传入的参数进行检查。如果pool为空指针或size小于等于sizeof(struct LosHeapManager)(一种内部结构的大小),则函数直接返回错误码LOS_NOK。 +接下来,函数会检查pool和size是否按照OS_MEM_ALIGN_SIZE(内存对齐大小)进行对齐。如果没有对齐,则打印警告信息,并将size调整为对齐后的大小。 +然后,函数会获取并保存当前的中断状态,以防止在初始化过程中发生中断。 +接着,函数调用OsMemMulPoolInit()初始化多内存池管理器,如果初始化失败,则跳转到OUT标签处。 +如果多内存池管理器初始化成功,函数继续调用OsHeapInit()初始化堆管理器。如果堆管理器初始化失败,则先释放多内存池,然后跳转到OUT标签处。 +最后,函数调用OsSlabMemInit()初始化 Slab 内存管理器,并将返回值设置为成功的状态码LOS_OK。 +在OUT标签处,函数会解锁之前保存的中断状态,并打印内存信息请求的跟踪日志。 +最终,函数返回初始化结果,可能是LOS_NOK表示失败,或者LOS_OK表示成功。 +这段代码主要实现了内存池的初始化逻辑,包括多内存池管理器、堆管理器和 Slab 内存管理器的初始化。*/ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size) { UINT32 ret = LOS_NOK; @@ -103,6 +125,21 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMemExcInteractionInit(UINTPTR memStart) * Description : Initialize Dynamic Memory pool * Return : LOS_OK on success or error code on failure */ + +/*这段代码是一个条件编译块,当定义了宏LOSCFG_EXC_INTERACTION时才会被编译。 + +LITE_OS_SEC_TEXT_INIT 是一个修饰符,用于指定函数所属的段(section)为.text.init,表示该函数在程序运行前会被初始化。 + +函数参数: + +memStart 是一个无符号整数指针,表示内存起始地址。 +函数内部逻辑: + +首先,函数将全局变量m_aucSysMem0指向memStart,即将系统内存的起始地址设为memStart。 +然后,函数将全局变量g_excInteractMemSize设置为宏定义EXC_INTERACT_MEM_SIZE的值,表示异常交互内存区域的大小。 +接下来,函数调用LOS_MemInit()函数,将m_aucSysMem0和g_excInteractMemSize作为参数进行内存初始化操作,并将返回结果保存在变量ret中。 +最后,函数打印一条信息,包含异常交互内存的地址和大小,并将初始化结果ret作为返回值返回。 +这段代码主要是用于初始化异常交互内存,通过调用LOS_MemInit()函数来初始化系统内存,并打印初始化信息。条件编译的目的是根据是否定义了LOSCFG_EXC_INTERACTION宏来控制代码的编译和执行。*/ LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart) { UINT32 ret; @@ -121,6 +158,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart) * Description : print heap information * Input : pool --- Pointer to the manager, to distinguish heap */ +/*这段代码是用于打印内存池(pool)信息的函数,接收一个pool指针作为参数。 + +函数参数: + +pool 是一个指向内存池的指针,用于获取内存池的信息。 +函数内部逻辑: + +首先,函数将传入的pool指针转换为LosHeapManager结构体类型的指针,并赋值给变量heapMan。 +然后,函数定义了一个LosHeapStatus类型的变量status,用于保存堆管理器的状态信息。 +接着,函数调用OsHeapStatisticsGet()函数获取堆管理器的状态信息,并将其保存在status变量中。如果函数返回错误码LOS_NOK,则函数直接返回。 +最后,函数打印一条包含内存池信息的日志信息,包括内存池地址、内存池大小、已使用内存大小、空闲内存大小、最大空闲节点大小、已分配节点数量和空闲节点数量。 +这段代码主要是用于获取内存池的状态信息,并打印到控制台或日志文件中,方便调试和排查内存泄漏等问题。*/ VOID OsMemInfoPrint(const VOID *pool) { struct LosHeapManager *heapMan = (struct LosHeapManager *)pool; @@ -136,6 +185,20 @@ VOID OsMemInfoPrint(const VOID *pool) status.usedNodeNum, status.freeNodeNum); } +/*这段代码是用于内存分配的函数,可以从指定的内存池中分配一块指定大小的内存。 + +函数参数: + +pool 是一个指向内存池的指针,用于从该内存池中分配内存。 +size 是需要分配的内存大小。 +函数内部逻辑: + +首先,函数定义了一个空指针ptr,用于保存分配到的内存块地址。 +然后,函数检查传入的参数,如果pool为空或者size为0,则直接返回空指针。 +接着,函数锁住中断,调用OsSlabMemAlloc()函数尝试从内存池的SLAB分配器中获取一块指定大小的内存。如果分配成功,则将返回的内存地址保存在ptr中。 +如果从SLAB分配器中分配内存失败,则调用OsHeapAlloc()函数从堆内存中分配一块指定大小的内存,并将返回的内存地址保存在ptr中。 +最后,函数解锁中断,记录内存分配操作的追踪日志,并返回分配到的内存地址。 +这段代码主要是用于从内存池中分配内存,首先尝试从SLAB分配器中获取内存,如果失败则从堆内存中获取。在获取内存时还记录了内存分配操作的追踪日志,方便调试和内存优化。*/ LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { VOID *ptr = NULL; @@ -158,6 +221,19 @@ LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) return ptr; } +/*这段代码是用于按指定对齐边界分配内存的函数,可以从指定的内存池中分配一块指定大小、按指定对齐边界对齐的内存。 + +函数参数: + +pool 是一个指向内存池的指针,用于从该内存池中分配内存。 +size 是需要分配的内存大小。 +boundary 是需要对齐的边界大小。返回的内存地址将会是该边界的整数倍。 +函数内部逻辑: + +首先,函数定义了一个空指针ptr,用于保存分配到的内存块地址。 +然后,函数锁住中断,调用OsHeapAllocAlign()函数从堆内存中按指定对齐边界分配一块指定大小的内存。如果分配成功,则将返回的内存地址保存在ptr中。 +最后,函数解锁中断,记录内存分配操作的追踪日志,并返回分配到的内存地址。 +这段代码主要是用于从内存池中按指定对齐边界分配内存,只能在堆内存上操作。在分配内存时还记录了内存分配操作的追踪日志,方便调试和内存优化。*/ LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { VOID *ptr = NULL; @@ -171,6 +247,14 @@ LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundar return ptr; } + +/*这段代码是用于重新分配内存大小的函数,主要有以下几个步骤: + +首先判断需要重新分配大小的指针ptr是否为空,如果为空,说明需要分配一块新的内存,直接调用LOS_MemAlloc()函数从内存池中分配一块指定大小的内存并返回。 +如果需要重新分配大小的指针ptr不为空且所需大小为0,则将该指针对应的内存块释放掉。 +如果需要重新分配大小的指针ptr不为空且所需大小非0,则需要从堆内存中分配一块新的内存,并将原内存中的数据拷贝到新内存中。这里在拷贝数据之前,需要先判断原内存地址是否合法。具体方法是通过OsSlabMemCheck()函数检查该指针是否属于内存池中的某个内存块,若是,则复制原内存中的数据;否则,根据原内存指针前面存储的一个整数值(表示实际内存块的大小和对齐状态)找到真正的内存块,再进行内存拷贝。 +将原内存块释放掉,返回分配到的新内存地址。 +这段代码的作用是实现重新分配内存大小的功能,可以对已经分配的内存进行扩展或缩小。在实现过程中,需要考虑到原内存块中已经存储的数据,避免无意义的内存拷贝操作。*/ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { VOID *retPtr = NULL; @@ -228,6 +312,15 @@ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) return retPtr; } +/*这段代码是用于释放内存的函数,主要有以下几个步骤: + +首先判断内存池指针pool和需要释放的内存指针mem是否为空,如果其中任意一个为空,则返回错误码LOS_NOK表示释放失败。 +获取并保存当前的中断状态,以便后续恢复。 +调用OsSlabMemFree()函数尝试从内存池中释放指定的内存块。若成功释放,则将返回值设置为TRUE,否则继续执行下一步。 +如果调用OsSlabMemFree()函数失败,说明该内存块不是由内存池分配的,需要调用OsHeapFree()函数尝试从堆内存中释放指定的内存块。同样,若成功释放,则将返回值设置为TRUE,否则返回值保持为FALSE。 +恢复之前保存的中断状态。 +根据最终的返回值,如果为TRUE,则返回成功码LOS_OK,否则返回失败码LOS_NOK。 +这段代码的作用是实现内存的释放功能。首先尝试从内存池中释放内存,如果失败,则再尝试从堆内存中释放内存。通过这两种方式,可以确保能够释放从内存池或堆中分配的内存块。*/ LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *mem) { BOOL ret = FALSE; @@ -250,6 +343,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *mem) return (ret == TRUE ? LOS_OK : LOS_NOK); } +/*这段代码是用于获取内存池状态信息的函数,主要有以下几个步骤: + +首先判断内存池指针pool和状态信息指针status是否为空,如果其中任意一个为空,则返回错误码LOS_NOK表示获取失败。 +声明一个LosHeapStatus结构体类型的变量heapStatus,用于保存堆内存的状态信息。 +声明一个错误码变量err和一个中断状态变量intSave。 +获取并保存当前的中断状态,以便后续恢复。 +调用OsHeapStatisticsGet()函数获取指定内存池的堆内存状态信息,将结果保存在heapStatus中。如果返回错误码不等于LOS_OK,则表示获取失败,释放锁并返回错误码LOS_NOK。 +将获取到的堆内存状态信息赋值给传入的status参数,包括总使用大小、总空闲大小、最大空闲节点大小、已使用节点数量和空闲节点数量。 +如果配置了任务内存统计,则还会将使用的峰值赋值给status的uwUsageWaterLine字段。 +释放锁并返回成功码LOS_OK。 +这段代码的作用是获取指定内存池的状态信息,包括已使用的内存大小、空闲的内存大小、最大空闲节点的大小等。通过这些状态信息,可以了解内存池的使用情况,并进行相应的优化和管理。*/ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *status) { LosHeapStatus heapStatus; @@ -282,6 +386,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *st return LOS_OK; } +/*这段代码是用于获取指定内存池已使用内存大小的函数,主要有以下几个步骤: + +首先判断内存池指针pool是否为空,如果为空,则返回错误码OS_NULL_INT表示获取失败。 +声明一个LosHeapStatus结构体类型的变量heapStatus,用于保存堆内存的状态信息。 +声明一个错误码变量err和一个中断状态变量intSave。 +获取并保存当前的中断状态,以便后续恢复。 +调用OsHeapStatisticsGet()函数获取指定内存池的堆内存状态信息,将结果保存在heapStatus中。如果返回错误码不等于LOS_OK,则表示获取失败,释放锁并返回错误码OS_NULL_INT。 +释放锁并返回堆内存的总使用大小。 +这段代码的作用是获取指定内存池已使用的内存大小。通过该函数可以了解内存池的已使用情况,以便进行相应的管理和优化。*/ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) { LosHeapStatus heapStatus; @@ -303,6 +416,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) return heapStatus.totalUsedSize; } +/*这段代码是用于获取指定内存池的大小的函数,主要有以下几个步骤: + +首先判断内存池指针pool是否为空,如果为空,则返回错误码OS_NULL_INT表示获取失败。 +声明一个LosHeapManager结构体类型的指针变量heapManager,用于保存内存池的管理信息。 +将传入的内存池指针转换为LosHeapManager类型的指针,并将结果保存在heapManager中。 +返回内存池的大小,即heapManager->size。 +这段代码的作用是获取指定内存池的大小。通过该函数可以了解内存池的大小,以便进行相应的管理和优化。*/ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(const VOID *pool) { struct LosHeapManager *heapManager = NULL; @@ -315,6 +435,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(const VOID *pool) return heapManager->size; } +/*这段代码是用于对指定内存池进行完整性检查的函数,主要有以下几个步骤: + +首先判断内存池指针pool是否为空,如果为空,则返回错误码OS_NULL_INT表示检查失败。 +声明一个中断状态变量intSave和一个无符号整型变量ret用于保存检查结果。 +获取并保存当前的中断状态,以便后续恢复。 +调用OsHeapIntegrityCheck()函数对指定的内存池进行完整性检查,并将检查结果保存在ret中。如果返回的结果不为0,则表示检查失败。 +释放锁并返回检查结果。 +这段代码的作用是对指定的内存池进行完整性检查,以确保内存池中的数据没有被破坏或溢出。通过该函数可以及时发现内存池中的问题,并采取相应的措施进行修复或处理。*/ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) { UINT32 intSave; @@ -331,6 +459,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) return ret; } +/*这段代码是用于对多个内存池进行完整性检查的函数,主要有以下几个步骤: + +首先调用LOS_MemIntegrityCheck()函数对系统内存池m_aucSysMem1进行完整性检查,并判断返回值是否为LOS_OK。 +如果检查通过,则在控制台输出一条信息表示检查成功,并在需要时将该信息写入异常信息缓冲区。 +如果系统内存池检查未通过,则不进行任何处理。 +如果宏定义LOSCFG_EXC_INTERACTION被定义,则继续执行下面的代码,否则直接结束函数。 +调用LOS_MemIntegrityCheck()函数对异常交互内存池m_aucSysMem0进行完整性检查,并判断返回值是否为LOS_OK。 +如果检查通过,则在控制台输出一条信息表示检查成功,并在需要时将该信息写入异常信息缓冲区。 +如果异常交互内存池检查未通过,则不进行任何处理。 +这段代码的作用是对多个内存池进行完整性检查,以确保内存池中的数据没有被破坏或溢出。通过该函数可以及时发现内存池中的问题,并采取相应的措施进行修复或处理。*/ VOID OsMemIntegrityMultiCheck(VOID) { if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) { diff --git a/src/kernel/base/mem/bestfit_little/los_memory_internal.h b/src/kernel/base/mem/bestfit_little/los_memory_internal.h index 2aeb022..52e29ff 100644 --- a/src/kernel/base/mem/bestfit_little/los_memory_internal.h +++ b/src/kernel/base/mem/bestfit_little/los_memory_internal.h @@ -42,13 +42,18 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - +//用于将指定的大小 sz 进行对齐,返回对齐后的大小。它使用 HEAP_ALIGN 宏定义来指定对齐的字节数,通过将 sz 加上 HEAP_ALIGN - 1,然后按位取反与运算(&)来实现向上对齐。 #define ALIGNE(sz) (((sz) + HEAP_ALIGN - 1) & (~(HEAP_ALIGN - 1))) +//用于将指定的 value 进行 align 字节对齐,返回对齐后的值。它将 value 转换为 UINT32 类型,并将其与 align - 1 按位取反与运算,即将 value 向上舍入到最近的 align 的倍数。 #define OS_MEM_ALIGN(value, align) (((UINT32)(UINTPTR)(value) + (UINT32)((align) - 1)) & \ (~(UINT32)((align) - 1))) +//用于表示对齐标志的宏定义,其值为 0x80000000。 #define OS_MEM_ALIGN_FLAG 0x80000000 +//用于设置对齐标志的宏定义,将传入的 align 参数按位或运算与 OS_MEM_ALIGN_FLAG 进行组合。 #define OS_MEM_SET_ALIGN_FLAG(align) ((align) = ((align) | OS_MEM_ALIGN_FLAG)) +//用于获取对齐标志的宏定义,将传入的 align 参数与 OS_MEM_ALIGN_FLAG 进行按位与运算,得到对齐标志。 #define OS_MEM_GET_ALIGN_FLAG(align) ((align) & OS_MEM_ALIGN_FLAG) +//用于获取对齐间隙大小的宏定义,将传入的 align 参数与 ~OS_MEM_ALIGN_FLAG 进行按位与运算,得到去除对齐标志后的值。 #define OS_MEM_GET_ALIGN_GAPSIZE(align) ((align) & (~OS_MEM_ALIGN_FLAG)) typedef struct tagLosHeapStatus { @@ -60,8 +65,12 @@ typedef struct tagLosHeapStatus { #ifdef LOSCFG_MEM_TASK_STAT UINT32 usageWaterLine; #endif -} LosHeapStatus; +} LosHeapStatus;//结构体:描述了内存堆的状态信息,包括总共使用的大小、总共空闲的大小、最大空闲节点的大小、已用节点数和空闲节点数等字段。 +/*结构体:描述了内存堆中的每个节点,包括前一个节点指针、任务 ID、节点大小、 +是否已经被使用、是否需要对齐等字段。这里使用了位域来节省空间, +并且使用了一个长度为 0 的数组 data[0] 来占位, +方便动态分配内存。*/ struct LosHeapNode { struct LosHeapNode *prev; #ifdef LOSCFG_MEM_TASK_STAT @@ -73,12 +82,12 @@ struct LosHeapNode { UINT8 data[0]; }; -extern BOOL OsHeapInit(VOID *pool, UINT32 size); -extern VOID* OsHeapAlloc(VOID *pool, UINT32 size); -extern VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary); -extern BOOL OsHeapFree(VOID *pool, const VOID* ptr); -extern UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status); -extern UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap); +extern BOOL OsHeapInit(VOID *pool, UINT32 size);//函数声明:用于初始化内存池,即将一块内存空间转化为一个内存堆,并返回是否初始化成功。 +extern VOID* OsHeapAlloc(VOID *pool, UINT32 size);//函数声明:用于在内存堆上分配一块指定大小的内存,并返回分配到的内存地址。 +extern VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary);//函数声明:用于在内存堆上分配一块指定大小并且按照给定对齐边界对齐的内存,并返回分配到的内存地址。 +extern BOOL OsHeapFree(VOID *pool, const VOID* ptr);//函数声明:用于释放内存堆中的指定内存地址所对应的节点,返回是否释放成功。 +extern UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status);//函数声明:用于获取内存堆的状态信息,并将其保存在传入的 LosHeapStatus 结构体中,返回获取到的信息字节数。 +extern UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap);//函数声明:用于检查整个内存堆的完整性,即检查是否存在内存泄漏或内存重叠等问题。 #ifdef __cplusplus #if __cplusplus diff --git a/src/kernel/base/mem/common/memstat/los_memstat.c b/src/kernel/base/mem/common/memstat/los_memstat.c index 7517b88..b0dc92c 100644 --- a/src/kernel/base/mem/common/memstat/los_memstat.c +++ b/src/kernel/base/mem/common/memstat/los_memstat.c @@ -39,6 +39,15 @@ extern "C" { #define MIN_TASK_ID(x, y) ((x) > (y) ? (y) : (x)) #define MAX_MEM_USE(x, y) ((x) > (y) ? (x) : (y)) +/*这段代码是一个函数OsMemstatTaskUsedInc的实现,用于更新内存统计信息。 + +代码首先获取任务ID的最小值,确保不越界。然后通过stat参数获取到任务内存统计数组taskMemstats。 + +接下来,代码将usedSize参数累加到对应任务的memUsed字段上,表示该任务使用的内存增加了usedSize字节。然后使用MAX_MEM_USE宏更新该任务的内存峰值,即将当前的memUsed值与memPeak进行比较,取较大值作为新的memPeak值。 + +最后,代码将usedSize参数累加到整体内存统计信息stat的memTotalUsed字段上,表示系统整体使用的内存增加了usedSize字节。同样地,使用MAX_MEM_USE宏更新整体内存的峰值。 + +这段代码的作用是在任务执行过程中,根据实际使用的内存大小更新任务和整体的内存统计信息。*/ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedInc(Memstat *stat, UINT32 usedSize, UINT32 taskId) { UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1); @@ -51,6 +60,13 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedInc(Memstat *stat, UINT32 usedSize, stat->memTotalPeak = MAX_MEM_USE(stat->memTotalPeak, stat->memTotalUsed); } +/*这段代码是一个函数OsMemstatTaskUsedDec的实现,用于更新内存统计信息。 + +代码首先获取任务ID的最小值,确保不越界。然后通过stat参数获取到任务内存统计数组taskMemstats。 + +接下来,代码判断当前任务使用的内存是否小于要释放的内存usedSize,如果是,则打印一条信息并直接返回。否则,将usedSize从对应任务的memUsed字段上减去,表示该任务使用的内存减少了usedSize字节。然后将usedSize从整体内存统计信息stat的memTotalUsed字段上减去,表示系统整体使用的内存减少了usedSize字节。 + +这段代码的作用是在任务执行过程中,根据实际释放的内存大小更新任务和整体的内存统计信息。如果当前任务使用的内存小于要释放的内存大小,则说明存在内存释放错误,打印一条信息以便调试。*/ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedDec(Memstat *stat, UINT32 usedSize, UINT32 taskId) { UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1); @@ -66,6 +82,15 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedDec(Memstat *stat, UINT32 usedSize, stat->memTotalUsed -= usedSize; } +/*这段代码是一个函数OsMemstatTaskClear的实现,用于清除任务的内存统计信息。 + +代码首先获取任务ID的最小值,确保不越界。然后通过stat参数获取到任务内存统计数组taskMemstats。 + +接下来,代码判断当前任务使用的内存是否为0,如果不为0,则打印一条信息,说明在删除任务时该任务仍有未释放的内存。 + +然后,将对应任务的memUsed字段和memPeak字段都设置为0,表示清除该任务的内存使用和内存峰值记录。 + +这段代码的作用是在删除任务时,清除该任务的内存统计信息,并在必要时打印警告信息以提醒开发者注意内存释放的完整性。*/ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskClear(Memstat *stat, UINT32 taskId) { UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1); @@ -80,6 +105,13 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskClear(Memstat *stat, UINT32 taskId) taskMemstats[record].memPeak = 0; } +/*这段代码是一个函数OsMemstatTaskUsage的实现,用于获取指定任务的内存使用量。 + +代码首先获取任务ID的最小值,确保不越界。然后通过stat参数获取到任务内存统计数组taskMemstats。 + +接下来,代码返回指定任务的memUsed字段,即该任务当前使用的内存量。 + +这段代码的作用是获取指定任务的内存使用量,可以用于监控和调试任务的内存消耗情况。*/ LITE_OS_SEC_TEXT_MINOR UINT32 OsMemstatTaskUsage(const Memstat *stat, UINT32 taskId) { UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1); @@ -88,6 +120,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsMemstatTaskUsage(const Memstat *stat, UINT32 tas return taskMemstats[record].memUsed; } +/*这段代码是一个函数OsMemTaskUsage的实现,用于获取指定任务在系统内所有内存池中的内存使用量之和。 + +首先,代码定义了两个指针变量pool和stat,用于存储内存池信息和内存统计信息。 + +然后,通过判断是否开启了多内存池支持,分别处理单内存池和多内存池的情况。 + +如果未开启多内存池支持,则直接获取系统内存池的内存统计信息stat。最后,调用OsMemstatTaskUsage函数获取指定任务在该内存池中的内存使用量,并返回结果。 + +如果开启了多内存池支持,则需要遍历所有内存池,将每个内存池中指定任务的内存使用量累加起来,最终返回总和。 + +这段代码的作用是获取指定任务在系统内所有内存池中的内存使用量之和,可以用于监控和调试系统内存的消耗情况。*/ UINT32 OsMemTaskUsage(UINT32 taskId) { LosMemPoolInfo *pool = NULL; @@ -110,6 +153,17 @@ UINT32 OsMemTaskUsage(UINT32 taskId) #endif } +/*这段代码是一个函数OsMemTaskClear的实现,用于清除指定任务在系统内所有内存池中的内存统计信息。 + +首先,代码定义了两个指针变量pool和stat,用于存储内存池信息和内存统计信息。 + +然后,通过判断是否开启了多内存池支持,分别处理单内存池和多内存池的情况。 + +如果未开启多内存池支持,则直接获取系统内存池的内存统计信息stat。最后,调用OsMemstatTaskClear函数清除指定任务在该内存池中的内存统计信息。 + +如果开启了多内存池支持,则需要遍历所有内存池,依次获取每个内存池的内存统计信息,并调用OsMemstatTaskClear函数清除指定任务在每个内存池中的内存统计信息。 + +这段代码的作用是清除指定任务在系统内所有内存池中的内存统计信息,可以用于在删除任务时释放相关的内存统计记录,以确保内存统计信息的准确性。*/ VOID OsMemTaskClear(UINT32 taskId) { LosMemPoolInfo *pool = NULL; diff --git a/src/kernel/base/mem/common/multipool/los_multipool.c b/src/kernel/base/mem/common/multipool/los_multipool.c index c4c8e33..d50caa8 100644 --- a/src/kernel/base/mem/common/multipool/los_multipool.c +++ b/src/kernel/base/mem/common/multipool/los_multipool.c @@ -30,6 +30,17 @@ STATIC VOID *g_poolHead = NULL; +/*这段代码是一个函数OsMemMulPoolInit的实现,用于初始化多内存池。 + +首先,代码定义了几个变量,包括nextPool、curPool和poolEnd。其中,nextPool和curPool用于遍历内存池链表,poolEnd用于计算内存池的结束地址。 + +然后,通过循环遍历内存池链表,检查新的内存池是否与已有的内存池冲突。如果发现冲突,则输出错误信息并返回错误码。 + +接着,根据内存池链表的状态,将新的内存池插入到链表的末尾或者作为链表的头节点。 + +最后,设置新的内存池的下一个内存池指针为NULL,并返回成功的状态码。 + +这段代码的作用是初始化多内存池,将新的内存池插入到内存池链表中,并确保各个内存池之间没有冲突。多内存池的使用可以提供更灵活的内存管理能力,方便系统对不同类型的内存进行分配和释放。*/ UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size) { VOID *nextPool = g_poolHead; @@ -58,6 +69,21 @@ UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size) return LOS_OK; } +/*这段代码是一个函数OsMemMulPoolDeinit的实现,用于反初始化多内存池。 + +首先,代码定义了几个变量,包括ret、nextPool和curPool。其中,ret用于保存函数执行结果,nextPool和curPool用于遍历内存池链表。 + +然后,通过一个do-while循环的结构来执行具体的反初始化操作。 + +在循环中,首先检查传入的内存池指针是否为空,如果为空则直接退出循环。 + +接着,判断传入的内存池是否为链表的头节点。如果是头节点,则将链表的头指针指向下一个内存池,并返回成功的状态码。 + +如果不是头节点,则遍历内存池链表,寻找与传入的内存池指针相等的节点。一旦找到对应的节点,将前一个节点的next指针指向下一个节点,并返回成功的状态码。 + +最后,循环结束后,返回执行结果。 + +这段代码的作用是反初始化多内存池,从内存池链表中移除指定的内存池,并释放相关的资源。反初始化操作可以根据需要动态地增加或删除内存池,以适应系统的内存管理需求的变化。*/ UINT32 OsMemMulPoolDeinit(const VOID *pool) { UINT32 ret = LOS_NOK; @@ -90,12 +116,29 @@ UINT32 OsMemMulPoolDeinit(const VOID *pool) return ret; } +/*这段代码是函数OsMemMulPoolHeadGet的实现,用于获取多内存池链表的头节点指针。 +代码很简单,直接返回全局变量g_poolHead,该变量保存了多内存池链表的头节点指针。 + +调用这个函数可以方便地获取多内存池链表的头节点地址,以便后续进行其他操作,比如对内存池进行遍历、查询或者修改等。*/ VOID *OsMemMulPoolHeadGet(VOID) { return g_poolHead; } +/*这段代码是函数LOS_MemDeInit的实现,用于释放指定内存池的资源并进行反初始化操作。 + +首先,代码定义了几个变量,包括ret和intSave。其中,ret用于保存函数执行结果,intSave用于保存中断状态。 + +接下来,通过调用MEM_LOCK函数保存中断状态,以确保在执行反初始化操作期间不会被中断打断。 + +然后,调用OsMemMulPoolDeinit函数对指定的内存池进行反初始化操作,将返回结果保存到ret中。 + +最后,通过调用MEM_UNLOCK函数恢复之前保存的中断状态。 + +最终,返回执行结果。 + +这段代码的作用是释放指定内存池的资源,并执行反初始化操作。在释放内存池之前,使用MEM_LOCK函数保存中断状态,避免在释放内存池期间被中断打断,然后通过调用OsMemMulPoolDeinit函数执行反初始化操作。最后,使用MEM_UNLOCK函数恢复之前保存的中断状态。这样可以确保在释放内存池的过程中,不会发生竞态条件或者资源冲突的问题。*/ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pool) { UINT32 ret; @@ -108,6 +151,17 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pool) return ret; } +/*这段代码是函数LOS_MemPoolList的实现,用于打印多内存池链表中每个内存池的信息。 + +首先,代码定义了两个变量,包括nextPool和index。其中,nextPool用于保存下一个内存池的指针,index用于记录内存池的数量。 + +然后,通过一个while循环遍历多内存池链表,对每个内存池调用OsMemInfoPrint函数进行信息输出,并更新nextPool和index。 + +在循环中,先输出当前内存池的编号,然后调用OsMemInfoPrint函数输出该内存池的相关信息。 + +最后,返回内存池的数量。 + +这段代码的作用是打印多内存池链表中每个内存池的信息,便于开发人员进行调试和管理。通过遍历内存池链表,可以获取每个内存池的地址,并使用OsMemInfoPrint函数将内存池的相关信息输出到控制台上。同时,还可以统计内存池的数量,以便对内存池进行更精细的管理。*/ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemPoolList(VOID) { VOID *nextPool = g_poolHead; diff --git a/src/kernel/extended/.vscode/c_cpp_properties.json b/src/kernel/extended/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..b1880ec --- /dev/null +++ b/src/kernel/extended/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "D:/mingw64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/src/kernel/extended/.vscode/launch.json b/src/kernel/extended/.vscode/launch.json new file mode 100644 index 0000000..f78275c --- /dev/null +++ b/src/kernel/extended/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "h:/ruanjian/LiteOS-Reading/src/kernel/extended/perf/pmu", + "program": "h:/ruanjian/LiteOS-Reading/src/kernel/extended/perf/pmu/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/src/kernel/extended/.vscode/settings.json b/src/kernel/extended/.vscode/settings.json new file mode 100644 index 0000000..3e5eb95 --- /dev/null +++ b/src/kernel/extended/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/src/kernel/extended/lowpower/los_lowpower.c b/src/kernel/extended/lowpower/los_lowpower.c index bd9dde0..2a19c3e 100644 --- a/src/kernel/extended/lowpower/los_lowpower.c +++ b/src/kernel/extended/lowpower/los_lowpower.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_lowpower_pri.h" #ifdef LOSCFG_KERNEL_TICKLESS #include "los_tickless_pri.h" @@ -36,10 +36,10 @@ __attribute__((section(".data"))) STATIC const PowerMgrOps *g_pmOps = NULL; -VOID OsLowpowerInit(const PowerMgrOps *pmOps) +VOID OsLowpowerInit(const PowerMgrOps *pmOps) /*鍒濆鍖栦綆鍔熻楃鐞*/ { if (pmOps == NULL) { -#ifdef LOSCFG_KERNEL_POWER_MGR +#ifdef LOSCFG_KERNEL_POWER_MGR/*鏄惁閰嶇疆浜嗕綆鍔熻楀唴鏍哥鐞*/ PRINT_ERR("\r\n [PM] PowerMgrOps must be non-null.\n"); return; #endif @@ -48,34 +48,34 @@ VOID OsLowpowerInit(const PowerMgrOps *pmOps) return; } - if (g_pmOps != NULL) { + if (g_pmOps != NULL) { PRINT_ERR("\r\n [PM] Reassignment of PowerMgrOps is forbidden.\n"); return; } g_pmOps = pmOps; LOS_LowpowerHookReg(OsPowerMgrProcess); - + /*娉ㄥ唽浣庡姛鑰楀鐞嗗嚱鏁板拰缁堢鍞ら啋澶勭悊鍑芥暟*/ LOS_IntWakeupHookReg(OsPowerMgrWakeUpFromInterrupt); } -VOID OsPowerMgrProcess(VOID) +VOID OsPowerMgrProcess(VOID) /*鎵ц浣庡姛鑰楃鐞嗙殑澶勭悊杩囩▼*/ { -#ifdef LOSCFG_KERNEL_POWER_MGR +#ifdef LOSCFG_KERNEL_POWER_MGR/*鍒ゆ柇鏄惁閰嶇疆浜嗗唴鏍镐綆鍔熻楃鐞*/ CALL_PMOPS_FUNC_VOID(process); #else - if (g_pmOps == NULL) { + if (g_pmOps == NULL) { #ifdef LOSCFG_KERNEL_TICKLESS OsTicklessOpen(); - wfi(); + wfi(); /*绠$悊杩涚▼杩涘叆鐫$湢鐘舵*/ #endif } else { - CALL_PMOPS_FUNC_VOID(process); + CALL_PMOPS_FUNC_VOID(process);/*鎵ц浣庡姛鑰楃鐞*/ } #endif } -VOID OsPowerMgrWakeUpFromInterrupt(UINT32 intNum) +VOID OsPowerMgrWakeUpFromInterrupt(UINT32 intNum) /*浠庝腑鏂敜閱掑鐞*/ { #ifdef LOSCFG_KERNEL_POWER_MGR CALL_PMOPS_FUNC_VOID(resumeFromInterrupt, intNum); @@ -90,44 +90,44 @@ VOID OsPowerMgrWakeUpFromInterrupt(UINT32 intNum) #endif } -VOID OsPowerMgrWakeupFromReset(VOID) +VOID OsPowerMgrWakeupFromReset(VOID) /*浠庡浣嶅敜閱掑鐞*/ { CALL_PMOPS_FUNC_VOID(wakeupFromReset); } -VOID LOS_PowerMgrChangeFreq(LosFreqMode freq) +VOID LOS_PowerMgrChangeFreq(LosFreqMode freq)/*鏀瑰彉绯荤粺棰戠巼*/ { CALL_PMOPS_FUNC_VOID(changeFreq, freq); } -VOID LOS_PowerMgrDeepSleepVoteBegin(VOID) +VOID LOS_PowerMgrDeepSleepVoteBegin(VOID)/*寮濮嬫繁搴︾潯鐪犺缃*/ { CALL_PMOPS_FUNC_VOID(deepSleepVoteBegin); } -VOID LOS_PowerMgrDeepSleepVoteEnd(VOID) +VOID LOS_PowerMgrDeepSleepVoteEnd(VOID)/*缁撴潫娣卞害鐫$湢鐘舵*/ { CALL_PMOPS_FUNC_VOID(deepSleepVoteEnd); } -VOID LOS_PowerMgrSleepDelay(UINT32 tick) +VOID LOS_PowerMgrSleepDelay(UINT32 tick)/*寤惰繜杩涘叆鐫$湢鐘舵*/ { CALL_PMOPS_FUNC_VOID(deepSleepVoteDelay, tick); } -VOID LOS_PowerMgrRegisterExtVoter(UINT32 (*callback)(VOID)) +VOID LOS_PowerMgrRegisterExtVoter(UINT32 (*callback)(VOID))/*娉ㄥ唽澶栭儴鎶曠エ鑰*/ { CALL_PMOPS_FUNC_VOID(registerExternalVoter, callback); } -UINT32 LOS_PowerMgrGetSleepMode(VOID) +UINT32 LOS_PowerMgrGetSleepMode(VOID)/*鑾峰彇鐫$湢妯″紡*/ { UINT32 ret = 0; CALL_PMOPS_FUNC_RET(getSleepMode, ret); return ret; } -UINT32 LOS_PowerMgrGetDeepSleepVoteCount(VOID) +UINT32 LOS_PowerMgrGetDeepSleepVoteCount(VOID)/*鑾峰彇娣卞害鐫$湢鐨勬姇绁ㄨ鏁*/ { UINT32 ret = 0; CALL_PMOPS_FUNC_RET(getDeepSleepVoteCount, ret); diff --git a/src/kernel/extended/lowpower/powermgr/los_lowpower_impl.c b/src/kernel/extended/lowpower/powermgr/los_lowpower_impl.c index 0f8cc28..78f5f94 100644 --- a/src/kernel/extended/lowpower/powermgr/los_lowpower_impl.c +++ b/src/kernel/extended/lowpower/powermgr/los_lowpower_impl.c @@ -44,7 +44,7 @@ #endif #if defined(LOSCFG_KERNEL_RUNSTOP) || defined(LOSCFG_KERNEL_DEEPSLEEP) -/* Is system is up from the memory image, then this flag should be 1; else 0 */ +/* 濡傛灉绯荤粺鏄粠鍐呭瓨鏄犲儚涓惎鍔ㄧ殑锛屽垯璇ユ爣蹇楀簲涓1锛涘惁鍒欎负0銆*/ #ifdef LOSCFG_AARCH64 __attribute__((section(".data"))) INT64 g_resumeFromImg = LOS_COLD_RESET; __attribute__((section(".data"))) STATIC INT64 g_otherCoreResume = 0; @@ -55,8 +55,8 @@ __attribute__((section(".data"))) INT32 g_otherCoreResume = 0; #ifdef LOSCFG_AARCH64 /* - * 16: The number of aligned memory, - * 34: The number of task context registers(X0~X30, SP, DAIF, NZCV) + * 16: 瀵归綈鍐呭瓨鐨勬暟閲, + * 34: 浠诲姟涓婁笅鏂囧瘎瀛樺櫒鐨勬暟閲忥紝鎸囧瘎瀛樺櫒鐨勯泦鍚(X0~X30, SP, DAIF, NZCV) */ LITE_OS_SEC_DATA_MINOR __attribute__((aligned(16))) UINT64 g_saveSRContext[34]; /* 3: The number of available universal registers(X0, X1, X2) temporarily saved */ @@ -161,24 +161,24 @@ STATIC PowerMgrRunOps g_pmRunOps = { .postConfig = OsPostConfigDefault, }; -STATIC VOID OsLightSleepDefault(VOID) +STATIC VOID OsLightSleepDefault(VOID)/*杞婚噺绾х潯鐪犲嚱鏁帮紝鎵цwfi鎸囦护锛岃澶勭悊鍣ㄨ繘鍏ョ潯鐪犵姸鎬*/ { TRACE_FUNC_CALL(); wfi(); } -STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick) +STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick)/*璁剧疆鍞ら啋瀹氭椂鍣紝榛樿瀹炵幇涓虹┖鍑芥暟*/ { TRACE_FUNC_CALL(); } -STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID) +STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID)/*鎾ら攢鍞ら啋瀹氭椂鍣紝榛樿瀹炵幇杩斿洖0*/ { TRACE_FUNC_CALL(); return 0; } -STATIC UINT32 OsGetSleepTimeDefault(VOID) +STATIC UINT32 OsGetSleepTimeDefault(VOID)/*鑾峰彇褰撳墠浠诲姟浼戠湢鏃堕棿*/ { #ifdef LOSCFG_KERNEL_TICKLESS return OsSleepTicksGet(); @@ -187,12 +187,12 @@ STATIC UINT32 OsGetSleepTimeDefault(VOID) #endif } -STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks) +STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)/*閫夋嫨鍚堥傜殑浼戠湢妯″紡*/ { if (sleepTicks < g_pmMgr.minSleepTicks) { return LOS_INTERMIT_NONE; } - + /*榛樿瀹炵幇鏍规嵁浼戠湢鏃堕棿鍜屽綋鍓嶇郴缁熺姸鎬侀夋嫨杞婚噺绾х潯鐪犳垨鑰呮繁搴︾潯鐪犳ā寮*/ if (g_pmMgr.deepSleepOps != NULL && sleepTicks >= g_pmMgr.minDeepSleepTicks && g_pmRunOps.getDeepSleepVoteCount() == 0) { return LOS_INTERMIT_DEEP_SLEEP; @@ -201,73 +201,73 @@ STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks) return LOS_INTERMIT_LIGHT_SLEEP; } -STATIC VOID OsChangeFreqDefault(UINT8 freq) +STATIC VOID OsChangeFreqDefault(UINT8 freq)/*鏀瑰彉澶勭悊鍣ㄩ鐜*/ { (VOID)freq; TRACE_FUNC_CALL(); } -STATIC VOID OsEnterDeepSleepDefault(VOID) +STATIC VOID OsEnterDeepSleepDefault(VOID)// 杩涘叆娣卞害鐫$湢妯″紡鍑芥暟 { TRACE_FUNC_CALL(); wfi(); } -STATIC UINT32 OsPreConfigDefault(VOID) +STATIC UINT32 OsPreConfigDefault(VOID)//鐢垫簮绠$悊妯″潡棰勯厤缃嚱鏁 { TRACE_FUNC_CALL(); return 1; } -STATIC VOID OsPostConfigDefault(VOID) +STATIC VOID OsPostConfigDefault(VOID)//鐢垫簮绠$悊妯″潡鍚庨厤缃嚱鏁 { } #ifdef LOSCFG_KERNEL_DEEPSLEEP -STATIC BOOL OsCouldDeepSleepDefault(VOID) +STATIC BOOL OsCouldDeepSleepDefault(VOID)// 鍒ゆ柇鏄惁鍙互杩涘叆娣卞害鐫$湢妯″紡 { TRACE_FUNC_CALL(); return true; } -STATIC BOOL OsSuspendPreConfigDefault(VOID) +STATIC BOOL OsSuspendPreConfigDefault(VOID)// 浼戠湢鍓嶇殑棰勯厤缃嚱鏁 { TRACE_FUNC_CALL(); return true; } -STATIC VOID OsSuspendDeviceDefault(VOID) +STATIC VOID OsSuspendDeviceDefault(VOID)//浼戠湢鏃惰澶囨寕璧峰嚱鏁 { TRACE_FUNC_CALL(); } -STATIC VOID OsRollBackDefault(VOID) +STATIC VOID OsRollBackDefault(VOID)//鍞ら啋鍚庣殑鍥炴粴鍑芥暟 { TRACE_FUNC_CALL(); } -STATIC VOID OsResumeDeviceDefault(VOID) +STATIC VOID OsResumeDeviceDefault(VOID)//鍞ら啋鍚庣殑璁惧鎭㈠鍑芥暟 { TRACE_FUNC_CALL(); } -STATIC VOID OsResumePostConfigDefault(VOID) +STATIC VOID OsResumePostConfigDefault(VOID)//鍞ら啋鍚庣數婧愮鐞嗘ā鍧楀悗閰嶇疆鍑芥暟 { TRACE_FUNC_CALL(); } -STATIC VOID OsSystemWakeupDefault(VOID) +STATIC VOID OsSystemWakeupDefault(VOID)//绯荤粺鍞ら啋鍑芥暟 { TRACE_FUNC_CALL(); } -STATIC VOID OsResumeCallBackDefault(VOID) +STATIC VOID OsResumeCallBackDefault(VOID)//鍞ら啋鍚庡洖璋冨嚱鏁 { TRACE_FUNC_CALL(); } -STATIC VOID OsOtherCoreResumeDefault(VOID) +STATIC VOID OsOtherCoreResumeDefault(VOID)//鍏朵粬鏍稿績鍞ら啋鍑芥暟 { TRACE_FUNC_CALL(); } @@ -275,18 +275,18 @@ STATIC VOID OsOtherCoreResumeDefault(VOID) STATIC VOID OsDeepSleepResume(VOID); STATIC PowerMgrDeepSleepOps g_deepSleepOps = { - .couldDeepSleep = OsCouldDeepSleepDefault, - .systemWakeup = OsSystemWakeupDefault, - .suspendPreConfig = OsSuspendPreConfigDefault, - .suspendDevice = OsSuspendDeviceDefault, - .rollback = OsRollBackDefault, - .resumeDevice = OsResumeDeviceDefault, - .resumePostConfig = OsResumePostConfigDefault, - .resumeCallBack = OsResumeCallBackDefault, - .otherCoreResume = OsOtherCoreResumeDefault + .couldDeepSleep = OsCouldDeepSleepDefault, //鍒ゆ柇鏄惁鍙互杩涘叆娣卞害鐫$湢妯″紡鐨勫嚱鏁版寚閽 + .systemWakeup = OsSystemWakeupDefault,//鍞ら啋鍑芥暟鐨勫嚱鏁版寚閽 + .suspendPreConfig = OsSuspendPreConfigDefault,//淇潰鍓嶇殑棰勯厤缃嚱鏁扮殑鍑芥暟鎸囬拡 + .suspendDevice = OsSuspendDeviceDefault,//璁惧鎸傝捣鍑芥暟鐨勫嚱鏁版寚閽 + .rollback = OsRollBackDefault,//鍞ら啋鍚庣殑鍥炴粴鍑芥暟鐨勫嚱鏁版寚閽 + .resumeDevice = OsResumeDeviceDefault,//璁惧鍥炲鍑芥暟鐨勫嚱鏁版寚閽 + .resumePostConfig = OsResumePostConfigDefault,//鍞ら啋鍚庣數婧愮鐞嗘ā鍧楀悗閰嶇疆鍑芥暟鐨勫嚱鏁版寚閽 + .resumeCallBack = OsResumeCallBackDefault,//鍞ら啋鍚庡洖璋冨嚱鏁扮殑鍑芥暟鎸囬拡 + .otherCoreResume = OsOtherCoreResumeDefault//鍏朵粬鏍稿績鍞ら啋鍑芥暟鐨勫嚱鏁版寚閽 }; -STATIC INLINE VOID OsTickResume(UINT32 sleepTicks) +STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)//鐢ㄤ簬鏇存柊绯荤粺濮嬬粓锛屾牴鎹紤鐪犳椂闂磋皟鏁寸郴缁熸椂閽 { UINT32 cpuid = ArchCurrCpuid(); if (sleepTicks > g_pmMgr.sleepTime[cpuid]) { @@ -297,7 +297,7 @@ STATIC INLINE VOID OsTickResume(UINT32 sleepTicks) OsSysTimeUpdate(sleepTicks); } -STATIC VOID OsDeepSleepResume(VOID) +STATIC VOID OsDeepSleepResume(VOID)//娣卞害鐫$湢鍞ら啋鍚庣殑澶勭悊鍑芥暟 { DEEPOPS_CALL_FUNC_VOID(resumeFromReset); LOS_AtomicSet(&g_pmMgr.resumeSleepCores, OS_MP_CPU_ALL); @@ -305,30 +305,32 @@ STATIC VOID OsDeepSleepResume(VOID) #ifdef LOSCFG_KERNEL_CPUP OsSetCpuCycle(0); #endif - +//鎭㈠璁剧疆锛屾仮澶嶅叾浠栨牳蹇冭繘绋 #if (LOSCFG_KERNEL_SMP == YES) release_secondary_cores(); #endif OsSRRestoreRegister(); } -STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID) +STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)//鐢ㄤ簬涓绘牳蹇冭繘鍏ユ繁搴︾潯鐪 { + //鎸傝捣棰勯厤缃 LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1); g_deepSleepOps.suspendPreConfig(); - + //鏄惁鍙互杩涘叆绁炲鐫$湢鍒ゆ柇 if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM && g_deepSleepOps.couldDeepSleep()) { g_deepSleepOps.suspendDevice(); g_pmRunOps.setWakeUpTimer(g_pmMgr.sleepTime[0]); g_resumeFromImg = LOS_COLD_RESET; OsSRSaveRegister(); - + //杩涘叆娣卞害鐫$湢锛岃繘琛屽洖婊氭搷浣滐紝淇濆瓨涓婁笅鏂 if (g_resumeFromImg == LOS_COLD_RESET) { g_resumeFromImg = LOS_DEEP_SLEEP_RESET; CALL_RUN_OPS_FUNC_NO_RETURN(contextSave); g_pmRunOps.enterDeepSleep(); g_deepSleepOps.rollback(); } + //璁剧疆鍞ら啋瀹氭椂鍣 g_deepSleepOps.resumeDevice(); UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer(); OsSysTimeUpdate(sleepTicks); @@ -342,42 +344,43 @@ STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID) LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1); } -STATIC INLINE VOID OsEnterSleepMode(VOID) +STATIC INLINE VOID OsEnterSleepMode(VOID)//杩涘叆鐫$湢妯″紡锛屽寘鎷富鏍稿績鍜屽叾浠栨牳蹇冪殑涓嶅悓澶勭悊 { #ifdef LOSCFG_KERNEL_SMP UINT32 currCpuid = ArchCurrCpuid(); - if (currCpuid == 0) { + if (currCpuid == 0) { //濡傛灉鏄0鍒欒繘鍏ヤ富鏍稿績娣卞害鐫$湢 #endif OsEnterDeepSleepMainCore(); -#ifdef LOSCFG_KERNEL_SMP +#ifdef LOSCFG_KERNEL_SMP //濡傛灉褰撳墠鏍稿績涓嶆槸涓绘牳蹇冿紝鍒欑洿鎺ヨ繑鍥烇紝鍥犱负鍏朵粬鏍稿績鐨勭潯鐪犲鐞嗛昏緫涓嶅湪姝ゅ嚱鏁颁腑澶勭悊 return; } UINT32 cpuMask = 1 << currCpuid; LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1); - OsSRSaveRegister(); + OsSRSaveRegister();//淇濆瓨鐩稿叧瀵勫瓨鍣ㄧ姸鎬佸苟鍒ゆ柇鏄惁闇瑕佸敜閱掑綋鍓嶆牳蹇冦 if (g_pmMgr.resumeSleepCores & cpuMask) { INT32 val; - do { + do { //锛屽皢 g_pmMgr.resumeSleepCores 鐨勫间腑褰撳墠鏍稿績鐨勪綅娓呴浂锛岃〃绀鸿鏍稿績宸茶鍞ら啋銆 val = LOS_AtomicRead(&g_pmMgr.resumeSleepCores); } while (LOS_AtomicCmpXchg32bits(&g_pmMgr.resumeSleepCores, val & (~cpuMask), val)); g_deepSleepOps.otherCoreResume(); UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer(); OsTickResume(sleepTicks); + //鎵ц鍏朵粬鏍稿績鐨勬仮澶嶆搷浣滐紝骞朵粠鍞ら啋瀹氭椂鍣ㄤ腑鑾峰彇浼戠湢鏃堕棿锛岀劧鍚庤皟鐢 OsTickResume 鍑芥暟鏇存柊绯荤粺鏃堕挓銆 } else { - if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) { - LOS_MpSchedule(1 << 0); + if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) {//濡傛灉涓嶉渶瑕佸敜閱掞紝鍒欏垽鏂槸鍚︽墍鏈夋牳蹇冮兘杩涘叆浜嗘繁搴︾潯鐪 + LOS_MpSchedule(1 << 0);//璋冪敤鍑芥暟閫夋嫨涓涓牳蹇冨敜閱掔郴缁 } #ifdef LOSCFG_KERNEL_TICKLESS - OsTicklessOpen(); + OsTicklessOpen();//寮鍚妭鑳芥ā寮 #endif g_pmRunOps.enterLightSleep(); } - LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1); + LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);//灏 g_pmMgr.deepSleepCores 鐨勫煎噺1锛岃〃绀哄綋鍓嶆牳蹇冨凡缁忓鐞嗗畬鐫$湢鐘舵 #endif // LOSCFG_KERNEL_SMP } -STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode) +STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)//閫夋嫨鍚堥傜殑浣庡姛鑰楁ā寮忥紙娣卞害锛岃交搴 { // If enterShutdownMode is not defined, will fall through to standby mode // If enterStandbyMode is not defined, will fall through to stop mode @@ -402,10 +405,10 @@ STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode) } #endif -STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks) +STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)//杞诲害鐫$湢涓殑妯″紡璋冩暣 { if (g_pmRunOps.preConfig != NULL) { - sleepTicks = g_pmRunOps.getSleepTime(); + sleepTicks = g_pmRunOps.getSleepTime();//鑾峰彇浼戠湢鏃堕棿 } if (sleepTicks > 1) { g_pmMgr.sleepMode[cpuid] = (mode & 0x0FF); @@ -414,18 +417,19 @@ STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks) OsTicklessOpen(); #endif if (mode == LOS_INTERMIT_LIGHT_SLEEP && g_pmRunOps.enterLightSleep != NULL) { - g_pmRunOps.enterLightSleep(); + g_pmRunOps.enterLightSleep();//杩涘叆杞诲害鐫$湢 } else { wfi(); } } else { - g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE; + g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;//绛夊緟涓柇浜嬩欢 g_pmMgr.sleepTime[cpuid] = 0; wfi(); } } STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 sleepTicks) +//娣卞害鐫$湢璁剧疆 { #ifdef LOSCFG_KERNEL_DEEPSLEEP if (g_pmRunOps.enterDeepSleep == NULL) { @@ -438,27 +442,31 @@ STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 slee OsSystemSuspend(mode); } #else - *mode = LOS_INTERMIT_LIGHT_SLEEP; + *mode = LOS_INTERMIT_LIGHT_SLEEP;//鑻ヤ笉鏀寔娣卞害鐫$湢鍒欏己鍒惰繘鍏ヨ交搴︾潯鐪 #endif } -STATIC VOID OsLowpowerProcess(VOID) +STATIC VOID OsLowpowerProcess(VOID)//澶勭悊绯荤粺杩涘叆浣庡姛鑰楁ā寮忕殑杩囩▼ { -#ifdef LOSCFG_KERNEL_RUNSTOP +#ifdef LOSCFG_KERNEL_RUNSTOP//妫鏌ョ郴缁熸槸鍚﹂渶瑕佸湪杩涘叆浣庡姛鑰楁ā寮忓墠淇濆瓨绯荤粺娑堟伅 if (OsWowSysDoneFlagGet() == OS_STORE_SYSTEM) { OsStoreSystemInfoBeforeSuspend(); } #endif /* Change frequency is pended, need to change the freq here. */ - if ((g_pmRunOps.changeFreq != NULL)) { + if ((g_pmRunOps.changeFreq != NULL)) {//濡傛灉闇瑕佹敼鍙橀鐜囧垯璋冩暣鍒囨崲 OsChangeFreq(); } - + //绂佹涓柇锛岄攣浣忎换鍔¤皟搴︼紝骞惰幏鍙栧綋鍓岰PUID鍜屼紤鐪犳椂闂 UINT32 intSave = LOS_IntLock(); LOS_TaskLock(); RUNOPS_CALL_FUNC_VOID(preConfig); UINT32 cpuid = ArchCurrCpuid(); UINT32 sleepTicks = g_pmRunOps.getSleepTime(); + /*濡傛灉浼戠湢鏃堕棿灏忎簬绛変簬鏈灏忎紤鐪犳椂闂达紙g_pmMgr.minSleepTicks锛 + 鎴栬呮湁浠诲姟璇锋眰涓嶈繘鍏ユ繁搴︾潯鐪狅紙LOS_PowerMgrGetDeepSleepVoteCount 杩斿洖鍊间笉涓0锛夛紝 + 鍒欏皢褰撳墠 CPU 璁剧疆涓轰笉杩涘叆浠讳綍涓柇妯″紡锛屾竻闆朵紤鐪犳椂闂达紝 + 骞惰皟鐢 postConfig 鍑芥暟銆*/ if (sleepTicks <= g_pmMgr.minSleepTicks || LOS_PowerMgrGetDeepSleepVoteCount() != 0) { g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE; g_pmMgr.sleepTime[cpuid] = 0; @@ -477,23 +485,23 @@ STATIC VOID OsLowpowerProcess(VOID) sleepTicks = g_pmMgr.maxSleepCount; } UINT32 mode = g_pmRunOps.selectSleepMode(sleepTicks); - if (mode >= LOS_INTERMIT_DEEP_SLEEP) { + if (mode >= LOS_INTERMIT_DEEP_SLEEP) {//濡傛灉鏀寔娣卞害鐫$湢 g_pmMgr.sleepTime[cpuid] = g_pmRunOps.withdrawWakeUpTimer(); OsLowpowerDeepSleep(&mode, cpuid, sleepTicks); } RUNOPS_CALL_FUNC_VOID(postConfig); - if (mode < LOS_INTERMIT_DEEP_SLEEP) { + if (mode < LOS_INTERMIT_DEEP_SLEEP) {//杩涘叆杞诲害鐫$湢 OsLowpowerLightSleep(mode, cpuid, sleepTicks); } } LOS_TaskUnlock(); - LOS_IntRestore(intSave); + LOS_IntRestore(intSave);//瑙i攣浠诲姟璋冨害骞舵仮澶嶄腑鏂 } -STATIC VOID OsLowpowerWakeupFromReset(VOID) +STATIC VOID OsLowpowerWakeupFromReset(VOID)//澶勭悊绯荤粺浠庨噸缃姸鎬佸敜閱掔殑鎯呭喌 { #ifdef LOSCFG_KERNEL_RUNSTOP if (g_resumeFromImg == LOS_RUN_STOP_RESET) { @@ -508,7 +516,7 @@ STATIC VOID OsLowpowerWakeupFromReset(VOID) #endif } -STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum) +STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)//鐢ㄤ簬澶勭悊绯荤粺浠庨噸缃姸鎬佸敜閱掔殑鎯呭喌 { #ifdef LOSCFG_KERNEL_TICKLESS OsTicklessUpdate(intNum); @@ -517,26 +525,27 @@ STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum) #endif } -STATIC VOID OsChangeFreq(VOID) +STATIC VOID OsChangeFreq(VOID)//澶勭悊鏀瑰彉绯荤粺棰戠巼鐨勬搷浣 { UINT32 freq; BOOL ret; - do { + do {//灏濊瘯鑾峰彇棰戠巼鍒囨崲鐨勮嚜鏃嬮攣锛堥氳繃鍘熷瓙鎿嶄綔瀹炵幇锛 + //濡傛灉鎴愬姛鑾峰彇閿侊紝鍒欒鏄庢病鏈夊叾浠栫嚎绋嬫鍦ㄩ鐜囧垏鎹㈣繃绋嬩腑锛屽彲浠ョ户缁墽琛 ret = LOS_AtomicCmpXchg32bits(&g_pmMgr.freeLock, LOCK_ON, LOCK_OFF); if (ret) { return; } - freq = (UINT32)g_pmMgr.freqPending; + freq = (UINT32)g_pmMgr.freqPending;//鑾峰彇棰戠巼鍒囨崲鐨勭洰鏍囬鐜囷紝骞惰繘琛岄鐜囧垏鎹 if (freq != (UINT32)g_pmMgr.freq) { - g_pmRunOps.changeFreq(freq); + g_pmRunOps.changeFreq(freq);//鏇存柊棰戠巼 LOS_AtomicSet(&g_pmMgr.freq, (INT32)freq); } - LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF); + LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);//閲婃斁鑷棆閿 } while (FreqHigher(g_pmMgr.freqPending, freq)); } -STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq) +STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)//鏀瑰彉绯荤粺棰戠巼 { TRACE_FUNC_CALL(); if (g_pmRunOps.changeFreq == NULL) { @@ -554,36 +563,36 @@ STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq) // We get a high frequency request, then change it if (FreqHigher(g_pmMgr.freqPending, g_pmMgr.freq) && g_pmRunOps.changeFreq != NULL) { - OsChangeFreq(); + OsChangeFreq();//濡傛灉鐩爣棰戠巼楂樹簬褰撳墠棰戠巼锛屽苟涓 g_pmRunOps.changeFreq 涓嶄负绌猴紝鍒欒皟鐢 OsChangeFreq 鍑芥暟杩涜棰戠巼鍒囨崲銆 } } -STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID) +STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID)//寮濮嬫繁搴︾潯鐪犳姇绁 { TRACE_FUNC_CALL(); - LOS_AtomicInc(&g_pmMgr.sleepVoteCount); + LOS_AtomicInc(&g_pmMgr.sleepVoteCount);//鐢ㄥ師瀛愭搷浣滃皢 g_pmMgr.sleepVoteCount 鍔犱竴锛屽苟鏂█ g_pmMgr.sleepVoteCount 澶т簬闆躲 LOS_ASSERT(g_pmMgr.sleepVoteCount > 0); } -STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID) +STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID)//缁撴潫娣卞害鐫$湢鎶曠エ { TRACE_FUNC_CALL(); - LOS_AtomicDec(&g_pmMgr.sleepVoteCount); + LOS_AtomicDec(&g_pmMgr.sleepVoteCount);//鍘熷瓙鎿嶄綔灏 g_pmMgr.sleepVoteCount 鍑忎竴锛屽苟鏂█ g_pmMgr.sleepVoteCount 澶т簬绛変簬闆躲 LOS_ASSERT(g_pmMgr.sleepVoteCount >= 0); } -STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks) +STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks)//寤惰繜娣卞害鐫$湢鎶曠エ { TRACE_FUNC_CALL(); } -STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback) +STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback)//娉ㄥ唽澶栭儴鎶曠エ鑰 { TRACE_FUNC_CALL(); g_pmMgr.exVoterHandle = callback; } -STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID) +STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)//鑾峰彇娣卞害鐫$湢鎶曠エ鏁 { if (g_pmMgr.exVoterHandle == NULL) { return (UINT32)g_pmMgr.sleepVoteCount; @@ -593,22 +602,26 @@ STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID) } STATIC PowerMgrOps g_pmOps = { - .process = OsLowpowerProcess, - .wakeupFromReset = OsLowpowerWakeupFromReset, - .resumeFromInterrupt = OsLowpowerWakeupFromInterrupt, - .changeFreq = OsLowpowerChangeFreq, - .deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin, - .deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd, - .deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay, - .registerExternalVoter = OsLowpowerRegisterExternalVoter, - .getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount, - .getSleepMode = NULL, - .setSleepMode = NULL, + .process = OsLowpowerProcess, //璇ュ嚱鏁版寚閽堢敤浜庡鐞嗕綆鍔熻楄繃绋嬶紝鍗冲湪杩涘叆浣庡姛鑰楁ā寮忓墠闇瑕佹墽琛岀殑鎿嶄綔 + .wakeupFromReset = OsLowpowerWakeupFromReset,//璇ュ嚱鏁版寚閽堢敤浜庡鐞嗕粠澶嶄綅鐘舵佸敜閱掓椂鐨勬搷浣 + .resumeFromInterrupt = OsLowpowerWakeupFromInterrupt,//璇ュ嚱鏁版寚閽堢敤浜庡鐞嗕粠涓柇鐘舵佹仮澶嶆椂鐨勬搷浣溿 + .changeFreq = OsLowpowerChangeFreq,//璇ュ嚱鏁版寚閽堢敤浜庢敼鍙樼郴缁熼鐜囩殑鎿嶄綔锛屽彲浠ユ牴鎹渶瑕佽皟鏁寸郴缁熺殑宸ヤ綔棰戠巼 + .deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin,//璇ュ嚱鏁版寚閽堢敤浜庡紑濮嬫繁搴︿紤鐪犳姇绁紝鍗冲湪杩涘叆娣卞害浼戠湢妯″紡鍓嶉渶瑕佹墽琛岀殑鎿嶄綔 + .deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd,//璇ュ嚱鏁版寚閽堢敤浜庣粨鏉熸繁搴︿紤鐪犳姇绁紝鍗冲湪閫鍑烘繁搴︿紤鐪犳ā寮忓悗闇瑕佹墽琛岀殑鎿嶄綔 + .deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay,//璇ュ嚱鏁版寚閽堢敤浜庡鐞嗘繁搴︿紤鐪犳姇绁ㄥ欢杩熺殑鎿嶄綔锛屽彲浠ユ牴鎹渶瑕佸欢杩熸繁搴︿紤鐪犵殑鎶曠エ + .registerExternalVoter = OsLowpowerRegisterExternalVoter,//璇ュ嚱鏁版寚閽堢敤浜庢敞鍐屽閮ㄦ姇绁ㄨ咃紝鍗冲湪绯荤粺涓瓨鍦ㄥ叾浠栨ā鍧椾篃闇瑕佸弬涓庝綆鍔熻楁姇绁ㄦ椂鐨勬搷浣 + .getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount,//璇ュ嚱鏁版寚閽堢敤浜庤幏鍙栧綋鍓嶆繁搴︿紤鐪犳姇绁ㄧ殑鏁伴噺锛屽彲浠ョ敤鏉ョ洃鎺х郴缁熶腑鍙備笌浼戠湢鎶曠エ鐨勬ā鍧楁暟閲 + .getSleepMode = NULL,//璇ュ嚱鏁版寚閽堢敤浜庤幏鍙栧綋鍓嶇殑鐫$湢妯″紡锛屽嵆鑾峰彇绯荤粺褰撳墠鏄惁澶勪簬鐫$湢鐘舵 + .setSleepMode = NULL,//璇ュ嚱鏁版寚閽堢敤浜庤缃潯鐪犳ā寮忥紝鍗冲皢绯荤粺璁剧疆涓烘寚瀹氱殑鐫$湢妯″紡 + //浠ヤ笂鎻愬強鐨勫嚱鏁板潎涓哄嚱鏁版寚閽 }; #define FORCE_NULL_CALLBACK (void *)0x3f3f3f3f - -#define ASSIGN_MEMBER(lhs, rhs, member) \ +//浠ヤ笅瀹氫箟鏄敤浜庣粰缁撴瀯浣撴垚鍛樿祴鍊硷紝濡傛灉鏌愪釜鍥炶皟鍑芥暟鎸囬拡涓虹壒娈婄┖鍊硷紝鍒欏皢鐩稿簲鐨勬垚鍛樼疆涓虹┖锛屽惁鍒欒繘琛岃祴鍊 +#define ASSIGN_MEMBER(lhs, rhs, member) +//lhs 鏄乏鎿嶄綔鏁帮紝琛ㄧず瑕佽祴鍊肩殑缁撴瀯浣撴寚閽堬紱 +//rhs 鏄彸鎿嶄綔鏁帮紝琛ㄧず瑕佽祴缁欐垚鍛樼殑鍊硷紱 +//member 鏄璧嬪肩殑缁撴瀯浣撴垚鍛 do { \ if ((rhs)->member == FORCE_NULL_CALLBACK) { \ (lhs)->member = NULL; \ @@ -631,16 +644,16 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para) const PowerMgrRunOps *runOps = NULL; const PowerMgrDeepSleepOps *deepSleepOps = NULL; (void)deepSleepOps; - if (para != NULL) { + if (para != NULL) { //濡傛灉para涓虹┖锛屽垯杩愯鎿嶄綔鍜屾繁搴︾潯鐪犳搷浣滈兘涓虹┖鎸囬拡 runOps = ¶->runOps; #ifdef LOSCFG_KERNEL_DEEPSLEEP deepSleepOps = ¶->deepSleepOps; #endif - g_pmMgr.minSleepTicks = para->config.minLightSleepTicks; - g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks; - g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks; + g_pmMgr.minSleepTicks = para->config.minLightSleepTicks;//璁板綍浜嗙郴缁熶腑闇瑕佷粠鐫$湢鐘舵佸敜閱掔殑 CPU 鏍稿績鏁 + g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks;//鐢ㄤ簬淇濇姢鐢垫簮绠$悊妯″潡鍦ㄥ绾跨▼鐜涓嬬殑骞跺彂璁块棶 + g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks;//璁板綍鑷棆閿佹槸鍚﹁閲婃斁 } - + //灏嗕紶鍏ョ殑杩愯鎿嶄綔鍜屾繁搴︾潯鐪犳搷浣滃垎鍒祴鍊肩粰鍏ㄥ眬鍙橀噺 g_pmRunOps 鍜 g_deepSleepOps LOS_AtomicSet(&g_pmMgr.resumeSleepCores, 0); LOS_SpinInit(&g_pmMgr.lock); @@ -648,25 +661,25 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para) // verify and assign input operators. if (runOps != NULL) { - ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq); - ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep); + ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq);//鏀瑰彉CPU棰戠巼 + ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep);//杩涘叆娴呭害鐫$湢 #ifdef LOSCFG_KERNEL_DEEPSLEEP - ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep); - ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer); - ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer); + ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep);//杩涘叆娣卞害鐫$湢 + ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer);//璁剧疆鍞ら啋瀹氭椂鍣 + ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer);//鎾ら攢瀹氭椂鍣 #else ASSIGN_MEMBER(&g_pmRunOps, runOps, enterDeepSleep); ASSIGN_MEMBER(&g_pmRunOps, runOps, setWakeUpTimer); ASSIGN_MEMBER(&g_pmRunOps, runOps, withdrawWakeUpTimer); #endif - ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime); - ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode); - ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig); - ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig); + ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime);//璐х殑鐫$湢鏃堕棿 + ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode);//閫夋嫨涓嶅悓鐨勭潯鐪犳ā寮 + ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig);//棰勯厤缃 + ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig);//鍚庨厤缃 } #ifdef LOSCFG_KERNEL_DEEPSLEEP - if (deepSleepOps != NULL) { + if (deepSleepOps != NULL) {//杩涘叆娣卞害鐫$湢 ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, couldDeepSleep); ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, systemWakeup); ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, suspendPreConfig); @@ -680,4 +693,7 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para) #endif // Register PowerMgr to Low-Power Framework. LOS_LowpowerInit(&g_pmOps); + //灏嗙數婧愮鐞嗘ā鍧楁敞鍐屽埌浣庡姛鑰楁鏋朵腑銆 + //浣庡姛鑰楁鏋舵槸涓涓敤浜庣鐞嗗鐞嗗櫒鍜岃澶囪繘鍏ヤ綆鍔熻楁ā寮忕殑杞欢妗嗘灦锛 + //瀹冭兘澶熸渶澶ч檺搴﹀湴闄嶄綆绯荤粺鑳借楋紝鎻愰珮绯荤粺鐨勭數姹犲鍛 } diff --git a/src/kernel/extended/lowpower/runstop/src/los_runstop.c b/src/kernel/extended/lowpower/runstop/src/los_runstop.c index 0da74e3..f529d6a 100644 --- a/src/kernel/extended/lowpower/runstop/src/los_runstop.c +++ b/src/kernel/extended/lowpower/runstop/src/los_runstop.c @@ -51,22 +51,28 @@ extern "C" { /* If core is ready for imaging */ LITE_OS_SEC_DATA_MINOR STATIC UINT32 g_sysDoneFlag[LOSCFG_KERNEL_CORE_NUM] = { [0 ... (LOSCFG_KERNEL_CORE_NUM - 1)] = OS_NO_STORE_SYSTEM -}; +}; /*鏍囪鏁扮粍鐘舵侊紝鐢ㄦ潵琛ㄧず绯荤粺鏄惁鍔犺浇瀹屾垚*/ /* Start position of flash to write image */ LITE_OS_SEC_DATA_MINOR STATIC UINTPTR g_flashImgAddr; +/*flash鍥惧儚鍦板潃鍜屽ぇ灏忥紝鐢ㄤ簬瀛樺偍flash鐩稿叧淇℃伅銆*/ /* Start position of heap memory after carry the image from flash to memory */ LITE_OS_SEC_DATA_MINOR STATIC const VOID *g_heapMemStart = NULL; +/*鍒濆鍖栧浘鍍忓湴鍧*/ /* Size of heap memory in image */ LITE_OS_SEC_DATA_MINOR STATIC size_t g_heapMemSize = 0; +/*鍒濆鍖栧畾涔夊浘鍍忓ぇ灏*/ + #ifdef LOSCFG_EXC_INTERACTION /* Start position of exc interaction heap memory after carry the image from flash to memory */ LITE_OS_SEC_DATA_MINOR STATIC const VOID *g_excInteractionMemStart = NULL; +/*鍦ㄥ瓨鍌ㄥ櫒鏄犲儚浠庨棯瀛樺鍒跺埌鍐呭瓨涔嬪悗寮傚父浜や簰鍫嗙殑璧峰浣嶇疆鍙橀噺*/ /* Size of exc interaction heap memory in image */ LITE_OS_SEC_DATA_MINOR STATIC size_t g_excInteractionMemSize = 0; +/*寮傚父浜や簰鍫嗗唴瀛樺湪鍌ㄥ瓨鍣ㄦ槧鍍忎腑鐨勫ぇ灏*/ #endif /* Size of wow image */ LITE_OS_SEC_DATA_MINOR STATIC size_t g_wowImgSize = 0; @@ -76,15 +82,17 @@ LITE_OS_SEC_DATA_MINOR STATIC EVENT_CB_S g_suspendResumeEvent; LITE_OS_SEC_DATA_MINOR STATIC EVENT_CB_S g_writeFlashEvent; typedef struct { - UINTPTR memStart; - UINTPTR flashStart; - size_t memSize; + UINTPTR memStart; /*鍐呭瓨璧峰鍦板潃*/ + UINTPTR flashStart; /*闂瓨璧峰鍦板潃*/ + size_t memSize; /*瀛樺偍绌洪棿澶у皬*/ } FlashWriteParam; BOOL IsImageResume(VOID) { return (g_resumeFromImg != LOS_COLD_RESET); } +/*鍒ゆ柇绯荤粺鏄惁浠庡瓨鍌ㄥ櫒鏄犲儚涓仮澶嶇殑锛屽姛鑳芥槸褰撶郴缁熷紓甯稿惎鍔ㄦ垨鑰呴渶瑕侀噸鍚殑鏃跺欏氨浼氫粠鍐呭瓨灏嗗叾鏁版嵁淇濆瓨鍒伴棯瀛樹腑 +姝ゅ嚱鏁板氨鏄垽鏂郴缁熸槸鍚︽槸浠庡瓨鍌ㄥ櫒鏄犲儚鍥炲鐨勶紝浠庤岀‘瀹氭槸鍚﹂渶瑕佸绯荤粺鐘舵佽繘琛屾仮澶*/ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsDoWriteWow2Flash(FLASH_WRITE_FUNC flashWriteFunc, const FlashWriteParam *wowSection, @@ -109,29 +117,32 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsDoWriteWow2Flash(FLASH_WRITE_FUNC flashWrit return; } } - -LITE_OS_SEC_TEXT_MINOR VOID OsWriteWow2Flash(VOID) +/*棣栧厛妫鏌ュ唴瀛樹腑鐨勫ぇ灏忔槸鍚︿负0 +鑻ヤ笉涓0鍒欏皢wowsection銆乪xcheapsection銆乭eapmemsection涓殑闈欐佹暟鎹拰浠g爜瀛樺偍鍦ㄧ郴缁熷惎鍔ㄧ殑鏃跺欏皢鍏朵粠闂瓨鍔犲叆鍒板唴瀛樹腑*/ +LITE_OS_SEC_TEXT_MINOR VOID OsWriteWow2Flash(VOID) /*鏍规嵁鎸囧畾鐨勫唴瀛樺尯鍩燂紝鍦ㄩ棯瀛樹腑鍐欏叆鐩稿簲鐨勬暟鎹紝瀹屾垚鍐欏叆鎿嶄綔*/ { FlashWriteParam wowSection; FlashWriteParam excHeapSection = {0}; - FlashWriteParam heapMemSection; - size_t eraseAlignSize; - size_t writeAlignSize; + FlashWriteParam heapMemSection; /*杩欐槸涓夌闂瓨鍐呴儴鐙珛鐨勫爢涓撶敤鐨勫唴瀛樺尯鍩熷搴旂殑闂瓨鍐欏叆鍙傛暟*/ + size_t eraseAlignSize; /*琛ㄧず闂瓨鎿﹂櫎鏃剁殑瀵归綈澶у皬*/ + size_t writeAlignSize; /*闂瓨鍐欏叆鏃剁殑瀵归綈澶у皬*/ FLASH_WRITE_FUNC flashWriteFunc = g_runstopParam.pfFlashWriteFunc; - eraseAlignSize = g_runstopParam.uwFlashEraseAlignSize; - writeAlignSize = g_runstopParam.uwFlashWriteAlignSize; + eraseAlignSize = g_runstopParam.uwFlashEraseAlignSize; /*鐢ㄦ潵鎸囧畾鎿﹂櫎鍜屽啓鍏ユ椂鐨勫榻愬ぇ灏忥紝閫氬父璁剧疆涓烘墖鍖哄ぇ灏忕殑鏁存暟鍊*/ + writeAlignSize = g_runstopParam.uwFlashWriteAlignSize; /*涓轰簡閬垮厤鍑虹幇鎿﹂櫎鎴栧啓鍏ヤ笉瑙勫垯鏁版嵁鐨勬儏鍐碉紝 + 闇瑕佸皢鎿嶄綔鐨勫湴鍧鍚戜笅鎴栧悜涓婅垗鍏ュ埌鎵囧尯澶у皬鐨勬暣鏁板 + 浠庤岄伩鍏嶅洜涓轰笉瑙勫垯鐨勬搷浣滆屽鑷存暟鎹殑閿欒鎴栨崯鍧忋*/ writeAlignSize = (writeAlignSize >= eraseAlignSize) ? writeAlignSize : eraseAlignSize; if (flashWriteFunc == NULL) { PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); return; } - wowSection.memStart = (UINTPTR)&__ram_vectors_vma; - wowSection.flashStart = g_flashImgAddr; + wowSection.memStart = (UINTPTR)&__ram_vectors_vma;/*鍒濆鍖杦owSection锛屼负鍐呭瓨涓捣濮嬪湴鍧*/ + wowSection.flashStart = g_flashImgAddr; /*涓洪棯瀛樹腑璧峰鍦板潃*/ wowSection.memSize = ((UINTPTR)&__wow_end) - ((UINTPTR)&__ram_vectors_vma); wowSection.memSize = (wowSection.memSize + writeAlignSize - 1) & ~(writeAlignSize - 1); - + /*璁$畻浜唚owSection澶у皬锛岄氳繃涓庤繍绠椾繚璇佹瘡娆″啓鍏ョ殑鏁版嵁閮芥槸鏁翠釜鎵囧尯鐨勫嶆暟*/ #ifdef LOSCFG_EXC_INTERACTION excHeapSection.memStart = (UINTPTR)m_aucSysMem0; excHeapSection.flashStart = g_flashImgAddr + wowSection.memSize; @@ -152,39 +163,41 @@ LITE_OS_SEC_TEXT_MINOR VOID OsWriteWow2Flash(VOID) g_wowImgSize = wowSection.memSize + heapMemSection.memSize + excHeapSection.memSize; OsDoWriteWow2Flash(flashWriteFunc, &wowSection, &excHeapSection, &heapMemSection); + /*灏嗗彉閲忎紶杈撶粰鍑芥暟锛岀敱鍏跺疄鐜扮浉搴旂殑鍐欏叆鎿嶄綔*/ } -LITE_OS_SEC_TEXT_MINOR VOID OsSystemSuspend(VOID) +LITE_OS_SEC_TEXT_MINOR VOID OsSystemSuspend(VOID) /*瀹炵幇绯荤粺鐨勬寕璧锋搷浣*/ { - UINT32 cpuid; + UINT32 cpuid; /*鑾峰彇褰撳墠CPU鐨処D*/ - (VOID)LOS_IntLock(); + (VOID)LOS_IntLock(); LOS_TaskLock(); cpuid = ArchCurrCpuid(); + /*绂佹涓柇骞堕攣瀹氫换鍔¤皟搴﹀櫒锛岀‘淇濆湪鎵ц鎸傝捣鎿嶄綔鏈熼棿涓嶄細琚墦鏂*/ + g_sysDoneFlag[cpuid] = OS_NO_STORE_SYSTEM; /*灏嗗綋鍓岰PU鐨勭郴缁熸寕璧锋爣蹇楄缃负涓嶉渶瑕佷繚瀛樼郴缁熺姸鎬*/ + g_saveTsk[cpuid] = OsCurrTaskGet(); /*淇濆瓨褰撳墠浠诲姟鎸囬拡鍒皊avetask鍙橀噺涓*/ - g_sysDoneFlag[cpuid] = OS_NO_STORE_SYSTEM; - g_saveTsk[cpuid] = OsCurrTaskGet(); - - OsSRSaveRegister(); + OsSRSaveRegister(); /*淇濆瓨褰撳墠CPU鐨勫瘎瀛樺櫒鐘舵侊紝浠ヤ究鍦ㄦ仮澶嶇郴缁熸椂鑳藉姝g‘鎭㈠鍒版寕璧峰墠鐨勭姸鎬*/ /* If 1 core, only to save registers */ - if (cpuid != 0) { - if (g_otherCoreResume != 0) { + if (cpuid != 0) { /*鑻ユCPU閮ㄤ綅0鍙峰唴鏍*/ + if (g_otherCoreResume != 0) { /*璇存槑鍏朵粬澶氭牳鏍稿績闇瑕佹仮澶嶈繍琛*/ HalIrqInitPercpu(); OsTickStart(); LOS_TaskUnlock(); (VOID)LOS_IntUnLock(); - return; + return; } - g_sysDoneFlag[cpuid - 1] = OS_STORE_SYSTEM; + g_sysDoneFlag[cpuid - 1] = OS_STORE_SYSTEM; /*闇瑕佸垵濮嬪寲涓柇骞跺惎鍔ㄧ郴缁熸椂閽燂紝骞舵渶缁堣В閿佷换鍔¤皟搴﹀櫒骞舵仮澶嶄腑鏂*/ while (1) {} } - if (g_resumeFromImg) { + if (g_resumeFromImg) { /*濡傛灉鏄 0 鍙 CPU锛屼笖绯荤粺闇瑕佷粠闀滃儚涓仮澶嶏紙g_resumeFromImg 涓虹湡锛*/ OsWriteWow2Flash(); LOS_TaskUnlock(); (VOID)LOS_IntUnLock(); (VOID)LOS_EventWrite(&g_suspendResumeEvent, FLASH_IMG_SUCCESS); - } else { + /*璋冪敤 OsWriteWow2Flash 鍑芥暟灏嗘暟鎹啓鍏ラ棯瀛橈紝骞跺彂閫 FLASH_IMG_SUCCESS 浜嬩欢淇″彿锛岃〃绀烘垚鍔熶粠闀滃儚涓仮澶*/ + } else { /*涓嶉渶瑕佷粠闀滃儚涓仮澶*/ OsTickStart(); LOS_TaskUnlock(); (VOID)LOS_IntUnLock(); @@ -194,9 +207,15 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemSuspend(VOID) } (VOID)LOS_EventWrite(&g_suspendResumeEvent, WAKEUP_FROM_SUSPEND); } + /*鍚姩绯荤粺鏃堕挓锛岃В閿佷换鍔¤皟搴﹀櫒鍜屼腑鏂紝骞舵牴鎹槸鍚﹁缃簡绌洪棽鍞ら啋鍥炶皟鍑芥暟鏉ユ墽琛岀浉搴旂殑鎿嶄綔锛 + 鏈鍚庡彂閫 WAKEUP_FROM_SUSPEND 浜嬩欢淇″彿锛岃〃绀轰粠鎸傝捣鐘舵佸敜閱*/ } LITE_OS_SEC_TEXT VOID OsWriteToFlashTask(VOID) +/*鍒濆鍖栦簡涓涓簨浠跺璞 g_writeFlashEvent +骞朵笖鍦ㄥ惊鐜腑璋冪敤 LOS_EventRead 鍑芥暟绛夊緟浜嬩欢鐨勫彂鐢燂紝 +骞朵互 OR 妯″紡鍜屾竻闄ゆā寮忕瓑寰呬簨浠剁殑鏍囧織浣嶄负 0x01銆 +涓鏃︿簨浠跺彂鐢燂紝瀹冭皟鐢 OsSystemSuspend 鍑芥暟灏嗙郴缁熸寕璧枫*/ { (VOID)LOS_EventInit(&g_writeFlashEvent); @@ -207,6 +226,10 @@ LITE_OS_SEC_TEXT VOID OsWriteToFlashTask(VOID) } LITE_OS_SEC_TEXT VOID OsStoreSystemInfoBeforeSuspend(VOID) +/*鏍规嵁褰撳墠 CPU 鐨 ID 鍒ゆ柇鏄惁闇瑕佹寕璧风郴缁熴 +濡傛灉褰撳墠 CPU 涓嶆槸 0 鍙 CPU锛岀洿鎺ヨ皟鐢 OsSystemSuspend 鍑芥暟鎸傝捣绯荤粺銆 +濡傛灉鏄 0 鍙 CPU锛屽垯璋冪敤 LOS_EventWrite 鍑芥暟鍚戜簨浠跺璞 g_writeFlashEvent 鍙戦佷竴涓簨浠讹紝 +鍞ら啋 OsWriteToFlashTask 浠诲姟鏉ユ墽琛屾寕璧锋搷浣溿*/ { UINT32 cpuid = ArchCurrCpuid(); if (cpuid != 0) { @@ -218,6 +241,9 @@ LITE_OS_SEC_TEXT VOID OsStoreSystemInfoBeforeSuspend(VOID) } LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID) +/*鏄郴缁熶粠鎸傝捣鐘舵佸敜閱掑悗鐨勫鐞嗗嚱鏁般*/ + + { UINT32 cpuid; errno_t err; @@ -225,7 +251,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID) if (!g_resumeFromImg) { return; } - +/*杩涜涓浜涘唴瀛樻暟鎹殑澶嶅埗鎿嶄綔锛岀劧鍚庤缃綋鍓 CPU 鐨勪换鍔℃寚閽堬紝*/ #ifdef LOSCFG_EXC_INTERACTION err = memmove_s(m_aucSysMem0, g_excInteractMemSize, g_excInteractionMemStart, g_excInteractionMemSize); if (err != EOK) { @@ -243,6 +269,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID) cpuid = ArchCurrCpuid(); OsCurrTaskSet(g_saveTsk[cpuid]); +/*璁剧疆绯荤粺璁℃暟鍣ㄩ鐜囥傛帴鐫锛屽畠閲嶇疆鍐呭瓨姹犵殑鏈熬鑺傜偣锛屾竻闆 BSS 鍖哄煙鐨勬暟鎹紝閲嶆柊鍒濆鍖栦腑鏂*/ /* Set system counter freq */ HalClockFreqWrite(OS_SYS_CLOCK); dsb(); @@ -270,7 +297,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID) #ifdef LOSCFG_KERNEL_CPUP OsSetCpuCycle(0); #endif - +/*骞惰皟鐢 OsSRRestoreRegister 鍑芥暟鎭㈠瀵勫瓨鍣ㄧ姸鎬*/ #if (LOSCFG_KERNEL_SMP == YES) release_secondary_cores(); #endif @@ -281,32 +308,33 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsWaitImagingDone(UINTPTR wowFlashAddr, size_t *wo { UINT32 ret; - g_flashImgAddr = wowFlashAddr; - (VOID)LOS_EventInit(&g_suspendResumeEvent); + g_flashImgAddr = wowFlashAddr; /*鐑у綍鐨刦lash鍦板潃*/ + (VOID)LOS_EventInit(&g_suspendResumeEvent); /*鎸囧悜鐢ㄤ簬瀛樺偍鐑у綍闀滃儚澶у皬鐨勫彉閲忕殑鎸囬拡*/ - // This flag will be stored into flash, and will affect the wakeup procedure when cpu is rebooting. + // 杩欎釜鏍囧織灏嗚瀛樺偍鍒伴棯瀛樹腑锛屽綋 CPU 閲嶆柊鍚姩鏃讹紝瀹冨皢褰卞搷鍞ら啋娴佺▼銆 g_resumeFromImg = LOS_RUN_STOP_RESET; - // This flag affects the suspending procedure later, - // and will be reset depending on 'g_resumeFromImg' when cpu is rebooting. + // 杩欎釜鏍囧織浼氬奖鍝嶄箣鍚庣殑鎸傝捣杩囩▼锛屽苟涓斿湪 CPU 閲嶆柊鍚姩鏃舵牴鎹 'g_resumeFromImg' 鐨勫艰繘琛岄噸缃 g_otherCoreResume = 0; - g_sysDoneFlag[LOSCFG_KERNEL_CORE_NUM - 1] = OS_STORE_SYSTEM; + g_sysDoneFlag[LOSCFG_KERNEL_CORE_NUM - 1] = OS_STORE_SYSTEM; /*琛ㄧず绯荤粺鐘舵侀渶瑕佽淇濆瓨*/ ret = LOS_EventRead(&g_suspendResumeEvent, 0xFF, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + /*绛夊緟浜嬩欢鍙戠敓*/ if (wowImgSize != NULL) { *wowImgSize = g_wowImgSize; - } + }/*淇濊瘉鑳藉鍦ㄧ儳褰曞畬鎴愪箣鍚庢纭殑淇濆瓨鍜屾仮澶嶇姸鎬*/ return ret; } -LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID) +LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID) /*灏嗕綅浜嶳AM鐨勬暟鎹粠鎸囧畾浣嶇疆澶嶅埗鍒癋lash瀛樺偍鍣ㄤ腑*/ { size_t size; UINTPTR memAddr; - size_t wowSize; - size_t readAlignSize; - size_t eraseAlignSize; - size_t writeAlignSize; + size_t wowSize;/*绛夊緟澶嶅埗鏁版嵁鐨勫ぇ灏*/ + size_t readAlignSize;/*璇诲彇瀵归綈澶у皬*/ + size_t eraseAlignSize;/*鎿﹂櫎瀵归綈澶у皬*/ + size_t writeAlignSize;/*鍐欏叆瀵归綈澶у皬*/ + /*璇诲彇鎵鏈夊弬鏁扮殑鍒濆鐘舵*/ UINTPTR imageFlashAddr; FLASH_READ_FUNC flashReadFunc = g_runstopParam.pfFlashReadFunc; @@ -315,18 +343,19 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID) eraseAlignSize = g_runstopParam.uwFlashEraseAlignSize; writeAlignSize = g_runstopParam.uwFlashWriteAlignSize; writeAlignSize = (writeAlignSize >= eraseAlignSize) ? writeAlignSize : eraseAlignSize; - + /*璁$畻wowsize鐨勫ぇ灏忥紝鏍规嵁瀵归綈澶у皬璋冩暣鍊*/ wowSize = ((UINTPTR)&__wow_end) - ((UINTPTR)&__ram_vectors_vma); wowSize = (wowSize + writeAlignSize - 1) & ~(writeAlignSize - 1); imageFlashAddr += wowSize; - + /*妫鏌emaddr鏄惁瓒呭嚭浜咮SS娈电殑璧峰鍦板潃*/ memAddr = ((UINTPTR)&__ram_vectors_vma) + wowSize; if (memAddr >= ((UINTPTR)&__bss_start)) { return; } + /*璁$畻浜嗚澶嶅埗鐨勬暟鎹ぇ灏忥紝鍦ㄧ鐩樹腑鏍规嵁瀵归綈澶у皬璋冩暣size*/ size = ((UINTPTR)&__int_stack_start) - memAddr; size = (size + readAlignSize - 1) & ~(readAlignSize - 1); - + /*灏哛AM涓殑鏁版嵁浠巑emaddr澶嶅埗鍒癴lash瀛樺偍鍣ㄧ殑imageflashaddr锛岃繘琛岀紦瀛樺拰鍚屾鎿嶄綔*/ if ((flashReadFunc != NULL) && (flashReadFunc((VOID *)memAddr, imageFlashAddr, size) != 0)) { PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); } @@ -336,6 +365,8 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID) } LITE_OS_SEC_TEXT_MINOR VOID OsRunstopParamInit(const RUNSTOP_PARAM_S *runstopParam) +/*鍒濆鍖栬繍琛屾殏鍋滃姛鑳芥墍闇鐨勫弬鏁帮紝淇濆瓨鍦ㄥ叏灞鍙橀噺g_涓紝浠ヤ究鍛婅瘔璁$畻鏈虹洰鍓嶇殑绯荤粺杞彴 +鍖呭惈浜嗚繍琛屾殏鍋滃姛鑳芥墍闇鐨勫悇涓洖璋冨嚱鏁板拰瀵归綈澶у皬绛夊弬鏁*/ { g_runstopParam.pfIdleWakeupCallback = runstopParam->pfIdleWakeupCallback; g_runstopParam.pfWakeupCallback = runstopParam->pfWakeupCallback; @@ -350,28 +381,31 @@ LITE_OS_SEC_TEXT_MINOR VOID OsRunstopParamInit(const RUNSTOP_PARAM_S *runstopPar } LITE_OS_SEC_TEXT_MINOR VOID LOS_MakeImage(RUNSTOP_PARAM_S *runstopParam) +/*鐢ㄤ簬闄ゆ硶杩愯鏆傚仠鍔熻兘鐨勬搷浣滐紝骞舵牴鎹繑鍥炲艰繘琛岀浉搴斿鐞*/ { UINT32 ret; size_t imgSize; - + /*妫鏌ユ槸鍚﹂渶瑕佹殏鍋*/ if (runstopParam == NULL) { return; } + /*璋冪敤鍑芥暟锛屽皢浼犲叆鐨剅unstopparam杞崲涓哄叏灞鍙橀噺*/ OsRunstopParamInit(runstopParam); ret = OsWaitImagingDone(g_runstopParam.uwWowFlashAddr, &imgSize); - if (ret == WAKEUP_FROM_SUSPEND) { + /*鐢ㄤ簬绛夊緟鍥惧儚杞Щ瀹屾垚锛岃寖鍥寸浉搴旂殑鐘舵佺爜ret鍜屽浘鍍忓ぇ灏廼mgsize*/ + if (ret == WAKEUP_FROM_SUSPEND) { /*浠庢殏鍋滅姸鎬佸敜閱掞紝骞舵煡鐪嬬郴缁熸槸鍚﹂渶瑕佺┖闂插敜閱掑洖璋*/ if (g_runstopParam.pfWakeupCallback != NULL) { g_runstopParam.pfWakeupCallback(); } - OsCarryLeftScatter(); + OsCarryLeftScatter(); /*灏哛AM涓殑鏁版嵁澶嶅埗鍒癋lash瀛樺偍鍣*/ PRINT_INFO("Resume ok!\n"); - } else if (ret == FLASH_IMG_SUCCESS) { + } else if (ret == FLASH_IMG_SUCCESS) { /*闂瓨鍥惧儚鎴愬姛*/ if (g_runstopParam.pfImageDoneCallback != NULL) { g_runstopParam.pfImageDoneCallback(); } - PRINT_INFO("Flash ok! Image length 0x%x\n", imgSize); + PRINT_INFO("Flash ok! Image length 0x%x\n", imgSize);/*鍥惧儚杞Щ鎴愬姛锛屽苟鎵撳嵃鍥惧儚澶у皬*/ } } @@ -380,8 +414,9 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsWowWriteFlashTaskCreate(VOID) UINT32 ret; UINT32 writeFlashTaskId; TSK_INIT_PARAM_S taskInitParam; - + /*棣栧厛瀵逛换鍔″垵濮嬪寲鍙傛暟杩涜浜嗘竻闆舵搷浣*/ (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + /*璁剧疆浜嗕换鍔″叆鍙e嚱鏁帮紝骞朵笖鍒跺畾浜嗕换鍔$殑鍫嗘爤澶у皬锛屼换鍔″悕鍜屼紭鍏堢骇*/ taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsWriteToFlashTask; taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; taskInitParam.pcName = "WowWriteFlashTask"; @@ -389,24 +424,28 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsWowWriteFlashTaskCreate(VOID) #ifdef LOSCFG_KERNEL_SMP taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(0); #endif + /*鍒涘缓浠诲姟锛岃繑鍥炵粨鏋*/ ret = LOS_TaskCreate(&writeFlashTaskId, &taskInitParam); return ret; } LITE_OS_SEC_TEXT_MINOR size_t OsWowImageSizeGet(VOID) +/*鑾峰彇wow鍥惧儚鐨勫ぇ灏忥紝杩斿洖鍏ㄥ眬鍙橀噺*/ { return g_wowImgSize; } LITE_OS_SEC_TEXT_MINOR UINT32 OsWowSysDoneFlagGet(VOID) +/*鑾峰彇wow绯荤粺瀹屾垚鐨勬爣蹇*/ { UINT32 cpuid = ArchCurrCpuid(); return g_sysDoneFlag[cpuid]; } LITE_OS_SEC_TEXT_MINOR VOID OsWowOtherCoreResume(UINT32 cpuid) +/*鍞ら啋鍏朵粬鐨勬牳蹇*/ { - if (g_otherCoreResume == 1) { + if (g_otherCoreResume == 1) { /*鍏ㄥ眬鍙橀噺鐨勫间负1鍒欒〃绀洪渶瑕佸敜閱掑叾浠栨牳蹇*/ OsCurrTaskSet(g_saveTsk[cpuid]); OsSRRestoreRegister(); } diff --git a/src/kernel/extended/lowpower/tickless/los_tickless.c b/src/kernel/extended/lowpower/tickless/los_tickless.c index fdeb5b8..d609b1e 100644 --- a/src/kernel/extended/lowpower/tickless/los_tickless.c +++ b/src/kernel/extended/lowpower/tickless/los_tickless.c @@ -46,42 +46,46 @@ STATIC volatile UINT32 g_sleepTicks[LOSCFG_KERNEL_CORE_NUM] = {0}; (((GET_SYS_CLOCK()) / (g_tickPerSecond)) - (cyclesCur)) : \ ((((GET_SYS_CLOCK()) / (g_tickPerSecond)) << 1) - (cyclesCur))) -LITE_OS_SEC_TEXT VOID LOS_TicklessEnable(VOID) +LITE_OS_SEC_TEXT VOID LOS_TicklessEnable(VOID) /*寮鍚疶ickless鍔熻兘*/ { g_ticklessFlag = TRUE; + /*鍙橀噺琛ㄧずTickless鍔熻兘鐨勫紑鍚姸鎬侊紝涓篢RUE琛ㄧず宸插紑鍚紝涓篎ALSE琛ㄧず宸插叧闂*/ } -LITE_OS_SEC_TEXT VOID LOS_TicklessDisable(VOID) +LITE_OS_SEC_TEXT VOID LOS_TicklessDisable(VOID) /*寮鍚疶ickless鍔熻兘*/ { g_ticklessFlag = FALSE; } -LITE_OS_SEC_TEXT BOOL OsTicklessFlagGet(VOID) +LITE_OS_SEC_TEXT BOOL OsTicklessFlagGet(VOID) /*鐢ㄤ簬鑾峰彇Tickless鏍囧織鐨勭姸鎬*/ { return g_ticklessFlag; } -LITE_OS_SEC_TEXT BOOL OsTickIrqFlagGet(VOID) +LITE_OS_SEC_TEXT BOOL OsTickIrqFlagGet(VOID) { return g_tickIrqFlag[ArchCurrCpuid()]; + /*鏁扮粍琛ㄧず姣忎釜鏍稿績鐨凾ick涓柇鏍囧織鐨勭姸鎬侊紝 + 涓篢RUE琛ㄧず涓柇姝e湪澶勭悊涓紝涓篎ALSE琛ㄧず涓柇鏈鐞嗐*/ } -LITE_OS_SEC_TEXT VOID OsTickIrqFlagSet(BOOL tickIrqFlag) +LITE_OS_SEC_TEXT VOID OsTickIrqFlagSet(BOOL tickIrqFlag) /*鐢ㄤ簬璁剧疆褰撳墠鏍稿績鐨勬椂閽熶腑鏂爣蹇*/ { g_tickIrqFlag[ArchCurrCpuid()] = tickIrqFlag; } -LITE_OS_SEC_TEXT UINT32 OsTicklessSleepTickGet(VOID) +LITE_OS_SEC_TEXT UINT32 OsTicklessSleepTickGet(VOID) /*鐢ㄤ簬鑾峰彇褰撳墠绯荤粺鐨勭潯鐪犺鏃跺櫒鐨勬暟鍊*/ { return g_sleepTicks[ArchCurrCpuid()]; } -LITE_OS_SEC_TEXT VOID OsTicklessSleepTickSet(UINT32 sleeptick) +LITE_OS_SEC_TEXT VOID OsTicklessSleepTickSet(UINT32 sleeptick) /*璁剧疆褰撳墠鏍稿績寰楀埌鐫$湢璁℃椂鍣ㄧ殑鏁板*/ { g_sleepTicks[ArchCurrCpuid()] = sleeptick; } -LITE_OS_SEC_TEXT UINT32 OsSleepTicksGet(VOID) +LITE_OS_SEC_TEXT UINT32 OsSleepTicksGet(VOID) /*鍑芥暟鐢ㄤ簬鑾峰彇褰撳墠闇瑕佷紤鐪犵殑ticks鏁帮紝閫氳繃鏌ヨ浠诲姟閾捐〃鍜岃蒋浠跺畾鏃跺櫒閾捐〃锛 + 鎵惧埌鏈灏忕殑瀹氭椂鍣ㄥ埌鏈熸椂闂达紝浣滀负浼戠湢鏃堕暱銆*/ { UINT32 tskSortLinkTicks, sleepTicks; @@ -104,7 +108,8 @@ LITE_OS_SEC_TEXT UINT32 OsSleepTicksGet(VOID) return sleepTicks; } -LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks) +LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks) /*鐢ㄤ簬鏇存柊绯荤粺鏃堕棿锛 + 鏍规嵁浼戠湢鏃堕暱鏇存柊鍏ㄥ眬璁℃暟鍣ㄥ拰浠诲姟閾捐〃銆佽蒋浠跺畾鏃跺櫒閾捐〃鐨勫埌鏈熸椂闂*/ { UINT32 intSave; @@ -127,7 +132,7 @@ LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks) LOS_IntRestore(intSave); } -VOID OsTicklessUpdate(UINT32 irqnum) +VOID OsTicklessUpdate(UINT32 irqnum) /*OsTicklessUpdate鍑芥暟鐢ㄤ簬鍦ㄥ彂鐢熶腑鏂椂鏇存柊绯荤粺鏃堕棿*/ { UINT32 cycles, ticks; UINT32 cyclesPertick; @@ -165,7 +170,8 @@ VOID OsTicklessUpdate(UINT32 irqnum) LOS_IntRestore(intSave); } -VOID OsTicklessStart(VOID) +VOID OsTicklessStart(VOID) /*Tickless妯″紡鐨勫叆鍙e嚱鏁帮紝鏍规嵁浼戠湢鏃堕暱璁$畻闇瑕佸欢杩熺殑鍛ㄦ湡鏁帮紝 + 骞惰缃畾鏃跺櫒鐨勯噸杞藉硷紝鍚姩Tickless妯″紡銆*/ { UINT32 intSave; /* @@ -202,7 +208,8 @@ VOID OsTicklessStart(VOID) return; } -VOID OsTicklessOpen(VOID) +VOID OsTicklessOpen(VOID) /*鍦═ick涓柇澶勭悊鍑芥暟涓紑鍚疶ickless妯″紡銆 + 褰揟ick涓柇澶勭悊鍑芥暟妫娴嬪埌Tickless鏍囧織涓1鏃讹紝璋冪敤璇ュ嚱鏁板惎鍔═ickless妯″紡銆*/ { if (OsTickIrqFlagGet()) { OsTickIrqFlagSet(0); diff --git a/src/kernel/extended/perf/los_perf.c b/src/kernel/extended/perf/los_perf.c index ecb0c2e..e8b84f6 100644 --- a/src/kernel/extended/perf/los_perf.c +++ b/src/kernel/extended/perf/los_perf.c @@ -37,10 +37,11 @@ extern "C" { #endif /* __cplusplus */ #ifdef LOSCFG_KERNEL_PERF -STATIC Pmu *g_pmu = NULL; -STATIC PerfCB g_perfCb = {0}; +STATIC Pmu *g_pmu = NULL;//鐢ㄤ簬淇濆瓨褰撳墠绯荤粺涓墍浣跨敤鐨勭‖浠舵ц兘璁℃暟鍣 +STATIC PerfCB g_perfCb = {0};//淇濆瓨浜嗘ц兘娴嬮噺鍥炶皟鍑芥暟鍜屼竴浜涙祴閲忕粨鏋滄暟鎹 LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_perfSpin); +//瀹氫箟浜嗕竴涓嚜鏃嬮攣 g_perfSpin锛岀敤浜庝繚鎶ゆц兘娴嬮噺妯″潡鍦ㄥ绾跨▼鐜涓嬬殑骞跺彂璁块棶 #define PERF_LOCK(state) LOS_SpinLockSave(&g_perfSpin, &(state)) #define PERF_UNLOCK(state) LOS_SpinUnlockRestore(&g_perfSpin, (state)) @@ -55,8 +56,9 @@ STATIC INLINE UINT64 OsPerfGetCurrTime(VOID) #endif } -STATIC UINT32 OsPmuInit(VOID) +STATIC UINT32 OsPmuInit(VOID)//鍒濆鍖栨ц兘璁℃暟鍣 { + //鍒ゆ柇鏄惁寮鍚簡璁℃暟鍣 #ifdef LOSCFG_PERF_HW_PMU if (OsHwPmuInit() != LOS_OK) { return LOS_ERRNO_PERF_HW_INIT_ERROR; @@ -77,13 +79,13 @@ STATIC UINT32 OsPmuInit(VOID) return LOS_OK; } -STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg) +STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg)//閰嶇疆鎬ц兘璁℃暟鍣 { UINT32 i; UINT32 ret; g_pmu = OsPerfPmuGet(eventsCfg->type); - if (g_pmu == NULL) { + if (g_pmu == NULL) {//鏍规嵁閰嶇疆鐨勭被鍨嬭幏鍙栧搴旂殑鎬ц兘璁℃暟鍣ㄥ璞 PRINT_ERR("perf config type error %u!\n", eventsCfg->type); return LOS_ERRNO_PERF_INVALID_PMU; } @@ -92,6 +94,7 @@ STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg) (VOID)memset_s(&g_pmu->events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); +//鏍规嵁閰嶇疆淇℃伅璁剧疆鍚勬ц兘浜嬩欢鐨勫弬鏁帮紝璋冪敤鎬ц兘璁℃暟鍣ㄥ璞$殑閰嶇疆鍑芥暟杩涜閰嶇疆 for (i = 0; i < eventNum; i++) { g_pmu->events.per[i].eventId = eventsCfg->events[i].eventId; g_pmu->events.per[i].period = eventsCfg->events[i].period; @@ -109,13 +112,13 @@ STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg) return LOS_OK; } -STATIC VOID OsPerfPrintCount(VOID) +STATIC VOID OsPerfPrintCount(VOID)//鐢ㄤ簬鎵撳嵃鎬ц兘璁℃暟鍣ㄧ殑缁熻淇℃伅 { UINT32 index; UINT32 intSave; UINT32 cpuid = ArchCurrCpuid(); - PerfEvent *events = &g_pmu->events; + PerfEvent *events = &g_pmu->events;//鑾峰彇鎬ц兘璁℃暟鍣ㄥ璞$殑鎬ц兘鏃堕棿鏁扮粍鍜屼簨浠舵暟閲 UINT32 eventNum = events->nr; PERF_LOCK(intSave); @@ -123,7 +126,7 @@ STATIC VOID OsPerfPrintCount(VOID) Event *event = &(events->per[index]); /* filter out event counter with no event binded. */ - if (event->period == 0) { + if (event->period == 0) { //浜嬩欢鍛ㄦ湡 continue; } PRINT_EMG("[%s] eventType: 0x%x [core %u]: %llu\n", g_pmu->getName(event), event->eventId, cpuid, @@ -132,7 +135,7 @@ STATIC VOID OsPerfPrintCount(VOID) PERF_UNLOCK(intSave); } -STATIC INLINE VOID OsPerfPrintTs(VOID) +STATIC INLINE VOID OsPerfPrintTs(VOID)//鎵撳嵃鏃堕棿淇℃伅 { #ifdef LOSCFG_PERF_CALC_TIME_BY_TICK DOUBLE time = (g_perfCb.endTime - g_perfCb.startTime) * 1.0 / LOSCFG_BASE_CORE_TICK_PER_SECOND; @@ -142,7 +145,7 @@ STATIC INLINE VOID OsPerfPrintTs(VOID) PRINT_EMG("time used: %.6f(s)\r\n", time); } -STATIC VOID OsPerfStart(VOID) +STATIC VOID OsPerfStart(VOID)//鍚姩鍙婃洿鏂癈PU鍜岃鏁板櫒鐘舵 { UINT32 cpuid = ArchCurrCpuid(); @@ -152,7 +155,7 @@ STATIC VOID OsPerfStart(VOID) } if (g_perfCb.pmuStatusPerCpu[cpuid] != PERF_PMU_STARTED) { - UINT32 ret = g_pmu->start(); + UINT32 ret = g_pmu->start();//鑻ヨ鏁板櫒鏈惎鍔ㄥ垯鍚姩 if (ret != LOS_OK) { PRINT_ERR("perf start on core:%u failed, ret = 0x%x\n", cpuid, ret); return; @@ -164,7 +167,7 @@ STATIC VOID OsPerfStart(VOID) } } -STATIC VOID OsPerfStop(VOID) +STATIC VOID OsPerfStop(VOID)//鍋滄鎬ц兘璁℃暟鍣 { UINT32 cpuid = ArchCurrCpuid(); @@ -191,19 +194,21 @@ STATIC VOID OsPerfStop(VOID) } STATIC UINT32 OsPerfBackTrace(UINTPTR *callChain, UINT32 maxDepth, PerfRegs *regs) +//鑾峰彇褰撳墠鍑芥暟璋冪敤閾剧殑淇℃伅锛屽苟灏嗙粨鏋滃瓨鍌ㄥ湪 callChain 鏁扮粍涓 { UINT32 i; - UINT32 count = ArchBackTraceGet(regs->fp, callChain, maxDepth); + UINT32 count = ArchBackTraceGet(regs->fp, callChain, maxDepth);//鑾峰彇褰撳墠鐘舵佺殑甯ф寚閽堝 PRINT_DEBUG("backtrace depth = %u, fp = 0x%x\n", count, regs->fp); for (i = 0; i < count; i++) { - PRINT_DEBUG("ip[%u]: 0x%x\n", i, callChain[i]); + PRINT_DEBUG("ip[%u]: 0x%x\n", i, callChain[i]);//鎵撳嵃璋冪敤閾句腑姣忎釜鍑芥暟鐨勬寚浠ゅ湴鍧 } - return count; + return count;//杩斿洖鐢ㄩ摼鐨勬繁搴 } STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *regs) +//鏀堕泦鎬ц兘璁℃暟鍣ㄧ殑鏁版嵁锛屽苟灏嗗叾瀛樺偍鍦 data 缁撴瀯浣撲腑 { UINT32 size = 0; UINT32 depth; @@ -211,12 +216,12 @@ STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *re CHAR *p = (CHAR *)data; if (sampleType & PERF_RECORD_CPU) { - *(UINT32 *)(p + size) = ArchCurrCpuid(); + *(UINT32 *)(p + size) = ArchCurrCpuid();//鍑芥暟鑾峰彇褰撳墠CPU鐨処D锛屽苟瀛樺偍鍦 data->cpuid 瀛楁涓 size += sizeof(data->cpuid); } if (sampleType & PERF_RECORD_TID) { - *(UINT32 *)(p + size) = LOS_CurTaskIDGet(); + *(UINT32 *)(p + size) = LOS_CurTaskIDGet();// 鍑芥暟鑾峰彇褰撳墠浠诲姟鐨処D锛屽苟瀛樺偍鍦 data->taskId 瀛楁涓 size += sizeof(data->taskId); } @@ -231,7 +236,7 @@ STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *re } if (sampleType & PERF_RECORD_TIMESTAMP) { - *(UINT64 *)(p + size) = OsPerfGetCurrTime(); + *(UINT64 *)(p + size) = OsPerfGetCurrTime();//鑾峰彇褰撳墠鏃堕棿鎴筹紝骞跺瓨鍌ㄥ湪 data->time 瀛楁涓 size += sizeof(data->time); } @@ -254,7 +259,7 @@ STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *re * return TRUE if user haven't specified any taskId(which is supposed * to instrument the whole system) */ -STATIC BOOL OsPerfTaskFilter(UINT32 taskId) +STATIC BOOL OsPerfTaskFilter(UINT32 taskId)//杩囨护浠诲姟ID锛屽垽鏂竴涓粰瀹氱殑浠诲姟ID鏄惁闇瑕佽繘琛屾ц兘浼樺寲 { UINT32 i; @@ -262,7 +267,7 @@ STATIC BOOL OsPerfTaskFilter(UINT32 taskId) return TRUE; } - for (i = 0; i < g_perfCb.taskIdsNr; i++) { + for (i = 0; i < g_perfCb.taskIdsNr; i++) { //鍌ㄥ瓨鍏佽杩囨护浠诲姟ID鐨勫垪琛 if (g_perfCb.taskIds[i] == taskId) { return TRUE; } @@ -270,7 +275,7 @@ STATIC BOOL OsPerfTaskFilter(UINT32 taskId) return FALSE; } -STATIC INLINE UINT32 OsPerfParamValid(VOID) +STATIC INLINE UINT32 OsPerfParamValid(VOID)//妫鏌ユц兘鍑芥暟鐨勬湁鏁堟 { UINT32 index; UINT32 res = 0; @@ -287,7 +292,7 @@ STATIC INLINE UINT32 OsPerfParamValid(VOID) return res; } -STATIC UINT32 OsPerfHdrInit(UINT32 id) +STATIC UINT32 OsPerfHdrInit(UINT32 id)//鍒濆鍖栨ц兘鏁版嵁鐨勫ご閮ㄤ俊鎭 { PerfDataHdr head = { .magic = PERF_DATA_MAGIC_WORD, @@ -299,7 +304,7 @@ STATIC UINT32 OsPerfHdrInit(UINT32 id) return OsPerfOutPutWrite((CHAR *)&head, head.len); } -VOID OsPerfUpdateEventCount(Event *event, UINT32 value) +VOID OsPerfUpdateEventCount(Event *event, UINT32 value)//鏇存柊涓婁紶浜嬩欢鐨勬妧鏈 { if (event == NULL) { return; @@ -307,46 +312,46 @@ VOID OsPerfUpdateEventCount(Event *event, UINT32 value) event->count[ArchCurrCpuid()] += (value & 0xFFFFFFFF); /* event->count is UINT64 */ } -VOID OsPerfHandleOverFlow(Event *event, PerfRegs *regs) +VOID OsPerfHandleOverFlow(Event *event, PerfRegs *regs)//澶勭悊鎬ц兘璁℃暟鍣ㄦ孩鍑虹殑鎯呭喌 { PerfSampleData data; UINT32 len; (VOID)memset_s(&data, sizeof(PerfSampleData), 0, sizeof(PerfSampleData)); - if ((g_perfCb.needSample) && OsPerfTaskFilter(LOS_CurTaskIDGet())) { + if ((g_perfCb.needSample) && OsPerfTaskFilter(LOS_CurTaskIDGet())) {//鍒ゆ柇鏄惁浼樺寲 len = OsPerfCollectData(event, &data, regs); OsPerfOutPutWrite((CHAR *)&data, len); } } -UINT32 LOS_PerfInit(VOID *buf, UINT32 size) +UINT32 LOS_PerfInit(VOID *buf, UINT32 size)//鍒濆鍖栨ц兘缁熻妯″潡 { UINT32 ret; UINT32 intSave; - PERF_LOCK(intSave); + PERF_LOCK(intSave);//淇濆瓨涓柇鐘舵 if (g_perfCb.status != PERF_UNINIT) { ret = LOS_ERRNO_PERF_STATUS_INVALID; goto PERF_INIT_ERROR; } - ret = OsPmuInit(); + ret = OsPmuInit();//鍑芥暟鎬ц兘璁℃暟鍣ㄥ垵濮嬪寲 if (ret != LOS_OK) { goto PERF_INIT_ERROR; } - ret = OsPerfOutPutInit(buf, size); + ret = OsPerfOutPutInit(buf, size);//鎬ц兘杈撳嚭缂撳啿鍖鸿繘琛屽垵濮嬪寲 if (ret != LOS_OK) { ret = LOS_ERRNO_PERF_BUF_ERROR; goto PERF_INIT_ERROR; } g_perfCb.status = PERF_STOPED; PERF_INIT_ERROR: - PERF_UNLOCK(intSave); + PERF_UNLOCK(intSave);//瑙i攣涓柇澶勭悊 return ret; } -UINT32 LOS_PerfConfig(PerfConfigAttr *attr) +UINT32 LOS_PerfConfig(PerfConfigAttr *attr)//閰嶇疆鎬ц兘缁熻妯″潡鐨勫睘鎬 { UINT32 ret; UINT32 intSave; @@ -355,20 +360,20 @@ UINT32 LOS_PerfConfig(PerfConfigAttr *attr) return LOS_ERRNO_PERF_CONFIG_NULL; } - PERF_LOCK(intSave); + PERF_LOCK(intSave);//淇濆瓨涓柇鐘舵 if (g_perfCb.status != PERF_STOPED) { ret = LOS_ERRNO_PERF_STATUS_INVALID; PRINT_ERR("perf config status error : 0x%x\n", g_perfCb.status); goto PERF_CONFIG_ERROR; } - g_pmu = NULL; + g_pmu = NULL;//灏嗗叏灞鏍囬噺PMU璁℃暟鍣ㄧ疆闆 g_perfCb.needSample = attr->needSample; g_perfCb.taskFilterEnable = attr->taskFilterEnable; g_perfCb.sampleType = attr->sampleType; - if (attr->taskFilterEnable) { + if (attr->taskFilterEnable) {//寮鍚换鍔¤繃婊ゅ姛鑳 ret = memcpy_s(g_perfCb.taskIds, PERF_MAX_FILTER_TSKS * sizeof(UINT32), attr->taskIds, g_perfCb.taskIdsNr * sizeof(UINT32)); if (ret != EOK) { @@ -377,29 +382,29 @@ UINT32 LOS_PerfConfig(PerfConfigAttr *attr) } g_perfCb.taskIdsNr = MIN(attr->taskIdsNr, PERF_MAX_FILTER_TSKS); } - ret = OsPerfConfig(&attr->eventsCfg); + ret = OsPerfConfig(&attr->eventsCfg);//瀵逛簨浠堕厤缃繘琛屽鐞 PERF_CONFIG_ERROR: PERF_UNLOCK(intSave); return ret; } -VOID LOS_PerfStart(UINT32 sectionId) +VOID LOS_PerfStart(UINT32 sectionId)//鍚姩鎬ц兘缁熻妯″潡 { UINT32 intSave; UINT32 ret; PERF_LOCK(intSave); - if (g_perfCb.status != PERF_STOPED) { + if (g_perfCb.status != PERF_STOPED) {//鍒ゆ柇缁熻妯″潡鏄惁鎵撳紑 PRINT_ERR("perf start status error : 0x%x\n", g_perfCb.status); goto PERF_START_ERROR; } - if (!OsPerfParamValid()) { + if (!OsPerfParamValid()) {//妫杞﹁鍛釜缁熻妯″潡鐨勫弬鏁版槸鍚︽湁鏁 PRINT_ERR("forgot call `LOS_Config(...)` before instrumenting?\n"); goto PERF_START_ERROR; } - if (g_perfCb.needSample) { + if (g_perfCb.needSample) {//鍒ゆ柇鏄惁闇瑕佹娊鏍 ret = OsPerfHdrInit(sectionId); /* section header init */ if (ret != LOS_OK) { PRINT_ERR("perf hdr init error 0x%x\n", ret); @@ -407,7 +412,7 @@ VOID LOS_PerfStart(UINT32 sectionId) } } - SMP_CALL_PERF_FUNC(OsPerfStart); /* send to all cpu to start pmu */ + SMP_CALL_PERF_FUNC(OsPerfStart); /* 鎵鏈塁PU寮濮婸MU璁℃暟鍣紝鍚姩鎬ц兘缁熻妯″潡i濂 */ g_perfCb.status = PERF_STARTED; g_perfCb.startTime = OsPerfGetCurrTime(); PERF_START_ERROR: @@ -415,7 +420,7 @@ PERF_START_ERROR: return; } -VOID LOS_PerfStop(VOID) +VOID LOS_PerfStop(VOID)//鍋滄鎬ц兘缁熻妯″潡鐨勮繍琛岋紝杩涜涓浜涙竻鐞嗘搷浣 { UINT32 intSave; @@ -427,12 +432,12 @@ VOID LOS_PerfStop(VOID) SMP_CALL_PERF_FUNC(OsPerfStop); /* send to all cpu to stop pmu */ - OsPerfOutPutFlush(); + OsPerfOutPutFlush();//鍒锋柊杈撳嚭鎿嶄綔 if (g_perfCb.needSample) { OsPerfOutPutInfo(); } - + //鏇存柊浜嗕袱涓叏灞鍙橀噺鐨勫硷紝琛ㄧず鎬ц兘缁熻妯″潡宸茬粡鍦ㄧ姸鎬佷笂鍜屾椂闂翠笂鍋滄浜 g_perfCb.status = PERF_STOPED; g_perfCb.endTime = OsPerfGetCurrTime(); @@ -442,21 +447,21 @@ PERF_STOP_ERROR: return; } -UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size) +UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size)//浠庢ц兘缁熻闂ㄧエ蹇殑杈撳嚭缂撳啿鍖轰腑璇诲彇鏁版嵁鍒版寚瀹氱殑鍐呭瓨 { return OsPerfOutPutRead(dest, size); } -VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func) +VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func)//娉ㄥ唽鍨嬮偅涓粺璁℃ā鍧楃殑閫氱煡hook鍑芥暟 { UINT32 intSave; - + //淇濆瓨涓柇鐘舵侊紝鎭㈠涓柇鐘舵 PERF_LOCK(intSave); OsPerfNotifyHookReg(func); PERF_UNLOCK(intSave); } -VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func) +VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)//鍒锋柊hook { UINT32 intSave; @@ -465,7 +470,7 @@ VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func) PERF_UNLOCK(intSave); } -VOID OsPerfSetIrqRegs(UINTPTR pc, UINTPTR fp) +VOID OsPerfSetIrqRegs(UINTPTR pc, UINTPTR fp)//璁剧疆涓柇鐩稿叧鐨勫瘎瀛樺櫒锛岀敤浜庝腑鏂椂鐨勬ц兘缁熻 { LosTaskCB *runTask = (LosTaskCB *)ArchCurrTaskGet(); runTask->pc = pc; diff --git a/src/kernel/extended/perf/perf_output.c b/src/kernel/extended/perf/perf_output.c index 20bea3a..a83d806 100644 --- a/src/kernel/extended/perf/perf_output.c +++ b/src/kernel/extended/perf/perf_output.c @@ -39,11 +39,14 @@ STATIC PERF_BUF_FLUSH_HOOK g_perfBufFlushHook = NULL; STATIC PerfOutputCB g_perfOutputCb; STATIC VOID OsPerfDefaultNotify(VOID) +//榛樿鐨勬ц兘缂撳啿鍖洪氱煡鍥炶皟鍑芥暟锛屽湪鎬ц兘缂撳啿鍖虹殑姘翠綅绾胯揪鍒颁竴瀹氬兼椂鎵撳嵃涓鏉′俊鎭 { PRINT_INFO("perf buf waterline notify!\n"); } UINT32 OsPerfOutPutInit(VOID *buf, UINT32 size) +//鍒濆鍖栨ц兘杈撳嚭妯″潡銆傚鏋滀紶鍏ョ殑缂撳啿鍖烘寚閽堜负绌猴紝鍒欎娇鐢↙OS_MemAlloc鍑芥暟鍔ㄦ佸垎閰嶅唴瀛樸 +//鐒跺悗鍒濆鍖栫幆褰㈢紦鍐插尯锛岃缃按浣嶇嚎锛屽苟娉ㄥ唽榛樿鐨勬ц兘缂撳啿鍖洪氱煡鍥炶皟鍑芥暟 { UINT32 ret; BOOL releaseFlag = FALSE; @@ -69,21 +72,22 @@ RELEASE: return ret; } -VOID OsPerfOutPutFlush(VOID) +VOID OsPerfOutPutFlush(VOID)//鍒锋柊鎬ц兘杈撳嚭缂撳啿鍖 { if (g_perfBufFlushHook != NULL) { g_perfBufFlushHook(g_perfOutputCb.ringbuf.fifo, g_perfOutputCb.ringbuf.size); } } -UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size) +UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size)//浠庢ц兘杈撳嚭缂撳啿鍖轰腑璇诲彇鏁版嵁 { OsPerfOutPutFlush(); return LOS_RingbufRead(&g_perfOutputCb.ringbuf, dest, size); } -STATIC BOOL OsPerfOutPutBegin(UINT32 size) +STATIC BOOL OsPerfOutPutBegin(UINT32 size)//寮濮嬪啓鍏ユц兘杈撳嚭缂撳啿鍖 { + //妫鏌ユ槸鍚︽湁瓒冲绌洪棿 if (g_perfOutputCb.ringbuf.remain < size) { PRINT_INFO("perf buf has no enough space for 0x%x\n", size); return FALSE; @@ -91,9 +95,9 @@ STATIC BOOL OsPerfOutPutBegin(UINT32 size) return TRUE; } -STATIC VOID OsPerfOutPutEnd(VOID) +STATIC VOID OsPerfOutPutEnd(VOID)//缁撴潫鎬ц兘杈撳嚭 { - OsPerfOutPutFlush(); + OsPerfOutPutFlush();//鍒锋柊缂撳啿鍖 if (LOS_RingbufUsedSize(&g_perfOutputCb.ringbuf) >= g_perfOutputCb.waterMark) { if (g_perfBufNotifyHook != NULL) { g_perfBufNotifyHook(); @@ -101,7 +105,7 @@ STATIC VOID OsPerfOutPutEnd(VOID) } } -UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size) +UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size)//灏嗘暟鎹啓鍏ユц兘杈撳叆缂撳啿鍖 { if (!OsPerfOutPutBegin(size)) { return LOS_NOK; @@ -113,17 +117,17 @@ UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size) return LOS_OK; } -VOID OsPerfOutPutInfo(VOID) +VOID OsPerfOutPutInfo(VOID)//鎵撳嵃鎬ц兘杈撳嚭缂撳啿鍖虹殑淇℃伅锛屽寘鎷湴鍧鍜岄暱搴 { PRINT_EMG("dump section data, addr: %p length: %#x \r\n", g_perfOutputCb.ringbuf.fifo, g_perfOutputCb.ringbuf.size); } -VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func) +VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func)//娉ㄥ唽鎬ц兘缂撳啿鍖洪氱煡 { g_perfBufNotifyHook = func; } -VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func) +VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)//娉ㄥ唽鎬ц兘缂撳啿鍖哄埛鏂扮殑鍑芥暟 { g_perfBufFlushHook = func; } diff --git a/src/kernel/extended/perf/perf_output_pri.h b/src/kernel/extended/perf/perf_output_pri.h index 382f2a9..603e64d 100644 --- a/src/kernel/extended/perf/perf_output_pri.h +++ b/src/kernel/extended/perf/perf_output_pri.h @@ -43,13 +43,13 @@ typedef struct { UINT32 waterMark; /* notify water mark */ } PerfOutputCB; -extern UINT32 OsPerfOutPutInit(VOID *buf, UINT32 size); -extern UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size); -extern UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size); -extern VOID OsPerfOutPutInfo(VOID); -extern VOID OsPerfOutPutFlush(VOID); -extern VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func); -extern VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func); +extern UINT32 OsPerfOutPutInit(VOID *buf, UINT32 size);//鍒濆鍖栨ц兘杈撳嚭妯″潡 +extern UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size);//浠庢ц兘杈撳嚭缂撳啿鍖轰腑璇诲彇鏁版嵁锛屽皢鏁版嵁鎷疯礉鍒版寚瀹氱殑鐩爣缂撳啿鍖轰腑 +extern UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size);//灏嗘暟鎹啓鍏ユц兘杈撳嚭缂撳啿鍖 +extern VOID OsPerfOutPutInfo(VOID);//杈撳嚭鎬ц兘缁熻淇℃伅 +extern VOID OsPerfOutPutFlush(VOID);//鍒锋柊鎬ц兘杈撳嚭缂撳啿鍖 +extern VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func);//娉ㄥ唽鎬ц兘杈撳嚭缂撳啿鍖洪氱煡 +extern VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func);//娉ㄥ唽鎬ц兘杈撳嚭缂撳啿鍖哄埛鏂 #ifdef __cplusplus #if __cplusplus diff --git a/src/kernel/extended/perf/perf_pmu.c b/src/kernel/extended/perf/perf_pmu.c index a2771ba..ff5cca6 100644 --- a/src/kernel/extended/perf/perf_pmu.c +++ b/src/kernel/extended/perf/perf_pmu.c @@ -36,11 +36,11 @@ extern "C" { STATIC Pmu *g_pmuMgr[PERF_EVENT_TYPE_MAX] = {NULL}; -UINT32 OsPerfPmuRegister(Pmu *pmu) +UINT32 OsPerfPmuRegister(Pmu *pmu)//娉ㄥ唽鎬ц兘璁℃暟鍣 { UINT32 type; - if ((pmu == NULL) || (pmu->type >= PERF_EVENT_TYPE_MAX)) { + if ((pmu == NULL) || (pmu->type >= PERF_EVENT_TYPE_MAX)) {//濡傛灉浼犲叆PMU涓虹┖鎸囬拡鎴栬卼ype瓒呭嚭浜嗘湁鏁堣寖鍥 return LOS_NOK; } @@ -52,19 +52,20 @@ UINT32 OsPerfPmuRegister(Pmu *pmu) return LOS_NOK; } -Pmu *OsPerfPmuGet(UINT32 type) +Pmu *OsPerfPmuGet(UINT32 type)//鑾峰彇鎸囧畾绫诲瀷鐨勬ц兘璁℃暟鍣 { if (type >= PERF_EVENT_TYPE_MAX) { return NULL; } - if (type == PERF_EVENT_TYPE_RAW) { /* process hardware raw events with hard pmu */ - type = PERF_EVENT_TYPE_HW; + if (type == PERF_EVENT_TYPE_RAW) { //濡傛灉鏄師濮嬩簨浠剁被鍨 + /* process hardware raw events with hard pmu */ + type = PERF_EVENT_TYPE_HW;//鍒欏皢鍏惰浆鍖栦负纭欢浜嬩欢绫诲瀷 } return g_pmuMgr[type]; } -VOID OsPerfPmuRm(UINT32 type) +VOID OsPerfPmuRm(UINT32 type)//鍒犻櫎鎸囧畾绫诲瀷鐨勬ц兘璁℃暟鍣 { if (type >= PERF_EVENT_TYPE_MAX) { return; diff --git a/src/kernel/extended/perf/perf_pmu_pri.h b/src/kernel/extended/perf/perf_pmu_pri.h index 2507d34..4cbb5bd 100644 --- a/src/kernel/extended/perf/perf_pmu_pri.h +++ b/src/kernel/extended/perf/perf_pmu_pri.h @@ -53,7 +53,7 @@ typedef struct { VOID (*setPeriod)(Event *event); UINTPTR (*readCnt)(Event *event); UINT32 (*mapEvent)(UINT32 eventType, BOOL reverse); -} HwPmu; +} HwPmu;//纭欢鎬ц兘璁℃暟鍣ㄧ粨鏋勪綋锛屽寘鎷‖浠惰鏁板櫒銆佽鏁板櫒鏄惁鑳借鍒嗛銆佸垎棰戠郴鏁般佸惎鐢ㄣ佺鐢ㄣ佸紑濮嬨佸仠姝€佹竻闄ゃ佽缃懆鏈熴佽鍙栬鏁板櫒鍊煎拰浜嬩欢鏄犲皠绛夊嚱鏁版寚閽 typedef struct { Pmu pmu; @@ -69,35 +69,35 @@ typedef struct { }; #endif }; -} SwPmu; +} SwPmu;//杞欢鎬ц兘璁℃暟鍣ㄧ粨鏋勪綋锛屽寘鎷蒋浠惰鏁板櫒銆佹槸鍚﹀惎鐢ㄦ爣蹇椾綅銆佸畾鏃跺櫒閰嶇疆鏃堕棿 #define GET_HW_PMU(item) LOS_DL_LIST_ENTRY(item, HwPmu, pmu) -#define TIMER_PERIOD_LOWER_BOUND_US 100 +#define TIMER_PERIOD_LOWER_BOUND_US 100//瀹氭椂鍣ㄦ渶灏忓懆鏈 -#define CCNT_FULL 0xFFFFFFFF -#define CCNT_PERIOD_LOWER_BOUND 0x00000000 -#define CCNT_PERIOD_UPPER_BOUND 0xFFFFFF00 -#define PERIOD_CALC(p) (CCNT_FULL - (p)) +#define CCNT_FULL 0xFFFFFFFF//璁℃暟鍣ㄦ渶澶у +#define CCNT_PERIOD_LOWER_BOUND 0x00000000//鏈灏忓懆鏈 +#define CCNT_PERIOD_UPPER_BOUND 0xFFFFFF00//鏈澶у懆鏈 +#define PERIOD_CALC(p) (CCNT_FULL - (p))//璁$畻缁欏畾鍛ㄦ湡瀵瑰簲鐨勮鏁板櫒鍊 #define VALID_PERIOD(p) ((PERIOD_CALC(p) > CCNT_PERIOD_LOWER_BOUND) \ - && (PERIOD_CALC(p) < CCNT_PERIOD_UPPER_BOUND)) + && (PERIOD_CALC(p) < CCNT_PERIOD_UPPER_BOUND))//鍒ゆ柇缁欏畾鍛ㄦ湡鏄惁鍚堟硶 -#define PERF_HW_INVAILD_EVENT_TYPE 0xFFFFFFFF +#define PERF_HW_INVAILD_EVENT_TYPE 0xFFFFFFFF//鏃犳晥鐨勪簨浠剁被鍨 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) -extern UINT32 OsPerfPmuRegister(Pmu *pmu); -extern VOID OsPerfPmuRm(UINT32 type); -extern Pmu *OsPerfPmuGet(UINT32 type); +extern UINT32 OsPerfPmuRegister(Pmu *pmu);//娉ㄥ唽纭欢鎬ц兘璁℃暟鍣 +extern VOID OsPerfPmuRm(UINT32 type);//鍒犻櫎纭欢鎬ц兘璁℃暟鍣 +extern Pmu *OsPerfPmuGet(UINT32 type);//鑾峰彇鎸囧畾绫诲瀷鐨勭‖浠舵ц兘璁℃暟鍣 -extern UINT32 OsHwPmuInit(VOID); -extern UINT32 OsSwPmuInit(VOID); -extern UINT32 OsTimedPmuInit(VOID); +extern UINT32 OsHwPmuInit(VOID);//鍒濆鍖栫‖浠舵ц兘璁℃暟鍣 +extern UINT32 OsSwPmuInit(VOID);//鍒濆鍖栬蒋浠舵ц兘璁℃暟鍣 +extern UINT32 OsTimedPmuInit(VOID);//鍒濆鍖栧畾鏃跺櫒鎬ц兘璁℃暟鍣 -extern UINT32 OsGetPmuCounter0(VOID); -extern UINT32 OsGetPmuMaxCounter(VOID); -extern UINT32 OsGetPmuCycleCounter(VOID); -extern UINT32 OsPerfHwInit(HwPmu *hwPmu); +extern UINT32 OsGetPmuCounter0(VOID);//鑾峰彇0鏍歌鏁板櫒鍊 +extern UINT32 OsGetPmuMaxCounter(VOID);//鑾峰彇鏈澶ц鏁板櫒鏁 +extern UINT32 OsGetPmuCycleCounter(VOID);//鑾峰彇鍛ㄦ湡鎬ц鏁板櫒鍊 +extern UINT32 OsPerfHwInit(HwPmu *hwPmu);//鍒濆鍖栫‖浠舵ц兘璁℃暟鍣 #ifdef __cplusplus #if __cplusplus diff --git a/src/kernel/extended/perf/pmu/perf_hw_pmu.c b/src/kernel/extended/perf/pmu/perf_hw_pmu.c index ca0b797..f76869d 100644 --- a/src/kernel/extended/perf/pmu/perf_hw_pmu.c +++ b/src/kernel/extended/perf/pmu/perf_hw_pmu.c @@ -34,7 +34,7 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -STATIC Pmu *g_perfHw = NULL; +STATIC Pmu *g_perfHw = NULL;//鎸囧悜鎬ц兘璁℃暟鍣ㄧ浉鍏崇殑鏁版嵁缁撴瀯鎴栧璞 STATIC CHAR *g_eventName[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_CPU_CYCLES] = "cycles", @@ -53,39 +53,41 @@ STATIC CHAR *g_eventName[PERF_COUNT_HW_MAX] = { * 2.Find available counter for each event. * 3.Decide whether this hardware pmu need prescaler (once every 64 cycle counts). */ -STATIC UINT32 OsPerfHwConfig(VOID) +STATIC UINT32 OsPerfHwConfig(VOID)//鎬ц兘璁℃暟鍣ㄧ殑閰嶇疆鍑芥暟锛岀敤浜庡垵濮嬪寲鍜岄厤缃‖浠舵ц兘璁℃暟鍣 { UINT32 i; HwPmu *armPmu = GET_HW_PMU(g_perfHw); - UINT32 maxCounter = OsGetPmuMaxCounter(); - UINT32 counter = OsGetPmuCounter0(); - UINT32 cycleCounter = OsGetPmuCycleCounter(); + UINT32 maxCounter = OsGetPmuMaxCounter();//鑾峰緱鏈澶ц鏁板櫒鏁伴噺 + UINT32 counter = OsGetPmuCounter0();//鑾峰彇0鏍歌鏁板櫒鐨勫 + UINT32 cycleCounter = OsGetPmuCycleCounter();//鍛ㄦ湡璁℃暟鍣ㄧ殑鍊 UINT32 cycleCode = armPmu->mapEvent(PERF_COUNT_HW_CPU_CYCLES, PERF_EVENT_TO_CODE); if (cycleCode == PERF_HW_INVAILD_EVENT_TYPE) { return LOS_NOK; } - + //鑾峰彇鎬ц兘浜嬩欢鐨勫垪琛ㄧ殑鍜屾暟閲忓苟杩涜閬嶅巻 PerfEvent *events = &g_perfHw->events; UINT32 eventNum = events->nr; for (i = 0; i < eventNum; i++) { Event *event = &(events->per[i]); - if (!VALID_PERIOD(event->period)) { + if (!VALID_PERIOD(event->period)) {//妫鏌ヤ簨浠跺懆鏈熸槸鍚﹀悎娉 PRINT_ERR("Config period: 0x%x invalid, should be in (%#x, %#x)\n", event->period, PERIOD_CALC(CCNT_PERIOD_UPPER_BOUND), PERIOD_CALC(CCNT_PERIOD_LOWER_BOUND)); return LOS_NOK; } if (g_perfHw->type == PERF_EVENT_TYPE_HW) { /* do map */ + //鏄犲皠缂栫爜 UINT32 eventId = armPmu->mapEvent(event->eventId, PERF_EVENT_TO_CODE); if (eventId == PERF_HW_INVAILD_EVENT_TYPE) { return LOS_NOK; } event->eventId = eventId; } - + //鍑芥暟鏍规嵁浜嬩欢缂栫爜鏄惁涓庡懆鏈熻鏁板櫒鐨勪簨浠剁紪鐮佺浉鍚岋紝鏉ョ‘瀹氳浜嬩欢浣跨敤鐨勮鏁板櫒銆 + //濡傛灉鐩稿悓锛屽垯浣跨敤鍛ㄦ湡璁℃暟鍣紱鍚﹀垯锛屼娇鐢ㄦ櫘閫氳鏁板櫒锛屽苟閫掑璁℃暟鍣ㄧ殑鍊笺 if (event->eventId == cycleCode) { event->counter = cycleCounter; } else { @@ -93,11 +95,11 @@ STATIC UINT32 OsPerfHwConfig(VOID) counter++; } - if (counter >= maxCounter) { + if (counter >= maxCounter) {//妫鏌ヨ鏁板櫒鏄惁瓒呰繃浜嗘渶澶ц鏁板櫒鏁伴噺 PRINT_ERR("max events: %u excluding cycle event\n", maxCounter - 1); return LOS_NOK; } - + //鎵撳嵃缁撴灉锛岃缃牴鎹钩鍙版敮鎸佺殑鍒嗛 PRINT_DEBUG("Perf Config %u eventId = 0x%x, counter = 0x%x, period = 0x%x\n", i, event->eventId, event->counter, event->period); } @@ -106,21 +108,21 @@ STATIC UINT32 OsPerfHwConfig(VOID) return LOS_OK; } -STATIC UINT32 OsPerfHwStart(VOID) +STATIC UINT32 OsPerfHwStart(VOID)//鐢ㄤ簬鍚姩纭欢鎬ц兘璁℃暟鍣 { UINT32 i; UINT32 cpuid = ArchCurrCpuid(); - HwPmu *armPmu = GET_HW_PMU(g_perfHw); + HwPmu *armPmu = GET_HW_PMU(g_perfHw);//鑾峰彇纭欢鎬ц兘璁℃暟鍣ㄧ殑鎸囬拡 PerfEvent *events = &g_perfHw->events; UINT32 eventNum = events->nr; - armPmu->clear(); + armPmu->clear();//娓呴浂璁℃暟鍣 for (i = 0; i < eventNum; i++) { Event *event = &(events->per[i]); - armPmu->setPeriod(event); - armPmu->enable(event); + armPmu->setPeriod(event);//璁剧疆浜嬩欢鐨勮鏁板懆鏈 + armPmu->enable(event);//鍚敤浜嬩欢鐨勮鏁板櫒 event->count[cpuid] = 0; } @@ -128,7 +130,7 @@ STATIC UINT32 OsPerfHwStart(VOID) return LOS_OK; } -STATIC UINT32 OsPerfHwStop(VOID) +STATIC UINT32 OsPerfHwStop(VOID)//鍋滄纭欢鎬ц兘璁℃暟鍣 { UINT32 i; UINT32 cpuid = ArchCurrCpuid(); @@ -148,7 +150,9 @@ STATIC UINT32 OsPerfHwStop(VOID) /* multiplier of cycle counter */ UINT32 eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT); if ((eventId == PERF_COUNT_HW_CPU_CYCLES) && (armPmu->cntDivided != 0)) { + //濡傛灉璇ヤ簨浠剁殑浜嬩欢ID涓庡懆鏈熻鏁板櫒浜嬩欢ID鐩稿悓锛屽苟涓旂‖浠舵ц兘璁℃暟鍣ㄧ殑鍒嗛璁剧疆armPmu->cntDivided涓嶄负0 PRINT_DEBUG("perf stop is cycle\n"); + //姝ゅ灏嗚浜嬩欢鐨勮鏁板煎乏绉6浣嶏紝鐩稿綋浜庝箻浠64 event->count[cpuid] = event->count[cpuid] << 6; /* CCNT counts every 64th cpu cycle */ } PRINT_DEBUG("perf stop eventCount[0x%x] : [%s] = %llu\n", event->eventId, g_eventName[eventId], @@ -157,11 +161,11 @@ STATIC UINT32 OsPerfHwStop(VOID) return LOS_OK; } -STATIC CHAR *OsPerfGetEventName(Event *event) +STATIC CHAR *OsPerfGetEventName(Event *event)//鑾峰彇浜嬩欢鍚嶇О { UINT32 eventId; - HwPmu *armPmu = GET_HW_PMU(g_perfHw); - eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT); + HwPmu *armPmu = GET_HW_PMU(g_perfHw);//鑾峰彇PMU涓婄殑浜嬩欢淇℃伅 + eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT);//灏嗕簨浠禝D鏄犲皠浣嶅搴旇鏁板櫒浜嬩欢ID if (eventId < PERF_COUNT_HW_MAX) { return g_eventName[eventId]; } else { @@ -169,21 +173,21 @@ STATIC CHAR *OsPerfGetEventName(Event *event) } } -UINT32 OsPerfHwInit(HwPmu *hwPmu) +UINT32 OsPerfHwInit(HwPmu *hwPmu)//鍒濆鍖栨ц兘璁℃暟鍣 { UINT32 ret; if (hwPmu == NULL) { return LOS_NOK; } - + //璁剧疆鎬ц兘璁℃暟鍣ㄧ殑绫诲瀷锛岄厤缃嚱鏁帮紝鍚姩鍑芥暟锛屽仠姝㈠嚱鏁帮紝鑾峰彇浜嬩欢鍚嶇О鍑芥暟 hwPmu->pmu.type = PERF_EVENT_TYPE_HW; hwPmu->pmu.config = OsPerfHwConfig; hwPmu->pmu.start = OsPerfHwStart; hwPmu->pmu.stop = OsPerfHwStop; hwPmu->pmu.getName = OsPerfGetEventName; - + //灏嗙‖浠舵ц兘璁℃暟鍣ㄧ殑浜嬩欢鏁版嵁缁撴瀯娓呴浂 (VOID)memset_s(&hwPmu->pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); - ret = OsPerfPmuRegister(&hwPmu->pmu); + ret = OsPerfPmuRegister(&hwPmu->pmu);//娉ㄥ唽纭欢鎬ц兘璁℃暟鍣紝灏嗗叾瀛樺偍鍦ㄥ叏灞鍙橀噺涓 g_perfHw = OsPerfPmuGet(PERF_EVENT_TYPE_HW); return ret; diff --git a/src/kernel/extended/perf/pmu/perf_sw_pmu.c b/src/kernel/extended/perf/pmu/perf_sw_pmu.c index 5ea7e52..fe6f251 100644 --- a/src/kernel/extended/perf/pmu/perf_sw_pmu.c +++ b/src/kernel/extended/perf/pmu/perf_sw_pmu.c @@ -51,7 +51,7 @@ STATIC CHAR* g_eventName[PERF_COUNT_SW_MAX] = { [PERF_COUNT_SW_MUX_PEND] = "mux pend", }; -VOID OsPerfHook(UINT32 eventType) +VOID OsPerfHook(UINT32 eventType)//杞欢鎬ц兘璁℃暟鍣ㄧ殑浜嬩欢澶勭悊鍑芥暟 { if (!g_perfSw.enable) { return; @@ -69,7 +69,7 @@ VOID OsPerfHook(UINT32 eventType) if (event->counter == eventType) { OsPerfUpdateEventCount(event, 1); if (event->count[ArchCurrCpuid()] % event->period == 0) { - OsPerfFetchCallerRegs(®s); + OsPerfFetchCallerRegs(®s);//鑾峰彇瀵勫瓨鍣ㄤ俊鎭 OsPerfHandleOverFlow(event, ®s); } return; @@ -77,7 +77,7 @@ VOID OsPerfHook(UINT32 eventType) } } -STATIC UINT32 OsPerfSwConfig(VOID) +STATIC UINT32 OsPerfSwConfig(VOID)//瀵硅蒋浠舵ц兘璁℃暟鍣ㄨ繘琛岄厤缃 { UINT32 i; PerfEvent *events = &g_perfSw.pmu.events; @@ -94,29 +94,29 @@ STATIC UINT32 OsPerfSwConfig(VOID) return LOS_OK; } -STATIC UINT32 OsPerfSwStart(VOID) +STATIC UINT32 OsPerfSwStart(VOID)//鍚姩杞欢鎬ц兘璁℃暟鍣 { UINT32 i; UINT32 cpuid = ArchCurrCpuid(); PerfEvent *events = &g_perfSw.pmu.events; UINT32 eventNum = events->nr; - for (i = 0; i < eventNum; i++) { + for (i = 0; i < eventNum; i++) {//閬嶅巻鎵鏈変簨浠 Event *event = &(events->per[i]); - event->count[cpuid] = 0; + event->count[cpuid] = 0;//娓呴浂褰撳墠浜嬩欢鍦–PU涓殑璁℃暟鍣 } - g_perfSw.enable = TRUE; + g_perfSw.enable = TRUE;//鍚姩璁℃暟鍣 return LOS_OK; } -STATIC UINT32 OsPerfSwStop(VOID) +STATIC UINT32 OsPerfSwStop(VOID)//鍏抽棴杞欢鎬ц兘璁℃暟鍣 { g_perfSw.enable = FALSE; return LOS_OK; } -STATIC CHAR *OsPerfGetEventName(Event *event) +STATIC CHAR *OsPerfGetEventName(Event *event)//鑾峰彇浜嬩欢鐨勫悕绉 { UINT32 eventId = event->eventId; if (eventId < PERF_COUNT_SW_MAX) { @@ -125,7 +125,7 @@ STATIC CHAR *OsPerfGetEventName(Event *event) return "unknown"; } -UINT32 OsSwPmuInit(VOID) +UINT32 OsSwPmuInit(VOID)//瀵筆MU璁℃暟鍣ㄨ繘琛屽垵濮嬪寲 { g_perfSw.pmu = (Pmu) { .type = PERF_EVENT_TYPE_SW, diff --git a/src/kernel/extended/perf/pmu/perf_timed_pmu.c b/src/kernel/extended/perf/pmu/perf_timed_pmu.c index 4659c08..6080f90 100644 --- a/src/kernel/extended/perf/pmu/perf_timed_pmu.c +++ b/src/kernel/extended/perf/pmu/perf_timed_pmu.c @@ -39,12 +39,12 @@ extern "C" { STATIC SwPmu g_perfTimed; -STATIC BOOL OsPerfTimedPeriodValid(UINT32 period) +STATIC BOOL OsPerfTimedPeriodValid(UINT32 period)//楠岃瘉瀹氭椂鍣ㄤ腑鐨勬椂闂村懆鏈熸槸鍚﹀悎娉 { return period >= TIMER_PERIOD_LOWER_BOUND_US; } -STATIC UINT32 OsPerfTimedStart(VOID) +STATIC UINT32 OsPerfTimedStart(VOID)//鍚姩瀹氭椂鍣ㄤ簨浠 { UINT32 i; UINT32 cpuid = ArchCurrCpuid(); @@ -74,7 +74,7 @@ STATIC UINT32 OsPerfTimedStart(VOID) return LOS_OK; } -STATIC UINT32 OsPerfTimedConfig(VOID) +STATIC UINT32 OsPerfTimedConfig(VOID)//閰嶇疆瀹氭椂鍣紝妫楠屾槸鍚﹀悎娉 { UINT32 i; PerfEvent *events = &g_perfTimed.pmu.events; @@ -101,7 +101,7 @@ STATIC UINT32 OsPerfTimedConfig(VOID) return LOS_NOK; } -STATIC UINT32 OsPerfTimedStop(VOID) +STATIC UINT32 OsPerfTimedStop(VOID)//鍏抽棴瀹氭椂鍣ㄨ缃 { UINT32 ret; if (ArchCurrCpuid() != 0) { /* only need stop on one core */ @@ -116,7 +116,7 @@ STATIC UINT32 OsPerfTimedStop(VOID) return LOS_OK; } -STATIC VOID OsPerfTimedHandle(VOID) +STATIC VOID OsPerfTimedHandle(VOID)//澶勭悊瀹氭椂鍣ㄤ簨浠 { UINT32 index; PerfRegs regs; @@ -125,7 +125,7 @@ STATIC VOID OsPerfTimedHandle(VOID) UINT32 eventNum = events->nr; (VOID)memset_s(®s, sizeof(PerfRegs), 0, sizeof(PerfRegs)); - OsPerfFetchIrqRegs(®s); + OsPerfFetchIrqRegs(®s);//鑾峰彇褰撳墠瀵勫瓨鍣ㄧ姸鎬 for (index = 0; index < eventNum; index++) { Event *event = &(events->per[index]); @@ -134,48 +134,50 @@ STATIC VOID OsPerfTimedHandle(VOID) } } -STATIC enum hrtimer_restart OsPerfHrtimer(struct hrtimer *hrtimer) +STATIC enum hrtimer_restart OsPerfHrtimer(struct hrtimer *hrtimer)//楂樼簿搴﹀畾鏃跺櫒(hrtimer)鐨勫洖璋冨嚱鏁 { SMP_CALL_PERF_FUNC(OsPerfTimedHandle); /* send to all cpu to collect data */ + //灏嗗畾鏃跺櫒浜嬩欢鐨勫鐞嗗彂閫佺粰鎵鏈塁PU杩涜鏁版嵁鏀堕泦 return HRTIMER_RESTART; } -STATIC CHAR *OsPerfGetEventName(Event *event) +STATIC CHAR *OsPerfGetEventName(Event *event)//鑾峰彇浜嬩欢鍚嶇О { - if (event->eventId == PERF_COUNT_CPU_CLOCK) { + if (event->eventId == PERF_COUNT_CPU_CLOCK) {//璇诲彇浜嬩欢ID鏄惁涓庤鏁板櫒涓殑浜嬩欢璁板綍鐩稿悓 return "timed"; } else { return "unknown"; } } -UINT32 OsTimedPmuInit(VOID) +UINT32 OsTimedPmuInit(VOID)//鍒濆鍖栧畾鏃跺櫒 { UINT32 ret; - g_perfTimed.time = (union ktime) { + g_perfTimed.time = (union ktime) {//淇濆瓨瀹氭椂鍣ㄤ俊鎭 .tv.sec = 0, .tv.usec = HRTIMER_DEFAULT_PERIOD_US, }; - hrtimer_init(&g_perfTimed.hrtimer, 1, HRTIMER_MODE_REL); + hrtimer_init(&g_perfTimed.hrtimer, 1, HRTIMER_MODE_REL);//绗竴涓弬鏁颁唬琛ㄥ畾鏃跺櫒瀵硅薄锛岀浜屼釜鍙傛暟涓烘椂闂存簮绫诲瀷锛屼唬琛ㄧ殑鏄浉瀵规椂闂达紝鏈鍚庝竴涓弬鏁颁唬琛ㄥ畾鏃跺櫒妯″紡锛岃繖閲屼娇鐢ㄧ殑鏄浉瀵规椂闂存ā寮 - ret = hrtimer_create(&g_perfTimed.hrtimer, g_perfTimed.time, OsPerfHrtimer); + ret = hrtimer_create(&g_perfTimed.hrtimer, g_perfTimed.time, OsPerfHrtimer);//鍒涘缓瀹氭椂鍣 if (ret != LOS_OK) { return ret; } g_perfTimed.pmu = (Pmu) { - .type = PERF_EVENT_TYPE_TIMED, - .config = OsPerfTimedConfig, - .start = OsPerfTimedStart, - .stop = OsPerfTimedStop, - .getName = OsPerfGetEventName, + .type = PERF_EVENT_TYPE_TIMED,//姝ゆц兘璁℃暟鍣ㄦ槸瀹氭椂鍣ㄧ被鍨 + .config = OsPerfTimedConfig,//鎬ц兘璁℃暟鍣ㄧ殑浜嬩欢閰嶇疆 + .start = OsPerfTimedStart,//鍚姩 + .stop = OsPerfTimedStop,//鍋滄 + .getName = OsPerfGetEventName,//鑾峰彇浜嬩欢鍚嶇О }; (VOID)memset_s(&g_perfTimed.pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); + //鎵ц瀹屼箣鍚庢竻闆朵簨浠剁粨鏋勪綋锛屽苟鍦ㄤ笅闈㈣繘琛岀姸鎬佺爜鐨勬敞鍐岃鍙 ret = OsPerfPmuRegister(&g_perfTimed.pmu); - return ret; + return ret;//杩斿洖鍊间负鍒濆鍖栫姸鎬佺爜 } #ifdef __cplusplus diff --git a/src/kernel/extended/杞欢宸ョ▼浠g爜闃呰锛堝垵绋匡級-浣曚匠鑱-.docx b/src/kernel/extended/杞欢宸ョ▼浠g爜闃呰锛堝垵绋匡級-浣曚匠鑱-.docx new file mode 100644 index 0000000..4d112b6 Binary files /dev/null and b/src/kernel/extended/杞欢宸ョ▼浠g爜闃呰锛堝垵绋匡級-浣曚匠鑱-.docx differ diff --git a/src/kernel/include/arch_generic/atomic.h b/src/kernel/include/arch_generic/atomic.h index 2b68336..81dc858 100644 --- a/src/kernel/include/arch_generic/atomic.h +++ b/src/kernel/include/arch_generic/atomic.h @@ -31,6 +31,7 @@ * @ingroup kernel */ +//在LiteOS操作系统中,atomic.h头文件通常用于提供原子操作的支持。原子操作是不可中断的操作,它可以确保在多线程环境中对共享资源进行安全的访问和修改。 #ifndef _ARCH_GENERIC_ATOMIC_H #define _ARCH_GENERIC_ATOMIC_H @@ -44,17 +45,26 @@ extern "C" { #endif /* __cplusplus */ #ifndef LOSCFG_KERNEL_SMP - +/*ArchAtomicRead 函数用于原子读取一个整数变量的值。 +它将一个指向原子变量的指针 v 强制转换为 volatile INT32 类型的指针, +并返回该指针所指向的值。*/ STATIC INLINE INT32 ArchAtomicRead(const Atomic *v) { return *(volatile INT32 *)v; } +/*ArchAtomicSet 函数用于原子设置一个整数变量的值。 +它将一个指向原子变量的指针 v 强制转换为 volatile INT32 类型的指针, +并将 setVal 的值赋给该指针所指向的变量。*/ STATIC INLINE VOID ArchAtomicSet(Atomic *v, INT32 setVal) { *(volatile INT32 *)v = setVal; } +/*ArchAtomicAdd 函数用于原子增加一个整数变量的值。 +它先保存当前中断状态,然后在关闭中断的情况下,将 addVal 加到指针 v 所指向的变量上, +并返回增加后的值。 +最后,恢复之前保存的中断状态。*/ STATIC INLINE INT32 ArchAtomicAdd(Atomic *v, INT32 addVal) { UINT32 intSave; @@ -66,6 +76,9 @@ STATIC INLINE INT32 ArchAtomicAdd(Atomic *v, INT32 addVal) return *v; } +/*ArchAtomicSub 函数用于原子减少一个整数变量的值。 +它的实现与 ArchAtomicAdd 类似, +只是将 subVal 减去指针 v 所指向的变量。*/ STATIC INLINE INT32 ArchAtomicSub(Atomic *v, INT32 subVal) { UINT32 intSave; @@ -77,6 +90,10 @@ STATIC INLINE INT32 ArchAtomicSub(Atomic *v, INT32 subVal) return *v; } +/*ArchAtomicInc 函数用于原子增加一个整数变量的值。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下, +将指针 addr 指向的变量加 1, +最后恢复之前保存的中断状态。*/ STATIC INLINE VOID ArchAtomicInc(Atomic *addr) { UINT32 intSave; @@ -86,6 +103,7 @@ STATIC INLINE VOID ArchAtomicInc(Atomic *addr) LOS_IntRestore(intSave); } +//ArchAtomicIncRet 函数与 ArchAtomicInc 类似,但它还返回增加后的变量值。 STATIC INLINE INT32 ArchAtomicIncRet(Atomic *addr) { UINT32 intSave; @@ -96,6 +114,7 @@ STATIC INLINE INT32 ArchAtomicIncRet(Atomic *addr) return *addr; } +//ArchAtomicDec 函数用于原子减少一个整数变量的值。它的实现类似于 ArchAtomicInc,只是将指针 addr 指向的变量减 1。 STATIC INLINE VOID ArchAtomicDec(Atomic *addr) { UINT32 intSave; @@ -105,6 +124,7 @@ STATIC INLINE VOID ArchAtomicDec(Atomic *addr) LOS_IntRestore(intSave); } +//ArchAtomicDecRet 函数与 ArchAtomicDec 类似,但它还返回减少后的变量值。 STATIC INLINE INT32 ArchAtomicDecRet(Atomic *addr) { UINT32 intSave; @@ -115,6 +135,10 @@ STATIC INLINE INT32 ArchAtomicDecRet(Atomic *addr) return *addr; } +/*ArchAtomic64Read 函数用于原子读取一个 64 位整数变量的值。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下, +读取指针 v 指向的 64 位整数变量的值, +最后恢复之前保存的中断状态,并返回读取的值。*/ STATIC INLINE INT64 ArchAtomic64Read(const Atomic64 *v) { UINT32 intSave; @@ -127,6 +151,10 @@ STATIC INLINE INT64 ArchAtomic64Read(const Atomic64 *v) return val; } +/*ArchAtomic64Set 函数用于原子设置一个 64 位整数变量的值为 setVal。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下, +将指针 v 指向的变量设置为 setVal, +最后恢复之前保存的中断状态。*/ STATIC INLINE VOID ArchAtomic64Set(Atomic64 *v, INT64 setVal) { UINT32 intSave; @@ -136,6 +164,10 @@ STATIC INLINE VOID ArchAtomic64Set(Atomic64 *v, INT64 setVal) LOS_IntRestore(intSave); } +/*ArchAtomic64Add 函数用于原子增加一个 64 位整数变量的值。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下, +将指针 v 指向的变量增加 addVal,然后将增加后的值赋给变量 val, +最后恢复之前保存的中断状态,并返回 val。*/ STATIC INLINE INT64 ArchAtomic64Add(Atomic64 *v, INT64 addVal) { UINT32 intSave; @@ -149,6 +181,9 @@ STATIC INLINE INT64 ArchAtomic64Add(Atomic64 *v, INT64 addVal) return val; } +/*ArchAtomic64Sub 函数用于原子减少一个 64 位整数变量的值。 +它的实现类似于 ArchAtomic64Add, +只是将指针 v 指向的变量减去 subVal。*/ STATIC INLINE INT64 ArchAtomic64Sub(Atomic64 *v, INT64 subVal) { UINT32 intSave; @@ -162,6 +197,8 @@ STATIC INLINE INT64 ArchAtomic64Sub(Atomic64 *v, INT64 subVal) return val; } +/*ArchAtomic64Inc 函数用于原子增加一个 64 位整数变量的值。 +它的实现类似于 ArchAtomic64Add,只是将增加的值固定为 1。*/ STATIC INLINE VOID ArchAtomic64Inc(Atomic64 *v) { UINT32 intSave; @@ -171,6 +208,7 @@ STATIC INLINE VOID ArchAtomic64Inc(Atomic64 *v) LOS_IntRestore(intSave); } +//ArchAtomic64IncRet 函数与 ArchAtomic64Inc 类似,但它还返回增加后的变量值。 STATIC INLINE INT64 ArchAtomic64IncRet(Atomic64 *v) { UINT32 intSave; @@ -184,6 +222,9 @@ STATIC INLINE INT64 ArchAtomic64IncRet(Atomic64 *v) return val; } +/*ArchAtomic64Dec 函数用于原子减少一个 64 位整数变量的值。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下,将指针 v 指向的变量减去 1, +最后恢复之前保存的中断状态。*/ STATIC INLINE VOID ArchAtomic64Dec(Atomic64 *v) { UINT32 intSave; @@ -193,6 +234,7 @@ STATIC INLINE VOID ArchAtomic64Dec(Atomic64 *v) LOS_IntRestore(intSave); } +//ArchAtomic64DecRet 函数与 ArchAtomic64Dec 类似,但它还返回减少后的变量值。 STATIC INLINE INT64 ArchAtomic64DecRet(Atomic64 *v) { UINT32 intSave; @@ -206,6 +248,10 @@ STATIC INLINE INT64 ArchAtomic64DecRet(Atomic64 *v) return val; } +/*ArchAtomicXchg32bits 函数用于原子交换一个 32 位整数变量的值。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下, +将指针 v 指向的变量的值赋给 prevVal,再将变量 v 的值设置为 val, +最后恢复之前保存的中断状态,并返回原先的值 prevVal。*/ STATIC INLINE INT32 ArchAtomicXchg32bits(Atomic *v, INT32 val) { UINT32 intSave; @@ -219,6 +265,7 @@ STATIC INLINE INT32 ArchAtomicXchg32bits(Atomic *v, INT32 val) return prevVal; } +//ArchAtomicXchg64bits 函数类似于 ArchAtomicXchg32bits,但它用于原子交换一个 64 位整数变量的值。 STATIC INLINE INT64 ArchAtomicXchg64bits(Atomic64 *v, INT64 val) { UINT32 intSave; @@ -232,6 +279,11 @@ STATIC INLINE INT64 ArchAtomicXchg64bits(Atomic64 *v, INT64 val) return prevVal; } +/*ArchAtomicCmpXchg32bits 函数用于原子比较和交换一个 32 位整数变量的值。 +它首先保存当前中断状态 intSave,然后在关闭中断的情况下, +将指针 v 指向的变量的值赋给 prevVal,接着判断 prevVal 是否等于 oldVal, +如果相等,则将变量 v 的值设置为 val,最后恢复之前保存的中断状态, +并返回是否执行了交换操作的布尔值。*/ STATIC INLINE BOOL ArchAtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) { UINT32 intSave; @@ -247,6 +299,7 @@ STATIC INLINE BOOL ArchAtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) return (prevVal != oldVal); } +//ArchAtomicCmpXchg64bits 函数类似于 ArchAtomicCmpXchg32bits,但它用于原子比较和交换一个 64 位整数变量的值。 STATIC INLINE BOOL ArchAtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal) { UINT32 intSave; diff --git a/src/kernel/include/console.h b/src/kernel/include/console.h index a0f102a..e57aba9 100644 --- a/src/kernel/include/console.h +++ b/src/kernel/include/console.h @@ -25,18 +25,18 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --------------------------------------------------------------------------- */ - +//在LiteOS操作系统中,console头文件通常用于定义与控制台交互相关的函数和数据结构。 #ifndef _CONSOLE_H #define _CONSOLE_H - -#include "los_config.h" -#ifdef LOSCFG_FS_VFS -#include "termios.h" -#ifdef LOSCFG_NET_TELNET -#include "telnet_dev.h" -#endif -#include "virtual_serial.h" -#include "los_ringbuf.h" +//代码中,首先使用了条件编译防护,以确保头文件内容只被包含一次。接着定义了控制台输入输出缓冲区的大小,并声明了控制台初始化、打印和读取等函数。 +#include "los_config.h"//引用了系统配置文件,用于获取操作系统的一些设置和属性。 +#ifdef LOSCFG_FS_VFS//使用条件编译指令判断是否定义了宏LOSCFG_FS_VFS,如果已经定义,则编译下面的代码块,否则跳过。 +#include "termios.h"//包含了 POSIX 终端控制定义的头文件,用于对终端进行控制。 +#ifdef LOSCFG_NET_TELNET//使用条件编译指令判断是否定义了宏,如果已经定义,则编译下面的代码块,否则跳过。 +#include "telnet_dev.h"//包含了 Telnet 设备驱动的头文件,用于实现 Telnet 连接。 +#endif//结束条件编译指令。 +#include "virtual_serial.h"//包含了虚拟串口的头文件,用于实现虚拟串口的功能。 +#include "los_ringbuf.h"//包含了环形缓冲区的头文件,用于实现缓冲区的读写操作。 #endif #ifdef __cplusplus @@ -57,76 +57,76 @@ extern "C" { #define CONSOLE "/dev/console" #define CONSOLE_NAMELEN 16 - -#define CONSOLE_CMD_RD_BLOCK_SERIAL 0x104 -#define CONSOLE_CMD_RD_BLOCK_TELNET 101 -#define CONSOLE_RD_BLOCK 1 -#define CONSOLE_RD_NONBLOCK 0 -#define CONSOLE_SHELL_KEY_EVENT 0x112 -#define CONSOLE_SHELL_EXITED 0x400 -#define CONSOLE_CONTROL_RIGHTS_CAPTURE 201 -#define CONSOLE_CONTROL_RIGHTS_RELEASE 202 -#define CONSOLE_CONTROL_CAPTURE_LINE 203 -#define CONSOLE_CONTROL_CAPTURE_CHAR 204 -#define CONSOLE_FIFO_SIZE 1024 -#define CONSOLE_NUM 2 +//这段代码定义了一些宏和常量,它们的含义如下: +#define CONSOLE_CMD_RD_BLOCK_SERIAL 0x104//表示从串口读取数据的阻塞命令,其值为0x104。 +#define CONSOLE_CMD_RD_BLOCK_TELNET 101//表示从Telnet连接读取数据的阻塞命令,其值为101。 +#define CONSOLE_RD_BLOCK 1//表示阻塞模式,其值为1。 +#define CONSOLE_RD_NONBLOCK 0//表示非阻塞模式,其值为0。 +#define CONSOLE_SHELL_KEY_EVENT 0x112//表示shell键盘事件,其值为0x112。 +#define CONSOLE_SHELL_EXITED 0x400//表示shell已退出,其值为0x400。 +#define CONSOLE_CONTROL_RIGHTS_CAPTURE 201//表示控制权被捕获,其值为201。 +#define CONSOLE_CONTROL_RIGHTS_RELEASE 202//表示控制权被释放,其值为202。 +#define CONSOLE_CONTROL_CAPTURE_LINE 203//表示捕获行命令,其值为203。 +#define CONSOLE_CONTROL_CAPTURE_CHAR 204//表示捕获字符命令,其值为204。 +#define CONSOLE_FIFO_SIZE 1024//表示控制台FIFO(First In First Out)缓冲区大小,其值为1024。 +#define CONSOLE_NUM 2//表示控制台数量,其值为2。 typedef struct { - Ringbuf ringbuf; /* Ring buffer */ - EVENT_CB_S sendEvent; /* Inform telnet send task */ + Ringbuf ringbuf; /* Ring buffer *///表示环形缓冲区,它可能是一个用于缓存数据的循环队列或者环形链表。 + EVENT_CB_S sendEvent; /* Inform telnet send task *///表示向telnet发送任务发送事件的回调函数。 } RingbufSendCB; typedef struct { - UINT32 consoleID; - UINT32 consoleType; - UINT32 consoleSem; - UINT32 shellEntryId; - UINT32 consoleMask; - struct inode *devInode; - CHAR *name; - INT32 fd; - UINT32 refCount; - BOOL isNonBlock; + UINT32 consoleID;//表示控制台的ID。 + UINT32 consoleType;//表示控制台的类型。 + UINT32 consoleSem;//表示用于同步的控制台信号量。 + UINT32 shellEntryId;//表示shell的入口ID。 + UINT32 consoleMask;//表示控制台的掩码。 + struct inode *devInode;//表示设备节点。 + CHAR *name;//表示控制台的名称。 + INT32 fd;//表示文件描述符。 + UINT32 refCount;//表示引用计数。 + BOOL isNonBlock;//表示是否为非阻塞模式。 #ifdef LOSCFG_SHELL - VOID *shellHandle; + VOID *shellHandle;//表示shell的句柄。 #endif - UINT32 sendTaskID; - RingbufSendCB *ringbufSendCB; - UINT8 fifo[CONSOLE_FIFO_SIZE]; - UINT32 fifoOut; - UINT32 fifoIn; - UINT32 currentLen; - struct termios consoleTermios; + UINT32 sendTaskID;//表示发送任务的ID。 + RingbufSendCB *ringbufSendCB;//表示环形缓冲区发送回调。 + UINT8 fifo[CONSOLE_FIFO_SIZE];//表示控制台的FIFO缓冲区。 + UINT32 fifoOut;//表示FIFO缓冲区的输出位置。 + UINT32 fifoIn;//表示FIFO缓冲区的输入位置。 + UINT32 currentLen;//表示当前长度。 + struct termios consoleTermios;//表示控制台的终端属性。 } CONSOLE_CB; -extern INT32 system_console_init(const CHAR *deviceName); -extern INT32 system_console_deinit(const CHAR *deviceName); -extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB); -extern BOOL SetSerialBlock(const CONSOLE_CB *consoleCB); -extern BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB); -extern BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB); -extern CONSOLE_CB *OsGetConsoleByID(INT32 consoleId); -extern CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskId); -extern UINT32 ConsoleTaskReg(INT32 consoleId, UINT32 taskId); -extern INT32 ConsoleUpdateFd(VOID); -extern BOOL ConsoleEnable(VOID); -extern BOOL is_nonblock(const CONSOLE_CB *consoleCB); -extern BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB); -extern INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops); -extern INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops); -extern INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen); -extern INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen); -extern INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds); -extern INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg); -extern INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops); +extern INT32 system_console_init(const CHAR *deviceName);//控制台初始化函数用于初始化控制台相关的资源和状态 +extern INT32 system_console_deinit(const CHAR *deviceName);//控制台反初始化函数,用于释放控制台相关的资源和状态。 +extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB);//设置串口为非阻塞模式。 +extern BOOL SetSerialBlock(const CONSOLE_CB *consoleCB);//设置串口为阻塞模式。 +extern BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB);//设置Telnet连接为非阻塞模式。 +extern BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB);//设置Telnet连接为阻塞模式。 +extern CONSOLE_CB *OsGetConsoleByID(INT32 consoleId);//根据控制台ID获取控制台的控制块(Control Block)。 +extern CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskId);//根据任务ID获取关联的控制台的控制块。 +extern UINT32 ConsoleTaskReg(INT32 consoleId, UINT32 taskId);//将任务与指定的控制台进行关联。 +extern INT32 ConsoleUpdateFd(VOID);//更新控制台的文件描述符(File Descriptor)。 +extern BOOL ConsoleEnable(VOID);//使能控制台功能。 +extern BOOL is_nonblock(const CONSOLE_CB *consoleCB);//判断控制台是否为非阻塞模式。 +extern BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB);//判断控制台是否已经被占用。 +extern INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops);//打开文件。 +extern INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops);//关闭文件。 +extern INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen);//从文件中读取数据。 +extern INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen);//向文件中写入数据。 +extern INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds);//对文件进行轮询操作。 +extern INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg);//对文件进行IO控制操作。 +extern INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops);//获取文件的操作函数。 #else -STATIC INLINE INT32 ConsoleUpdateFd(VOID) +STATIC INLINE INT32 ConsoleUpdateFd(VOID)//这是一个函数声明,声明了一个名为ConsoleUpdateFd的静态内联函数,返回类型为INT32(32位整数),参数为空。根据函数体的实现为return -1;,该函数的作用是更新控制台的文件描述符(File Descriptor),并返回-1。 { return -1; } -#endif +#endif//这个宏表示结束了之前的条件编译指令#if。 -#ifdef __cplusplus +#ifdef __cplusplus//这一组条件编译指令用于判断是否为C++编译环境。如果是C++编译环境,则将后面的代码块用extern "C"包裹起来,以保证C和C++之间的函数调用规则一致。 #if __cplusplus } #endif /* __cplusplus */ diff --git a/src/kernel/include/los_atomic.h b/src/kernel/include/los_atomic.h index 05fff5f..eaf9204 100644 --- a/src/kernel/include/los_atomic.h +++ b/src/kernel/include/los_atomic.h @@ -30,12 +30,12 @@ * @defgroup los_atomic Atomic * @ingroup kernel */ - -#ifndef _LOS_ATOMIC_H -#define _LOS_ATOMIC_H +//los_atomic.h是用于支持原子操作的头文件。 +#ifndef _LOS_ATOMIC_H//表示如果宏变量 _LOS_ATOMIC_H 没有被定义过,则执行以下代码,否则忽略这段代码。 +#define _LOS_ATOMIC_H//是定义一个宏变量,可以用来判断这个头文件是否已经被包含过。 #include "los_typedef.h" -#include "arch/atomic.h" +#include "arch/atomic.h"//是平台相关的原子操作头文件,具体实现依赖于不同的硬件平台。 #ifdef __cplusplus #if __cplusplus @@ -60,7 +60,7 @@ extern "C" { * @see LOS_Atomic64Read * @since Huawei LiteOS V200R003C00 */ -STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v) +STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v)//函数接受一个Atomic类型的指针参数v,并返回一个32位整数。用于读取指定内存位置的原子变量的值。 { return ArchAtomicRead(v); } @@ -84,7 +84,7 @@ STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v) * @see LOS_Atomic64Set * @since Huawei LiteOS V200R003C00 */ -STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal) +STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal)//函数接受一个Atomic类型的指针参数v和一个32位整数setVal,没有返回值(返回类型为VOID)。 { ArchAtomicSet(v, setVal); } @@ -114,7 +114,7 @@ STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal) */ STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal) { - return ArchAtomicAdd(v, addVal); + return ArchAtomicAdd(v, addVal);//用于将指定内存位置的原子变量增加指定的值。 } /** @@ -142,7 +142,7 @@ STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal) */ STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal) { - return ArchAtomicSub(v, subVal); + return ArchAtomicSub(v, subVal);//用于将指定内存位置的原子变量减少指定的值。 } /** @@ -168,7 +168,7 @@ STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal) */ STATIC INLINE VOID LOS_AtomicInc(Atomic *v) { - ArchAtomicInc(v); + ArchAtomicInc(v);//用于将指定内存位置的原子变量增加1。 } /** @@ -222,7 +222,7 @@ STATIC INLINE INT32 LOS_AtomicIncRet(Atomic *v) */ STATIC INLINE VOID LOS_AtomicDec(Atomic *v) { - ArchAtomicDec(v); + ArchAtomicDec(v);//该函数通常是由特定的体系结构提供的原子递减函数的实现。通过使用内联函数和宏定义,可以在编译时将这段代码直接嵌入到调用处,从而提高执行效率和节省函数调用的开销。 } /** @@ -248,7 +248,7 @@ STATIC INLINE VOID LOS_AtomicDec(Atomic *v) */ STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v) { - return ArchAtomicDecRet(v); + return ArchAtomicDecRet(v);//该函数通常是由特定的体系结构提供的原子递减操作并返回递减后的值的函数。 } /** @@ -270,7 +270,7 @@ STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v) */ STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v) { - return ArchAtomic64Read(v); + return ArchAtomic64Read(v);//该函数通常是由特定的体系结构提供的原子读取操作的函数。 } /** @@ -294,7 +294,7 @@ STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v) */ STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal) { - ArchAtomic64Set(v, setVal); + ArchAtomic64Set(v, setVal);//该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -322,7 +322,7 @@ STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal) */ STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal) { - return ArchAtomic64Add(v, addVal); + return ArchAtomic64Add(v, addVal);//函数来完成原子加操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -350,7 +350,7 @@ STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal) */ STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal) { - return ArchAtomic64Sub(v, subVal); + return ArchAtomic64Sub(v, subVal);//函数来完成原子减操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -376,7 +376,7 @@ STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal) */ STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v) { - ArchAtomic64Inc(v); + ArchAtomic64Inc(v);//函数来完成原子增加操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -403,7 +403,7 @@ STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v) */ STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v) { - return ArchAtomic64IncRet(v); + return ArchAtomic64IncRet(v);//函数来完成原子增加操作并返回增加后的值,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -430,7 +430,7 @@ STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v) */ STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v) { - ArchAtomic64Dec(v); + ArchAtomic64Dec(v);//函数来完成原子减少操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -456,7 +456,7 @@ STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v) */ STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v) { - return ArchAtomic64DecRet(v); + return ArchAtomic64DecRet(v);//函数来完成原子减少操作并返回减少后的值,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -480,7 +480,7 @@ STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v) */ STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val) { - return ArchAtomicXchg32bits(v, val); + return ArchAtomicXchg32bits(v, val);//函数来完成原子交换操作并返回交换前的值,该函数应该是由底层的架构代码提供的,用于实现 32 位整数的原子操作。 } /** @@ -504,7 +504,7 @@ STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val) */ STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val) { - return ArchAtomicXchg64bits(v, val); + return ArchAtomicXchg64bits(v, val);//函数来完成原子交换操作并返回交换前的值,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } /** @@ -531,7 +531,7 @@ STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val) */ STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) { - return ArchAtomicCmpXchg32bits(v, val, oldVal); + return ArchAtomicCmpXchg32bits(v, val, oldVal);//函数来完成原子比较和交换操作,并返回比较结果,该函数应该是由底层的架构代码提供的,用于实现 32 位整数的原子操作。 } /** @@ -558,7 +558,7 @@ STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) */ STATIC INLINE BOOL LOS_AtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal) { - return ArchAtomicCmpXchg64bits(v, val, oldVal); + return ArchAtomicCmpXchg64bits(v, val, oldVal);//函数来完成原子比较和交换操作,并返回比较结果,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。 } #ifdef __cplusplus diff --git a/src/kernel/include/los_base.h b/src/kernel/include/los_base.h index a4544a5..bf1e570 100644 --- a/src/kernel/include/los_base.h +++ b/src/kernel/include/los_base.h @@ -75,19 +75,19 @@ extern "C" { * @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). @@ -111,8 +111,8 @@ extern "C" { * @see LOS_Align | TRUNCATE * @since Huawei LiteOS V100R001C00 */ -#ifndef ALIGN -#define ALIGN(addr, boundary) LOS_Align(addr, boundary) +#ifndef ALIGN//判断ALIGN是否已经被定义过,如果没有被定义过,则执行接下来的代码。 +#define ALIGN(addr, boundary) LOS_Align(addr, boundary)//分别表示需要对齐的地址和对齐边界。在函数体内部,它调用了LOS_Align函数进行地址对齐操作,将addr地址向上对齐到最接近的boundary的倍数。 #endif /** @@ -139,10 +139,16 @@ extern "C" { * @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(); }) /** @@ -155,6 +161,9 @@ extern "C" { */ #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. @@ -162,6 +171,11 @@ extern "C" { #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. */ @@ -177,6 +191,8 @@ extern "C" { */ #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. @@ -187,11 +203,13 @@ extern "C" { /** * 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; }) /** @@ -199,6 +217,8 @@ extern "C" { */ #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. @@ -226,7 +246,7 @@ extern "C" { * @see LOS_ASSERT_COND * @since Huawei LiteOS V100R001C00 */ -#ifdef LOSCFG_DEBUG_VERSION +#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(); \ @@ -234,8 +254,12 @@ extern "C" { while (1) {} \ } \ } while (0) +//在调试版本下,宏定义的代码块中,LOS_ASSERT 宏被定义为一个带有参数 judge 的宏函数。它的作用是进行断言检查,如果 judge 表达式的结果为零(即假),则执行以上操作 +//调用 LOS_IntLock() 函数,该函数可能是一个用于禁止中断的操作,以确保在断言失败时不会中断处理。 +//使用 PRINT_ERR 打印一条错误信息,其中包含了出错的文件名、行号和函数名。 +//进入一个无限循环 while (1),程序会一直停留在这个循环中。 #else -#define LOS_ASSERT(judge) +#define LOS_ASSERT(judge)//在非调试版本下,宏定义的代码块中,LOS_ASSERT 宏被定义为空,即不进行任何操作。 #endif /** @@ -261,7 +285,8 @@ extern "C" { * @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. diff --git a/src/kernel/include/los_bitmap.h b/src/kernel/include/los_bitmap.h index 81bfb8f..b05e472 100644 --- a/src/kernel/include/los_bitmap.h +++ b/src/kernel/include/los_bitmap.h @@ -31,7 +31,7 @@ * @ingroup kernel */ -#ifndef _LOS_BITMAP_H +#ifndef _LOS_BITMAP_H//这段代码是一个条件编译指令块,用于判断是否定义了宏 _LOS_BITMAP_H。如果未定义该宏,则会执行 #ifndef 和 #endif 之间的代码。 #define _LOS_BITMAP_H #include "los_typedef.h" @@ -48,6 +48,7 @@ extern "C" { * * The effective bit index is from 0 to 31. */ +//由于这里宏定义的值为 32,这个宏的含义是使用 0 到 31 的整数表示位索引值,而 32 则表示无效的位索引值。这种处理方式在计算机编程中比较常见,一般用于标识某些特殊的状态或标志。 #define LOS_INVALID_BIT_INDEX 32 /** @@ -69,6 +70,9 @@ extern "C" { * @see LOS_BitmapClr * @since Huawei LiteOS V100R001C00 */ +/*bitmap 是一个指向 UINT32 类型的指针,表示一个位图(或称为位数组)。 +pos 是一个 UINT16 类型的参数,表示要设置的位索引。 +函数的作用是在给定的位图中将指定的位索引位置设为 1,即将相应位置的比特位设置为 1。*/ VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos); /** @@ -90,6 +94,9 @@ VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos); * @see LOS_BitmapSet. * @since Huawei LiteOS V100R001C00 */ +/*bitmap 是一个指向 UINT32 类型的指针,表示一个位图(或称为位数组)。 +pos 是一个 UINT16 类型的参数,表示要清除的位索引。 +函数的作用是在给定的位图中将指定的位索引位置清零,即将相应位置的比特位设置为 0。*/ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos); /** @@ -108,6 +115,12 @@ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos); * @see LOS_HighBitGet * @since Huawei LiteOS V100R001C00 */ +/*函数的作用是在给定的位图中找到最低位(也就是数值最小的位)的索引, +并返回该索引。如果位图中不存在任何置位的比特位, +则返回 32,即宏 LOS_INVALID_BIT_INDEX 的值。 +具体实现可能会涉及位运算和掩码操作, +以找到最低位的索引号。由于函数返回类型为 UINT16, +即 unsigned short 类型,因此返回值为 0 到 31 的整数(包括 0 和 31)或 32*/ UINT16 LOS_LowBitGet(UINT32 bitmap); /** @@ -126,6 +139,12 @@ UINT16 LOS_LowBitGet(UINT32 bitmap); * @see LOS_LowBitGet * @since Huawei LiteOS V100R001C00 */ +/*函数的作用是在给定的位图中找到最高位(也就是数值最大的位)的索引, +并返回该索引。如果位图中不存在任何置位的比特位, +则返回 32,即宏 LOS_INVALID_BIT_INDEX 的值。 +具体实现可能会涉及位运算和掩码操作,以找到最高位的索引号。 +由于函数返回类型为 UINT16,即 unsigned short 类型, +因此返回值为 0 到 31 的整数(包括 0 和 31)或 32。*/ UINT16 LOS_HighBitGet(UINT32 bitmap); #ifdef __cplusplus diff --git a/src/kernel/include/los_builddef.h b/src/kernel/include/los_builddef.h index 894fd80..192d90a 100644 --- a/src/kernel/include/los_builddef.h +++ b/src/kernel/include/los_builddef.h @@ -35,79 +35,79 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define OS_LITTLE_ENDIAN 0x1234 /* Little endian */ -#define OS_BIG_ENDIAN 0x4321 /* Big endian */ +#define OS_LITTLE_ENDIAN 0x1234 /* Little endian *///表示小端序,数值为 0x1234 +#define OS_BIG_ENDIAN 0x4321 /* Big endian *///表示大端序,数值为 0x4321 #ifndef OS_BYTE_ORDER -#define OS_BYTE_ORDER OS_LITTLE_ENDIAN +#define OS_BYTE_ORDER OS_LITTLE_ENDIAN//如果未定义 OS_BYTE_ORDER,则将其设置为 OS_LITTLE_ENDIAN #endif /* Define OS code data sections */ /* The indicator function is inline */ #ifndef LITE_OS_SEC_ALW_INLINE -#define LITE_OS_SEC_ALW_INLINE /* __attribute__((always_inline)) */ +#define LITE_OS_SEC_ALW_INLINE /* __attribute__((always_inline)) *///定义了一个宏,用于将函数声明为内联函数 #endif #ifndef LITE_OS_SEC_TEXT -#define LITE_OS_SEC_TEXT /* __attribute__((section(".text.sram"))) */ +#define LITE_OS_SEC_TEXT /* __attribute__((section(".text.sram"))) *///定义了一个宏,用于将代码段放置在 .text.sram 段中 #endif #ifndef LITE_OS_SEC_TEXT_MINOR -#define LITE_OS_SEC_TEXT_MINOR /* __attribute__((section(".text.ddr"))) */ +#define LITE_OS_SEC_TEXT_MINOR /* __attribute__((section(".text.ddr"))) *///定义了一个宏,用于将代码段放置在 .text.ddr 段中 #endif #ifndef LITE_OS_SEC_TEXT_INIT -#define LITE_OS_SEC_TEXT_INIT /* __attribute__((section(".text.init"))) */ +#define LITE_OS_SEC_TEXT_INIT /* __attribute__((section(".text.init"))) *///宏定义了一个代码段,用于放置初始化代码,其位置在 .text.init 段中。 #endif #ifndef LITE_OS_SEC_DATA -#define LITE_OS_SEC_DATA /* __attribute__((section(".data.sram"))) */ +#define LITE_OS_SEC_DATA /* __attribute__((section(".data.sram"))) *///宏定义了一个数据段,用于放置数据,其位置在 .data.sram 段中。 #endif #ifndef LITE_OS_SEC_DATA_MINOR -#define LITE_OS_SEC_DATA_MINOR /* __attribute__((section(".data.ddr"))) */ +#define LITE_OS_SEC_DATA_MINOR /* __attribute__((section(".data.ddr"))) *///定义了一个次要数据段,用于放置次要的数据,其位置在 .data.ddr 段中。 #endif #ifndef LITE_OS_SEC_DATA_INIT -#define LITE_OS_SEC_DATA_INIT /* __attribute__((section(".data.init"))) */ +#define LITE_OS_SEC_DATA_INIT /* __attribute__((section(".data.init"))) *///宏定义了一个数据段,用于放置初始化数据,其位置在 .data.init 段中。 #endif #ifndef LITE_OS_SEC_DATA_VEC -#define LITE_OS_SEC_DATA_VEC __attribute__((section(".data.vector"))) +#define LITE_OS_SEC_DATA_VEC __attribute__((section(".data.vector")))//宏定义了一个数据段,用于放置向量表数据,其位置在 .data.vector 段中。 #endif #ifndef LITE_OS_SEC_BSS -#define LITE_OS_SEC_BSS /* __attribute__((section(".bss.sram"))) */ +#define LITE_OS_SEC_BSS /* __attribute__((section(".bss.sram"))) *///宏定义了一个数据段,用于放置未初始化的数据(BSS段),其位置在 .bss.sram 段中。 #endif #ifndef LITE_OS_SEC_BSS_MINOR -#define LITE_OS_SEC_BSS_MINOR /* __attribute__((section(".bss.ddr"))) */ +#define LITE_OS_SEC_BSS_MINOR /* __attribute__((section(".bss.ddr"))) */// 宏定义了一个数据段,用于放置未初始化的次要数据(BSS段),其位置在 .bss.ddr 段中。 #endif #ifndef LITE_OS_SEC_BSS_INIT -#define LITE_OS_SEC_BSS_INIT /* __attribute__((section(".bss.init"))) */ +#define LITE_OS_SEC_BSS_INIT /* __attribute__((section(".bss.init"))) *///宏定义了一个数据段,用于放置未初始化的初始化数据(BSS段),其位置在 .bss.init 段中。 #endif #ifndef LITE_OS_SEC_ITCM -#define LITE_OS_SEC_ITCM /* __attribute__((section(".itcm "))) */ +#define LITE_OS_SEC_ITCM /* __attribute__((section(".itcm "))) */// 宏定义了一个代码段,用于放置代码(指令)和只读数据,在 ITCM 中运行。 ITCM 与其他内存有所不同,它位于 CPU 内部,具有高速访问和低延迟的优势。 #endif #ifndef LITE_OS_SEC_DTCM -#define LITE_OS_SEC_DTCM /* __attribute__((section(".dtcm"))) */ +#define LITE_OS_SEC_DTCM /* __attribute__((section(".dtcm"))) *///宏定义了一个数据段,用于放置数据,位于 DTCM 中。 DTCM 与其他内存有所不同,它位于 CPU 内部,具有高速访问和低延迟的优势。 #endif -#define PACK1 +#define PACK1//宏定义了一个结构体成员变量的对齐方式,将结构体的成员变量紧密地打包在一起,不使用空间来对齐。 #ifndef LITE_OS_ATTR_SEC -#define LITE_OS_ATTR_SEC(name) __attribute__((section(#name))) +#define LITE_OS_ATTR_SEC(name) __attribute__((section(#name)))//宏定义了一个函数或变量所在的段,通过 #name 将 name 转换为字符串,将函数或变量放置到指定名称的段中。 #endif #ifndef LITE_OS_ATTR_ALIGN -#define LITE_OS_ATTR_ALIGN(x) __attribute__((aligned(x))) +#define LITE_OS_ATTR_ALIGN(x) __attribute__((aligned(x)))//宏定义了数据的对齐方式,即几个字节对齐,x 表示对齐的字节数。 #endif #ifndef LITE_OS_ATTR_SEC_ALIGN -#define LITE_OS_ATTR_SEC_ALIGN(name, x) __attribute__((section(#name), aligned(x))) +#define LITE_OS_ATTR_SEC_ALIGN(name, x) __attribute__((section(#name), aligned(x)))//宏定义了某段数据的对齐方式,即将数据放置到指定名称的段中,并按照指定的对齐方式对齐。 #endif #ifndef OS_EMBED_ASM -#define OS_EMBED_ASM __asm__ __volatile__ +#define OS_EMBED_ASM __asm__ __volatile__//宏定义了嵌入汇编指令的方式,将 asm volatile 作为嵌入汇编指令的前缀,使得编译器可以将其识别为汇编指令。 #endif #ifdef __cplusplus diff --git a/src/kernel/include/los_config.h b/src/kernel/include/los_config.h index 75b9ea0..bd14843 100644 --- a/src/kernel/include/los_config.h +++ b/src/kernel/include/los_config.h @@ -30,6 +30,22 @@ * @defgroup los_config System configuration items * @ingroup kernel */ +/*具体而言,los_config.h 文件通常包含以下内容: + +任务(Task)配置:可以定义任务的数量、优先级范围、堆栈大小等参数,以满足不同应用场景的需求。 + +中断(Interrupt)配置:可以定义中断服务例程的数量、优先级范围,以及中断处理的策略等。 + +内存管理(Memory Management)配置:可以定义动态内存分配算法、内存池的大小和数量等相关参数。 + +定时器(Timer)配置:可以定义定时器的数量、精度、触发方式等。 + +任务调度(Task Scheduling)配置:可以配置任务调度算法、时间片轮转的时间等。 + +系统时钟(System Clock)配置:可以定义系统时钟的频率、定时器的输入时钟源等。 + +通过修改 los_config.h 文件中的宏定义和全局变量,开发人员可以根据应用需求对操作系统进行定制和优化。 +然后,将修改后的 los_config.h 文件编译进入 LiteOS 内核,即可实现对操作系统行为和功能的定制化配置。*/ #ifndef _LOS_CONFIG_H #define _LOS_CONFIG_H @@ -45,53 +61,53 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#ifdef LOSCFG_LIB_CONFIGURABLE -extern UINT32 g_osSysClock; -extern UINT32 g_tickPerSecond; -extern UINT32 g_taskLimit; -extern UINT32 g_taskMinStkSize; -extern UINT32 g_taskIdleStkSize; -extern UINT32 g_taskDfltStkSize; -extern UINT32 g_taskSwtmrStkSize; -extern UINT32 g_swtmrLimit; -extern UINT32 g_semLimit; -extern UINT32 g_muxLimit; -extern UINT32 g_queueLimit; -extern UINT32 g_timeSliceTimeOut; - -extern BOOL g_nxEnabled; -extern UINTPTR g_dlNxHeapBase; -extern UINT32 g_dlNxHeapSize; - -#define LOS_GET_NX_CFG() (g_nxEnabled) -#define LOS_SET_NX_CFG(value) (g_nxEnabled = (value)) -#define LOS_GET_DL_NX_HEAP_BASE() (g_dlNxHeapBase) -#define LOS_SET_DL_NX_HEAP_BASE(addr) (g_dlNxHeapBase = (addr)) -#define LOS_GET_DL_NX_HEAP_SIZE() (g_dlNxHeapSize) -#define LOS_SET_DL_NX_HEAP_SIZE(size) (g_dlNxHeapSize = (size)) - -#define OS_SYS_CLOCK g_osSysClock -#define KERNEL_TICK_PER_SECOND g_tickPerSecond -#define KERNEL_TSK_LIMIT g_taskLimit -#define KERNEL_TSK_MIN_STACK_SIZE g_taskMinStkSize -#define KERNEL_TSK_DEFAULT_STACK_SIZE g_taskDfltStkSize -#define KERNEL_TSK_IDLE_STACK_SIZE g_taskIdleStkSize -#define KERNEL_TSK_SWTMR_STACK_SIZE g_taskSwtmrStkSize -#define KERNEL_SWTMR_LIMIT g_swtmrLimit -#define KERNEL_SEM_LIMIT g_semLimit -#define KERNEL_MUX_LIMIT g_muxLimit -#define KERNEL_QUEUE_LIMIT g_queueLimit -#define KERNEL_TIMESLICE_TIMEOUT g_timeSliceTimeOut +#ifdef LOSCFG_LIB_CONFIGURABLE//判断宏定义 LOSCFG_LIB_CONFIGURABLE 是否被定义。如果该宏被定义,那么以下变量声明将会被编译进程序中。 +extern UINT32 g_osSysClock;//系统时钟频率 +extern UINT32 g_tickPerSecond;//系统时钟滴答数 +extern UINT32 g_taskLimit;//最大任务数量 +extern UINT32 g_taskMinStkSize;//任务最小堆栈大小 +extern UINT32 g_taskIdleStkSize;//空闲任务堆栈大小 +extern UINT32 g_taskDfltStkSize;//默认任务堆栈大小 +extern UINT32 g_taskSwtmrStkSize;//软件定时器任务堆栈大小 +extern UINT32 g_swtmrLimit;//最大软件定时器数量 +extern UINT32 g_semLimit;//最大信号量数量 +extern UINT32 g_muxLimit;//最大互斥量数量 +extern UINT32 g_queueLimit;//最大队列数量 +extern UINT32 g_timeSliceTimeOut;//时间片轮转的时间 + +extern BOOL g_nxEnabled;//是否启用内存保护机制 +extern UINTPTR g_dlNxHeapBase;//内存保护机制的起始地址 +extern UINT32 g_dlNxHeapSize;//内存保护机制的大小 + +#define LOS_GET_NX_CFG() (g_nxEnabled)//宏用于获取一个名为g_nxEnabled的变量的值。 +#define LOS_SET_NX_CFG(value) (g_nxEnabled = (value))//宏用于设置一个名为g_nxEnabled的变量的值。 +#define LOS_GET_DL_NX_HEAP_BASE() (g_dlNxHeapBase)//宏用于获取一个名为g_dlNxHeapBase的变量的值。 +#define LOS_SET_DL_NX_HEAP_BASE(addr) (g_dlNxHeapBase = (addr))//宏用于设置一个名为g_dlNxHeapBase的变量的值。 +#define LOS_GET_DL_NX_HEAP_SIZE() (g_dlNxHeapSize)//宏用于获取一个名为g_dlNxHeapSize的变量的值。 +#define LOS_SET_DL_NX_HEAP_SIZE(size) (g_dlNxHeapSize = (size))//宏用于设置一个名为g_dlNxHeapSize的变量的值。 + +#define OS_SYS_CLOCK g_osSysClock//定义系统时间频率 +#define KERNEL_TICK_PER_SECOND g_tickPerSecond//定义系统时针滴答数 +#define KERNEL_TSK_LIMIT g_taskLimit//定义最大任务数量 +#define KERNEL_TSK_MIN_STACK_SIZE g_taskMinStkSize//定义任务最小堆栈大小 +#define KERNEL_TSK_DEFAULT_STACK_SIZE g_taskDfltStkSize//定义默认任务堆栈大小 +#define KERNEL_TSK_IDLE_STACK_SIZE g_taskIdleStkSize//定义默认任务堆栈大小 +#define KERNEL_TSK_SWTMR_STACK_SIZE g_taskSwtmrStkSize//定义软件定时器任务堆栈大小 +#define KERNEL_SWTMR_LIMIT g_swtmrLimit//定义最大软件定时器数量 +#define KERNEL_SEM_LIMIT g_semLimit//定义最大信号量数量 +#define KERNEL_MUX_LIMIT g_muxLimit//定义最大互斥量数量 +#define KERNEL_QUEUE_LIMIT g_queueLimit//定义最大对列数量 +#define KERNEL_TIMESLICE_TIMEOUT g_timeSliceTimeOut//定义时间片轮转的时间 #else /* LOSCFG_LIB_CONFIGURABLE */ #ifdef LOSCFG_KERNEL_NX -#define LOS_GET_NX_CFG() true -#define LOS_SET_NX_CFG(value) -#define LOS_GET_DL_NX_HEAP_BASE() LOS_DL_HEAP_BASE -#define LOS_SET_DL_NX_HEAP_BASE(addr) -#define LOS_GET_DL_NX_HEAP_SIZE() LOS_DL_HEAP_SIZE -#define LOS_SET_DL_NX_HEAP_SIZE(size) +#define LOS_GET_NX_CFG() true//获取内存保护机制是否开启的配置值,当 LOSCFG_KERNEL_NX 宏被定义时,返回 true;否则返回 false。 +#define LOS_SET_NX_CFG(value)//设置内存保护机制的配置值,该宏定义为空白,没有实际操作。 +#define LOS_GET_DL_NX_HEAP_BASE() LOS_DL_HEAP_BASE//获取内存保护机制的起始地址,当 LOSCFG_KERNEL_NX 宏被定义时,返回 LOS_DL_HEAP_BASE;否则返回 NULL。 +#define LOS_SET_DL_NX_HEAP_BASE(addr)//设置内存保护机制的起始地址,该宏定义为空白,没有实际操作。 +#define LOS_GET_DL_NX_HEAP_SIZE() LOS_DL_HEAP_SIZE//获取内存保护机制的大小,当 LOSCFG_KERNEL_NX 宏被定义时,返回 LOS_DL_HEAP_SIZE;否则返回 0。 +#define LOS_SET_DL_NX_HEAP_SIZE(size)//设置内存保护机制的大小,该宏定义为空白,没有实际操作。 #else /* LOSCFG_KERNEL_NX */ #define LOS_GET_NX_CFG() false #define LOS_SET_NX_CFG(value) @@ -101,7 +117,9 @@ extern UINT32 g_dlNxHeapSize; #define LOS_SET_DL_NX_HEAP_SIZE(size) #endif /* LOSCFG_KERNEL_NX */ -#define KERNEL_TICK_PER_SECOND LOSCFG_BASE_CORE_TICK_PER_SECOND +//这段代码是一系列宏定义,用于将一些配置参数映射到对应的宏定义。 +//这样做的目的是将配置参数与代码解耦,使得修改配置参数时只需要修改相应的宏定义,而无需修改引用该参数的代码。这样可以提高代码的可维护性和可移植性。 +#define KERNEL_TICK_PER_SECOND LOSCFG_BASE_CORE_TICK_PER_SECOND//如KERNEL_TICK_PER_SECOND宏定义为LOSCFG_BASE_CORE_TICK_PER_SECOND,意味着在代码中使用KERNEL_TICK_PER_SECOND时,实际上是使用了配置参数 #define KERNEL_TSK_LIMIT LOSCFG_BASE_CORE_TSK_LIMIT #define KERNEL_TSK_MIN_STACK_SIZE LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE #define KERNEL_TSK_DEFAULT_STACK_SIZE LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE @@ -112,27 +130,27 @@ extern UINT32 g_dlNxHeapSize; #define KERNEL_MUX_LIMIT LOSCFG_BASE_IPC_MUX_LIMIT #define KERNEL_QUEUE_LIMIT LOSCFG_BASE_IPC_QUEUE_LIMIT #define KERNEL_TIMESLICE_TIMEOUT LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT - +//最后的#endif /* LOSCFG_LIB_CONFIGURABLE */表示这组宏定义的结束,在条件LOSCFG_LIB_CONFIGURABLE不成立时,这组宏定义不起作用,因为它们是在这个条件下定义的。 #endif /* LOSCFG_LIB_CONFIGURABLE */ /** * system sections start and end address */ -extern CHAR __int_stack_start; -extern CHAR __int_stack_end; -extern CHAR __rodata_start; -extern CHAR __rodata_end; -extern CHAR __bss_start; -extern CHAR __bss_end; -extern CHAR __text_start; -extern CHAR __text_end; -extern CHAR __ram_data_start; -extern CHAR __ram_data_end; -extern CHAR __exc_heap_start; -extern CHAR __exc_heap_end; -extern CHAR __heap_start; -extern CHAR __init_array_start__; -extern CHAR __init_array_end__; +extern CHAR __int_stack_start;//内部栈的起始地址 +extern CHAR __int_stack_end;//内部栈的结束地址 +extern CHAR __rodata_start;//只读数据段的起始地址。 +extern CHAR __rodata_end;//只读数据段的结束地址。 +extern CHAR __bss_start;//未初始化的全局变量段(BSS Segment)的起始地址。 +extern CHAR __bss_end;//未初始化的全局变量段(BSS Segment)的结束地址。 +extern CHAR __text_start;//可执行代码段(Text Segment)的起始地址。 +extern CHAR __text_end;//可执行代码段(Text Segment)的结束地址。 +extern CHAR __ram_data_start;//RAM 数据段的起始地址。 +extern CHAR __ram_data_end;//RAM 数据段的结束地址。 +extern CHAR __exc_heap_start;//异常堆(Exception Heap)的起始地址。 +extern CHAR __exc_heap_end;//异常堆(Exception Heap)的结束地址。 +extern CHAR __heap_start;//堆(Heap)的起始地址。 +extern CHAR __init_array_start__;//初始化数组的起始地址。 +extern CHAR __init_array_end__; //初始化数组的结束地址。 /****************************** System clock module configuration ****************************/ /** @@ -140,24 +158,24 @@ extern CHAR __init_array_end__; * System clock (unit: HZ) */ #ifndef OS_SYS_CLOCK -#define OS_SYS_CLOCK (get_bus_clk()) +#define OS_SYS_CLOCK (get_bus_clk())//定义系统时钟频率,默认值为get_bus_clk() #endif /** * @ingroup los_config * time timer clock (unit: HZ) */ #ifndef OS_TIME_TIMER_CLOCK -#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK +#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK//定义定时器时钟频率,默认值为 OS_SYS_CLOCK #endif /** * limit addr range when search for 'func local(frame pointer)' or 'func name' */ #ifndef OS_SYS_FUNC_ADDR_START -#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start) +#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start)//定义函数起始地址,默认值为&__int_stack_start #endif #ifndef OS_SYS_FUNC_ADDR_END -#define OS_SYS_FUNC_ADDR_END g_sys_mem_addr_end +#define OS_SYS_FUNC_ADDR_END g_sys_mem_addr_end//定义函数终止地址,默认值为g_sys_mem_addr_end #endif /** @@ -165,14 +183,14 @@ extern CHAR __init_array_end__; * Microseconds of adjtime in one second */ #ifndef LOSCFG_BASE_CORE_ADJ_PER_SECOND -#define LOSCFG_BASE_CORE_ADJ_PER_SECOND 500 +#define LOSCFG_BASE_CORE_ADJ_PER_SECOND 500//每秒钟的微调时间。如果没有定义过LOSCFG_BASE_CORE_ADJ_PER_SECOND,则将其定义为500。这意味着系统在进行时间微调时,每秒钟可以微调500微秒。 #endif /** * @ingroup los_config * Sched clck interval */ -#define SCHED_CLOCK_INTETRVAL_TICKS 100 +#define SCHED_CLOCK_INTETRVAL_TICKS 100//表示调度时钟的间隔。这个宏定义的值为100,表示调度时钟的间隔为100个时钟节拍。 /****************************** Interrupt module configuration ****************************/ /** @@ -184,7 +202,7 @@ extern CHAR __init_array_end__; */ #ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION #ifndef MAX_BINARY_POINT_VALUE -#define MAX_BINARY_POINT_VALUE 4 +#define MAX_BINARY_POINT_VALUE 4//使用条件编译来检查是否已经定义了MAX_BINARY_POINT_VALUE宏。如果没有定义,则将其定义为4。 #endif #endif @@ -197,6 +215,11 @@ extern CHAR __init_array_end__; * 0xFFFF: max number of all software timers */ #ifndef OS_SWTMR_MAX_TIMERID +/*表示软件定时器ID的最大数量。 +默认值为((0xFFFF / KERNEL_SWTMR_LIMIT) * KERNEL_SWTMR_LIMIT), +其中KERNEL_SWTMR_LIMIT表示系统中每个任务可以创建的最大软件定时器数。 +这个宏定义的作用是将可用的ID数量限制在一个整数倍的软件定时器数范围内, +这样可以更好地利用ID资源。*/ #define OS_SWTMR_MAX_TIMERID ((0xFFFF / KERNEL_SWTMR_LIMIT) * KERNEL_SWTMR_LIMIT) #endif /** @@ -204,6 +227,11 @@ extern CHAR __init_array_end__; * Maximum size of a software timer queue. The default value of LOSCFG_BASE_CORE_SWTMR_LIMIT is 16. */ #ifndef OS_SWTMR_HANDLE_QUEUE_SIZE +/*示软件定时器队列的最大大小。 +默认值为KERNEL_SWTMR_LIMIT, +也就是系统中每个任务可以同时管理的软件定时器数。 +这个宏定义的作用是限制任务能够管理的软件定时器数量, +以避免资源浪费和性能问题。*/ #define OS_SWTMR_HANDLE_QUEUE_SIZE KERNEL_SWTMR_LIMIT #endif #endif @@ -214,6 +242,10 @@ extern CHAR __init_array_end__; * Starting address of the system memory */ #ifndef OS_SYS_MEM_ADDR +/*__heap_start是在链接脚本中定义的符号, +表示内存池的起始地址。 +因此,OS_SYS_MEM_ADDR的值就是内存池的起始地址的指针, +可以通过该宏来访问系统内存池。*/ #define OS_SYS_MEM_ADDR (&__heap_start) #endif @@ -223,9 +255,11 @@ extern CHAR __init_array_end__; * Starting address of dynload heap */ #if defined (LOSCFG_KERNEL_NX) && defined (LOSCFG_KERNEL_DYNLOAD) -#define LOS_DL_HEAP_SIZE (LOSCFG_KERNLE_DYN_HEAPSIZE * 0x100000) -#define LOS_DL_HEAP_BASE (SYS_MEM_END - LOS_DL_HEAP_SIZE) +//如果这两个宏都被定义了,那么将动态加载模块堆的大小定义为 +#define LOS_DL_HEAP_SIZE (LOSCFG_KERNLE_DYN_HEAPSIZE * 0x100000)//(LOSCFG_KERNLE_DYN_HEAPSIZE * 0x100000) +#define LOS_DL_HEAP_BASE (SYS_MEM_END - LOS_DL_HEAP_SIZE)//SYS_MEM_END - LOS_DL_HEAP_SIZE,其中SYS_MEM_END表示系统内存池的结束地址 #else +//如果没有定义LOSCFG_KERNEL_NX和LOSCFG_KERNEL_DYNLOAD宏,则将动态加载模块堆的大小和起始地址都定义为0。 #define LOS_DL_HEAP_SIZE 0 #define LOS_DL_HEAP_BASE 0 #endif @@ -236,7 +270,7 @@ extern CHAR __init_array_end__; */ #ifndef OS_SYS_MEM_SIZE #define OS_SYS_MEM_SIZE ((g_sys_mem_addr_end) - \ - ((LOS_DL_HEAP_SIZE + ((UINTPTR)&__heap_start) + (64 - 1)) & ~(64 - 1))) + ((LOS_DL_HEAP_SIZE + ((UINTPTR)&__heap_start) + (64 - 1)) & ~(64 - 1)))//定义内存池的大小 #endif /****************************** fw Interface configuration **************************/ @@ -245,11 +279,12 @@ extern CHAR __init_array_end__; * The core number is one in non-SMP architecture. */ #ifdef LOSCFG_KERNEL_SMP +//LOSCFG_KERNEL_CORE_NUM 将被设置为 LOSCFG_KERNEL_SMP_CORE_NUM 的值;否则,LOSCFG_KERNEL_CORE_NUM 将被设置为 1。 #define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM #else #define LOSCFG_KERNEL_CORE_NUM 1 #endif - +//LOSCFG_KERNEL_CPU_MASK 被定义为用于表示 CPU 核心掩码的表达式。它使用了位运算,通过将 1 左移 LOSCFG_KERNEL_CORE_NUM 位,然后减去 1,来生成一个包含 LOSCFG_KERNEL_CORE_NUM 个 1 的二进制数。这个数字通常用于设置 CPU 亲和性,以确定线程可以运行在哪些 CPU 核心上。 #define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1) /****************************** trace module configuration **************************/ @@ -259,6 +294,10 @@ extern CHAR __init_array_end__; */ #ifdef LOSCFG_KERNEL_TRACE #ifdef LOSCFG_RECORDER_MODE_OFFLINE +/*LOSCFG_KERNEL_TRACE 被定义的情况下,该代码块会被编译。 +如果同时定义了 LOSCFG_RECORDER_MODE_OFFLINE, +则 LOSTRACE_BUFFER_SIZE 会被设置为 LOSCFG_TRACE_BUFFER_SIZE 的值; +否则,LOSTRACE_BUFFER_SIZE 会被设置为 0。*/ #define LOS_TRACE_BUFFER_SIZE LOSCFG_TRACE_BUFFER_SIZE #else #define LOS_TRACE_BUFFER_SIZE 0 @@ -277,39 +316,44 @@ extern CHAR __init_array_end__; /** * Version number */ -#define _T(x) x -#define HW_LITEOS_SYSNAME "Huawei LiteOS" -#define HW_LITEOS_SEP " " -#define _V(v) _T(HW_LITEOS_SYSNAME)_T(HW_LITEOS_SEP)_T(v) +//这段代码是一组宏定义,用于定义操作系统的版本号和系统名称。 +#define _T(x) x//宏定义将传入的参数 x 原样返回,用于在宏定义中表示字符串。 +#define HW_LITEOS_SYSNAME "Huawei LiteOS"//宏定义为字符串 "Huawei LiteOS",表示操作系统的名称。 +#define HW_LITEOS_SEP " "//宏定义为字符串 " ",表示名称和版本号之间的分隔符。 +#define _V(v) _T(HW_LITEOS_SYSNAME)_T(HW_LITEOS_SEP)_T(v)//宏定义通过将操作系统名称和版本号连接起来,生成一个完整的版本字符串。 -#define HW_LITEOS_VERSION "V200R005C20B053" -#define HW_LITEOS_VER _V(HW_LITEOS_VERSION"-SMP") +#define HW_LITEOS_VERSION "V200R005C20B053"//宏定义为字符串 "V200R005C20B053",表示操作系统的具体版本号。 +#define HW_LITEOS_VER _V(HW_LITEOS_VERSION"-SMP")//宏定义使用了 _V 宏,将操作系统名称和版本号连接起来,形成类似 "Huawei LiteOS V200R005C20B053-SMP" 的完整版本号字符串。 /** * The Version number of Public */ -#define MAJ_V 5 -#define MIN_V 1 -#define REL_V 0 +#define MAJ_V 5//宏定义为整数 5,表示操作系统的主要版本号。 +#define MIN_V 1//宏定义为整数 1,表示操作系统的次要版本号。 +#define REL_V 0//宏定义为整数 0,表示操作系统的发布版本号。 /** * The release candidate version number */ -#define EXTRA_V 0 +//这些宏定义和函数声明用于管理操作系统的版本号,并提供了一种将版本号转换为字符串格式的机制。 +#define EXTRA_V 0//宏定义为整数 0,表示操作系统的额外版本号或候选版本号。 -#define VERSION_NUM(a, b, c) (((a) << 16) | ((b) << 8) | (c)) -#define HW_LITEOS_OPEN_VERSION_NUM VERSION_NUM(MAJ_V, MIN_V, REL_V) +#define VERSION_NUM(a, b, c) (((a) << 16) | ((b) << 8) | (c))//宏定义将主版本号 a、次版本号 b 和发布版本号 c 组合成一个无符号整数,通过位运算实现。 +#define HW_LITEOS_OPEN_VERSION_NUM VERSION_NUM(MAJ_V, MIN_V, REL_V)// 宏定义使用了 VERSION_NUM 宏,将主版本号、次版本号和发布版本号组成一个表示版本号的无符号整数。 -#define STRINGIFY_1(x) #x -#define STRINGIFY(x) STRINGIFY_1(x) +#define STRINGIFY_1(x) #x//宏定义将参数 x 转换为字符串。 +#define STRINGIFY(x) STRINGIFY_1(x)//宏定义调用 STRINGIFY_1 宏,将参数转换为字符串。 -#define HW_LITEOS_OPEN_VERSION_STRING STRINGIFY(MAJ_V) "." STRINGIFY(MIN_V) "." STRINGIFY(REL_V) +#define HW_LITEOS_OPEN_VERSION_STRING STRINGIFY(MAJ_V) "." STRINGIFY(MIN_V) "." STRINGIFY(REL_V)//宏定义使用了 STRINGIFY 宏,将主版本号、次版本号和发布版本号转换为形如 "5.1.0" 的字符串格式。 #if (EXTRA_V != 0) +/*不等于 0,则 HW_LITEOS_KERNEL_VERSION_STRING 宏定义为带有候选版本号的版本字符串; +否则,它被定义为不带候选版本号的版本字符串。*/ #define HW_LITEOS_KERNEL_VERSION_STRING HW_LITEOS_OPEN_VERSION_STRING "-rc" STRINGIFY(EXTRA_V) #else #define HW_LITEOS_KERNEL_VERSION_STRING HW_LITEOS_OPEN_VERSION_STRING #endif +//不等于 0,则 HW_LITEOS_KERNEL_VERSION_STRING 宏定义为带有候选版本号的版本字符串;否则,它被定义为不带候选版本号的版本字符串。 extern VOID OsStart(VOID); extern UINT32 OsMain(VOID); extern VOID *OsGetMainTask(VOID); diff --git a/src/kernel/include/los_cppsupport.h b/src/kernel/include/los_cppsupport.h index cdf3fd4..c02d5e4 100644 --- a/src/kernel/include/los_cppsupport.h +++ b/src/kernel/include/los_cppsupport.h @@ -47,6 +47,8 @@ extern "C" { * If LOS_CppSystemInit() is called in the first stage of scatter load, * this flag should be passed as the third parameter. */ +/*如果在散射加载的第一阶段调用 LOS_CppSystemInit(), +则此标志应作为第三个参数传递。*/ #define BEFORE_SCATTER 0 /** @@ -54,6 +56,8 @@ extern "C" { * If LOS_CppSystemInit() is called in the second stage of scatter load, * this flag should be passed as the third parameter. */ +/*如果在散射加载的第二阶段调用 LOS_CppSystemInit(), +则此标志应作为第三个参数传递。*/ #define AFTER_SCATTER 1 /** @@ -61,6 +65,8 @@ extern "C" { * If scatter load is disabled, this flag should be passed as the third * parameter when LOS_CppSystemInit() is called. */ +/*如果禁用了分散加载,则在调用 LOS_CppSystemInit() 时, +应将此标志作为第三个参数传递。*/ #define NO_SCATTER 2 /** @@ -87,6 +93,16 @@ extern "C" { * * @since Huawei LiteOS V100R001C00 */ +//初始化操作系统C++运行环境的函数 +/*具体来说,LOS_CppSystemInit函数的主要工作包括: +调用全局静态对象的构造函数:在C++中, +全局静态对象的构造函数需要在程序开始运行前被调用。 +LOS_CppSystemInit函数会遍历全局静态对象列表, +并依次调用它们的构造函数。 +执行其他C++运行时环境的初始化工作: +除了全局静态对象的构造函数之外, +还可能需要执行其他与C++运行时环境相关的初始化工作。 +例如,可以初始化C++异常处理机制、动态内存分配器等。*/ extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd, INT32 flag); #ifdef __cplusplus diff --git a/src/kernel/include/los_cpup.h b/src/kernel/include/los_cpup.h index 3591a26..690cea4 100644 --- a/src/kernel/include/los_cpup.h +++ b/src/kernel/include/los_cpup.h @@ -53,6 +53,9 @@ extern "C" { * * Solution: Decrease the maximum number of tasks. */ +/*在 CPU调度器模块中发生了内存不足的错误, +并且具体的错误码是由 LOS_ERRNO_OS_ERROR 宏根据模块ID(LOS_MOD_CPUP)和错误码(0x00)生成的。 +这个错误码可以被用于在程序中标识和处理这个特定的错误情况。*/ #define LOS_ERRNO_CPUP_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00) /** @@ -63,6 +66,9 @@ extern "C" { * * Solution: Check whether the pointer to the input parameter is usable. */ +/*在 CPU调度器模块中发生了空指针错误, +并且具体的错误码是由 LOS_ERRNO_OS_ERROR 宏根据模块ID(LOS_MOD_CPUP)和错误码(0x01)生成的。 +这个错误码可以被用于在程序中标识和处理这个特定的错误情况。*/ #define LOS_ERRNO_CPUP_TASK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x01) /** @@ -73,6 +79,9 @@ extern "C" { * * Solution: Check whether the CPU usage is initialized. */ +/*在 CPU调度器模块中发生了未初始化的错误, +具体的错误码是由 LOS_ERRNO_OS_ERROR 宏根据模块ID(LOS_MOD_CPUP)和错误码(0x02)生成的。 +这个错误码可以被用于在程序中标识和处理这个特定的错误情况。*/ #define LOS_ERRNO_CPUP_NO_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x02) /** @@ -83,6 +92,9 @@ extern "C" { * * Solution: Check whether the number of threads is applicable for the current operation. */ +/*在 CPU调度器模块中发生了无效的最大数量错误, +具体的错误码是由 LOS_ERRNO_OS_ERROR 宏根据模块ID(LOS_MOD_CPUP)和错误码(0x03)生成的。 +这个错误码可以被用于在程序中标识和处理这个特定的错误情况。*/ #define LOS_ERRNO_CPUP_MAXNUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x03) /** @@ -93,6 +105,9 @@ extern "C" { * * Solution: Check whether the target thread is created. */ +/*在 CPU调度器模块中发生了线程未创建的错误, +具体的错误码是由 LOS_ERRNO_OS_ERROR 宏根据模块ID(LOS_MOD_CPUP)和错误码(0x04)生成的。 +这个错误码可以被用于在程序中标识和处理这个特定的错误情况。*/ #define LOS_ERRNO_CPUP_THREAD_NO_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x04) /** @@ -103,12 +118,22 @@ extern "C" { * * Solution: Check whether the target task ID is applicable for the current operation. */ +/*在CPU调度器模块中发生了无效的任务ID错误, +具体的错误码是由 LOS_ERRNO_OS_ERROR 宏根据模块ID(LOS_MOD_CPUP)和错误码(0x05)生成的。 +这个错误码可以被用于在程序中标识和处理这个特定的错误情况。*/ #define LOS_ERRNO_CPUP_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x05) /** * @ingroup los_cpup * The structure of the CPU usage information of all tasks. */ +/*用于描述CPU调度器的信息。 +结构体包含两个成员变量: +usStatus:表示任务的状态,是一个 16 位的无符号整数。 +uwUsage:表示所有任务的 CPU 使用率,是一个 32 位的无符号整数,单位为 permillage,即千分之一。 +在操作系统中,CPU 调度器会负责管理系统中各个任务的执行。 +CPUP_INFO_S 结构体则提供了一种方式, +可以帮助了解任务状态和系统 CPU 使用情况的信息。*/ typedef struct tagCpupInfo { UINT16 usStatus; /**< The task status. */ UINT32 uwUsage; /**< CPU usage of all tasks. It is a permillage. And the value range is [0,1000]. */ @@ -118,9 +143,13 @@ typedef struct tagCpupInfo { * @ingroup los_cpup * The time period which the CPU usage collects in. */ +//用于表示 CPU 使用率的时间范围。 enum { + //表示显示最近 10 秒钟的 CPU 使用率,值为0。 CPUP_LAST_TEN_SECONDS = 0, /**< Display CPU usage in the last ten seconds, the value is 0. */ + //表示显示最近 1 秒钟的 CPU 使用率,值为1。 CPUP_LAST_ONE_SECONDS = 1, /**< Display CPU usage in the last one second, the value is 1. */ + //表示显示从系统启动到现在的 CPU 使用率,值为 0xffff。 CPUP_ALL_TIME = 0xffff /**< Display CPU usage from system startup to now, the value is 0xffff. */ }; @@ -149,6 +178,7 @@ enum { * @see LOS_HistoryTaskCpuUsage | LOS_AllCpuUsage * @since Huawei LiteOS V100R001C00 */ +//获取历史系统CPU使用率。参数 mode 是用来指定获取 CPU 使用率的时间范围或者其他相关设置。 extern UINT32 LOS_HistorySysCpuUsage(UINT32 mode); /** @@ -182,6 +212,9 @@ extern UINT32 LOS_HistorySysCpuUsage(UINT32 mode); * @see LOS_HistorySysCpuUsage * @since Huawei LiteOS V100R001C00 */ +/*用于获取历史任务的CPU使用率。 +其中 taskId 参数表示任务的ID或标识符, +mode 参数可能表示获取CPU使用率的模式或配置选项。*/ extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskId, UINT32 mode); /** @@ -224,6 +257,10 @@ extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskId, UINT32 mode); * * @since Huawei LiteOS V100R001C00 */ +/*用于获取系统中所有CPU的使用率信息。 +其中 maxNum 参数表示最大的CPU数量,cpupInfo 参数表示用于存储CPU使用率信息的结构体指针, +mode 参数可能表示获取CPU使用率的模式或配置选项, +flag 参数则可能表示其他的控制标志位。*/ extern UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT32 mode, UINT16 flag); /** @@ -244,6 +281,10 @@ extern UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT32 mode, * * @since Huawei LiteOS V100R001C00 */ +/*LOS_CpupReset 函数会遍历系统中所有任务和中断, +将它们的 CPU 使用率统计信息清零。 +这样,在下一次任务或中断执行时, +操作系统就会重新开始记录它们的 CPU 使用率。*/ extern VOID LOS_CpupReset(VOID); #ifdef __cplusplus diff --git a/src/kernel/include/los_err.h b/src/kernel/include/los_err.h index ff84c03..ef1f1dc 100644 --- a/src/kernel/include/los_err.h +++ b/src/kernel/include/los_err.h @@ -62,11 +62,12 @@ extern "C" { * * @since Huawei LiteOS V100R001C00 */ -typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName, - UINT32 lineNo, - UINT32 errorNo, - UINT32 paraLen, - VOID *para); +//LOS_ERRORHANDLE_FUNC 是一个函数指针类型,它指向一个函数,该函数具有以下特征: +typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName,//表示发生错误的文件名。 + UINT32 lineNo,//表示发生错误的行号。 + UINT32 errorNo,//表示错误代码或错误号。 + UINT32 paraLen,//表示附加参数的长度。 + VOID *para);//表示附加参数的指针。 /** * @ingroup los_err @@ -88,6 +89,15 @@ typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName, * * @since Huawei LiteOS V100R001C00 */ +/*函数的作用是处理错误。当程序运行过程中发生错误时, +可以调用这个函数来进行错误处理,包括记录错误信息、输出错误日志等操作。 +传入的参数可以用于定位和描述错误的具体信息, +从而更好地进行错误分析和排查。 +CHAR *fileName:表示发生错误的文件名。 +UINT32 lineNo:表示发生错误的行号。 +UINT32 errorNo:表示错误码或错误类型。 +UINT32 paraLen:表示传递的参数长度。 +VOID *para:表示传递的参数。*/ extern UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo, UINT32 paraLen, VOID *para); diff --git a/src/kernel/include/los_errno.h b/src/kernel/include/los_errno.h index 9d05458..106b7ef 100644 --- a/src/kernel/include/los_errno.h +++ b/src/kernel/include/los_errno.h @@ -46,31 +46,31 @@ extern "C" { * @ingroup los_errno * OS error code flag. It is a 24-bit unsigned integer. Its value is 0x000000U. */ -#define LOS_ERRNO_OS_ID (0x00U << 16) +#define LOS_ERRNO_OS_ID (0x00U << 16)//宏定义为 0x00U << 16,表示操作系统相关的错误码。 /** * @ingroup los_errno * Define the error level as informative. It is a 32-bit unsigned integer. Its value is 0x00000000U. */ -#define LOS_ERRTYPE_NORMAL (0x00U << 24) +#define LOS_ERRTYPE_NORMAL (0x00U << 24)//宏定义表示错误级别为 "informative"(信息级别),其值为 0x00U << 24。 /** * @ingroup los_errno * Define the error level as warning. It is a 32-bit unsigned integer. Its value is 0x01000000U. */ -#define LOS_ERRTYPE_WARN (0x01U << 24) +#define LOS_ERRTYPE_WARN (0x01U << 24)//宏定义表示错误级别为 "warning"(警告级别),其值为 0x01U << 24。 /** * @ingroup los_errno * Define the error level as critical. It is a 32-bit unsigned integer. Its value is 0x02000000U. */ -#define LOS_ERRTYPE_ERROR (0x02U << 24) +#define LOS_ERRTYPE_ERROR (0x02U << 24)//宏定义表示错误级别为 "critical"(严重级别),其值为 0x02U << 24。 /** * @ingroup los_errno * Define the error level as fatal. It is a 32-bit unsigned integer. Its value is 0x03000000U. */ -#define LOS_ERRTYPE_FATAL (0x03U << 24) +#define LOS_ERRTYPE_FATAL (0x03U << 24)//宏定义表示错误级别为 "fatal"(致命级别),其值为 0x03U << 24。 /** * @ingroup los_errno @@ -82,6 +82,14 @@ extern "C" { *
  • 0-7 bits indicate the error code number. It is specified by ERRNO.
  • * */ +/*用于生成操作系统致命错误码。 +LOS_ERRTYPE_FATAL 表示错误级别为 "fatal"(致命级别),其值为 0x03U << 24。 +LOS_ERRNO_OS_ID 表示操作系统相关的错误码,其值为 0x00U << 16。 +(UINT32)(MID) << 8 将参数 MID 左移 8 位,用于表示错误码的模块标识。 +(UINT32)(ERRNO) 表示具体的错误码。 +将上述宏和位运算组合起来,LOS_ERRNO_OS_FATAL 宏可以生成一个操作系统致命错误码, +其格式为:错误级别(LOS_ERRTYPE_FATAL)+ 错误码来源(LOS_ERRNO_OS_ID)+ 模块标识(MID)+ 具体错误码(ERRNO)。 +通过定义这样的宏,可以方便地生成不同类型的错误码,并根据错误码的不同属性进行分类和处理。*/ #define LOS_ERRNO_OS_FATAL(MID, ERRNO) \ (LOS_ERRTYPE_FATAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) @@ -95,6 +103,15 @@ extern "C" { *
  • 0-7 bits indicate the error code number. It is specified by ERRNO.
  • * */ +/*这段代码定义了一个宏 LOS_ERRNO_OS_ERROR,用于生成操作系统严重错误码。 +该宏使用了以下几个宏和位运算操作: +LOS_ERRTYPE_ERROR 表示错误级别为 "critical"(严重级别),其值为 0x02U << 24。 +LOS_ERRNO_OS_ID 表示操作系统相关的错误码,其值为 0x00U << 16。 +(UINT32)(MID) << 8 将参数 MID 左移 8 位,用于表示错误码的模块标识。 +(UINT32)(ERRNO) 表示具体的错误码。 +将上述宏和位运算组合起来,LOS_ERRNO_OS_ERROR 宏可以生成一个操作系统严重错误码, +其格式为:错误级别(LOS_ERRTYPE_ERROR)+ 错误码来源(LOS_ERRNO_OS_ID)+ 模块标识(MID)+ 具体错误码(ERRNO)。 +通过定义这样的宏,可以方便地生成不同类型的错误码,并根据错误码的不同属性进行分类和处理。*/ #define LOS_ERRNO_OS_ERROR(MID, ERRNO) \ (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) @@ -108,6 +125,15 @@ extern "C" { *
  • 0-7 bits indicate the error code number. It is specified by ERRNO.
  • * */ +/*这段代码定义了一个宏 LOS_ERRNO_OS_WARN,用于生成操作系统警告错误码。 +该宏使用了以下几个宏和位运算操作: +LOS_ERRTYPE_WARN 表示错误级别为 "warning"(警告级别),其值为 0x01U << 24。 +LOS_ERRNO_OS_ID 表示操作系统相关的错误码,其值为 0x00U << 16。 +(UINT32)(MID) << 8 将参数 MID 左移 8 位,用于表示错误码的模块标识。 +(UINT32)(ERRNO) 表示具体的错误码。 +将上述宏和位运算组合起来,LOS_ERRNO_OS_WARN 宏可以生成一个操作系统警告错误码, +其格式为:错误级别(LOS_ERRTYPE_WARN)+ 错误码来源(LOS_ERRNO_OS_ID)+ 模块标识(MID)+ 具体错误码(ERRNO)。 +通过定义这样的宏,可以方便地生成不同类型的错误码,并根据错误码的不同属性进行分类和处理。在发生警告级别的错误时,可以采取相应的处理措施以避免潜在问题的发生。*/ #define LOS_ERRNO_OS_WARN(MID, ERRNO) \ (LOS_ERRTYPE_WARN | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) @@ -121,13 +147,29 @@ extern "C" { *
  • 0-7 bits indicate the error code number. It is specified by ERRNO.
  • * */ +/*这段代码定义了一个宏 LOS_ERRNO_OS_NORMAL,用于生成操作系统普通错误码。 +该宏使用了以下几个宏和位运算操作: +LOS_ERRTYPE_NORMAL 表示错误级别为 "normal"(普通级别),其值为 0x00U << 24。 +LOS_ERRNO_OS_ID 表示操作系统相关的错误码,其值为 0x00U << 16。 +(UINT32)(MID) << 8 将参数 MID 左移 8 位,用于表示错误码的模块标识。 +(UINT32)(ERRNO) 表示具体的错误码。 +将上述宏和位运算组合起来,LOS_ERRNO_OS_NORMAL 宏可以生成一个操作系统普通错误码, +其格式为:错误级别(LOS_ERRTYPE_NORMAL)+ 错误码来源(LOS_ERRNO_OS_ID)+ 模块标识(MID)+ 具体错误码(ERRNO)。 +通过定义这样的宏,可以方便地生成不同类型的错误码,并根据错误码的不同属性进行分类和处理。在发生普通级别的错误时,可以根据需要进行相应的处理或记录。*/ #define LOS_ERRNO_OS_NORMAL(MID, ERRNO) \ (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) /** * @ingroup los_errno * Define the ID of each module in kernel. The ID is used in error code. + * 在内核中定义每个模块的 ID。该 ID 用于错误代码。 */ +/*这段代码定义了一个枚举类型 LOS_MODULE_ID,它包含了一系列的模块标识符及其对应的数值。 +每个模块都有一个唯一的标识符,用于在代码中进行识别和引用。这些标识符的值是以十六进制表示的,比如 LOS_MOD_SYS 的值是 0x0,LOS_MOD_MEM 的值是 0x1,以此类推。 +在这个枚举类型中,最后一个标识符 LOS_MOD_BUTT 是一个结束标志,表示枚举的结束。 +通过使用这个枚举类型,你可以方便地使用这些模块标识符来表示、操作和传递不同的模块。 +例如,你可以使用 LOS_MOD_SYS 来表示系统模块,在代码中进行相关的操作或者判断。 +总之,这个枚举类型提供了一种简单而有序的方式来管理和使用各个模块的标识符。*/ enum LOS_MOUDLE_ID { LOS_MOD_SYS = 0x0, /**< System ID. Its value is 0x0. */ LOS_MOD_MEM = 0x1, /**< Dynamic memory module ID. Its value is 0x1. */ diff --git a/src/kernel/include/los_event.h b/src/kernel/include/los_event.h index 7f1f653..47abca9 100644 --- a/src/kernel/include/los_event.h +++ b/src/kernel/include/los_event.h @@ -47,19 +47,19 @@ extern "C" { * @ingroup los_event * Event reading mode: The task waits for all its expected events to occur. */ -#define LOS_WAITMODE_AND 4U +#define LOS_WAITMODE_AND 4U//该模式表示任务等待所有期望的事件发生。也就是说,任务只有当所有的事件都发生时才会继续执行。 /** * @ingroup los_event * Event reading mode: The task waits for any of its expected events to occur. */ -#define LOS_WAITMODE_OR 2U +#define LOS_WAITMODE_OR 2U//该模式表示任务等待任何一个期望的事件发生。也就是说,任务只要有任何一个事件发生就会继续执行。 /** * @ingroup los_event * Event reading mode: The event flag is immediately cleared after the event is read. */ -#define LOS_WAITMODE_CLR 1U +#define LOS_WAITMODE_CLR 1U//该模式表示在事件被读取后立即清除事件标志。也就是说,一旦任务读取了事件,事件标志就会被清除。 /** * @ingroup los_event @@ -69,6 +69,14 @@ extern "C" { * Value: 0x02001c00. * * Solution: Set bits excluding bit 25 of the event mask to events. + * 这段代码定义了一个错误码 LOS_ERRNO_EVENT_SETBIT_INVALID, + 表示事件设置位无效。在这个宏定义中使用了 LOS_ERRNO_OS_ERROR 宏, + 该宏通常用于定义操作系统相关的错误码。 + 在这里,LOS_MOD_EVENT 表示错误码所属的模块是事件模块, + 0x00 是该错误码在事件模块内部的具体编号。 + 通过使用这样的宏定义,可以方便地在代码中引用和传播错误码, + 同时也有助于对错误进行分类和定位。当某个操作导致事件设置位无效时, + 可以返回这个错误码,从而让调用者知道发生了什么问题并进行相应的处理。 */ #define LOS_ERRNO_EVENT_SETBIT_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x00) @@ -81,6 +89,13 @@ extern "C" { * Solution: Increase the waiting time for event reading, or make another task write a * mask for the event. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_TIMEOUT,表示事件读取超时。同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏,表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x01。 + +当某个任务等待事件时,如果设定了超时时间, +并且在该时间内没有等到事件发生,那么就会返回这个错误码, +告知调用者事件读取超时。 +这个错误码的定义可以帮助开发人员更好地判断和处理超时情况, +从而提高系统的稳定性和可靠性。*/ #define LOS_ERRNO_EVENT_READ_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x01) /** @@ -92,6 +107,13 @@ extern "C" { * * Solution: Pass in a valid EVENTMASK value. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_EVENTMASK_INVALID,表示事件掩码无效。 +同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x02。 +事件掩码用于标识期望等待的事件,如果事件掩码无效, +则表示指定的事件掩码不符合规范或不可识别。当发生这种情况时, +可以返回这个错误码,告知调用者事件掩码无效。通过这个错误码的定义, +开发人员可以更好地检测和处理事件掩码相关的错误,从而提高系统的健壮性和可维护性。*/ #define LOS_ERRNO_EVENT_EVENTMASK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x02) /** @@ -102,6 +124,15 @@ extern "C" { * * Solution: Read the event in a task. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_IN_INTERRUPT,表示在中断中进行事件读取。 +同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x03。 +通常情况下,事件读取操作应该在任务上下文中进行,而不是在中断处理程序中执行。 +因为中断处理程序具有高优先级,可能会引起任务调度的竞争和冲突。 +当事件读取操作发生在中断上下文中时,就会返回这个错误码, +告知调用者在中断中进行了事件读取,这是不被支持的。 +通过这个错误码的定义,可以帮助开发人员及时发现并修复在中断上下文中执行事件读取的问题, +确保系统的正确运行和可靠性。*/ #define LOS_ERRNO_EVENT_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x03) /** @@ -115,6 +146,15 @@ extern "C" { * * Solution: Pass in a valid flag value. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_FLAGS_INVALID,表示事件标志无效。 +同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x04。 +事件标志用于标识特定的事件或状态,在进行事件操作时需要使用有效的事件标志。 +当事件标志无效时,可能是因为传递了错误的标志参数或者标志参数不符合预期。 +当发生这种情况时,可以返回这个错误码,告知调用者事件标志无效。 +通过这个错误码的定义,可以帮助开发人员更好地检测和处理事件标志相关的错误, +从而提高系统的稳定性和可维护性。开发人员可以根据错误码来定位并修复导致事件标志无效的问题, +确保事件操作的准确性和可靠性。*/ #define LOS_ERRNO_EVENT_FLAGS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x04) /** @@ -125,6 +165,15 @@ extern "C" { * * Solution: Unlock the task and read the event. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_IN_LOCK,表示在锁定状态下进行事件读取。 +同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x05。 +通常情况下,事件读取操作应该在非锁定状态下进行, +因为在锁定状态下进行事件读取可能导致资源竞争和死锁等问题。 +当发生在锁定状态下进行事件读取的情况时,可以返回这个错误码, +告知调用者事件读取发生在不合适的锁定状态下。 +通过这个错误码的定义,开发人员可以及时发现并修复在锁定状态下执行事件读取的问题, +确保系统的正确运行和可靠性。这有助于提高系统的并发性和避免潜在的问题。*/ #define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) /** @@ -135,6 +184,14 @@ extern "C" { * * Solution: Check whether the input parameter is null. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_PTR_NULL,表示传入的指针为空指针。 +同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x06。 +在进行事件操作时,通常需要传递一些参数,如事件掩码、事件标志、事件句柄等。 +如果传递的指针为空指针,可能会导致访问非法内存、程序崩溃等问题。当发生这种情况时, +可以返回这个错误码,告知调用者传入的指针为空指针。 +通过这个错误码的定义,开发人员可以及时发现并修复传入空指针的问题, +确保系统的正确运行和可靠性。这有助于提高系统的稳定性和可维护性。*/ #define LOS_ERRNO_EVENT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x06) /** @@ -147,6 +204,15 @@ extern "C" { * Solution: Read the event in a vailid task. * @deprecated This error code is obsolete since LiteOS 5.0.0. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK, +表示在系统任务中进行了事件读取操作。同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x07。 +一般来说,系统任务具有较高的特权级别,并且用于操作系统内部的关键任务, +而不是用于普通的应用程序任务。因此,在系统任务中进行事件读取可能会引起不可预期的行为, +破坏系统的稳定性和可靠性。当发生在系统任务中进行事件读取的情况时, +可以返回这个错误码,告知调用者不应该在系统任务中执行事件读取操作。 +通过这个错误码的定义,可以帮助开发人员避免在系统任务中执行事件读取操作, +从而确保系统的正常运行和安全性。这有助于提高系统的稳定性和可维护性。*/ #define LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x07) /** @@ -157,12 +223,29 @@ extern "C" { * * Solution: Check whether the event list is not empty. */ +/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY, +表示试图销毁不应该被销毁的事件。同样地,该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏, +表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x08。 +在事件处理过程中,有些事件可能不应该被销毁,因为它们可能仍在被其他任务或线程使用。 +如果试图销毁这些事件,可能会导致错误的行为,如资源泄漏、程序崩溃等问题。当发生这种情况时,可以返回这个错误码,告知调用者不应该销毁这些事件。 +通过这个错误码的定义,可以帮助开发人员避免销毁不应该被销毁的事件, +从而确保系统的正常运行和可靠性。这有助于提高系统的稳定性和可维护性。*/ #define LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x08) /** * @ingroup los_event * Event control structure */ +/*这段代码定义了一个名为 tagEvent 的结构体,其中包含两个成员变量: +uwEventID:表示事件掩码,在事件控制块中指示已经逻辑处理的事件。 +通常用于标识事件的类型或属性。 +stEventList:是一个链表节点,用于将事件控制块进行链接,以支持对事件的管理操作。 +此外,通过 typedef 关键字将 struct tagEvent 重新定义为 EVENT_CB_S 类型, +同时定义了指向 EVENT_CB_S 结构体的指针类型 PEVENT_CB_S。 +这种结构体的设计通常用于事件管理模块,用于存储和管理事件相关的信息, +包括事件的标识和事件控制块的链表关系。 +开发人员可以使用这样的结构体来实现事件的创建、删除、等待和触发等功能, +从而更好地管理系统中的异步事件,提高系统的并发处理能力。*/ typedef struct tagEvent { UINT32 uwEventID; /**< Event mask in the event control block, indicating the event that has been logically processed. */ @@ -187,6 +270,15 @@ typedef struct tagEvent { * @see LOS_EventClear * @since Huawei LiteOS V100R001C00 */ +/*UINT32 LOS_EventInit(PEVENT_CB_S eventCB) 是 LiteOS 操作系统中的一个函数, +用于初始化事件控制块。 +参数 eventCB 是指向事件控制块结构体 EVENT_CB_S 的指针, +该结构体用于存储和管理事件相关的信息。 +函数的返回值 UINT32 是一个无符号整数,表示函数执行的结果或错误码。 +通常,如果函数成功执行,则返回 LOS_OK 表示成功;如果发生错误,则返回对应的错误码。 +调用 LOS_EventInit 函数可以在使用事件之前对事件控制块进行初始化。 +通过此函数,可以确保事件控制块的初始状态正确, +并且可以安全地使用事件控制块进行事件的等待、触发和处理等操作。*/ extern UINT32 LOS_EventInit(PEVENT_CB_S eventCB); /** @@ -223,6 +315,25 @@ extern UINT32 LOS_EventInit(PEVENT_CB_S eventCB); * @see LOS_EventRead | LOS_EventWrite * @since Huawei LiteOS V100R001C00 */ +/*UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode) 是 LiteOS 操作系统中的一个函数,用于轮询事件。 + +参数说明: + +eventId 是一个指向无符号整数的指针,用于存储轮询到的事件ID。 +eventMask 是一个无符号整数,表示希望轮询的事件掩码。 +mode 是一个无符号整数,表示轮询模式,可以是以下几种值之一: +OS_EVENT_OR:轮询任意一个在事件掩码中设置的事件。 +OS_EVENT_AND:轮询所有在事件掩码中设置的事件。 +函数的返回值 UINT32 是一个无符号整数, +表示函数执行的结果或错误码。通常,如果函数成功执行,则返回 LOS_OK 表示成功; +如果发生错误,则返回对应的错误码。 +调用 LOS_EventPoll 函数可以轮询指定的事件,并根据指定的模式检查事件是否已经触发。 +如果有事件符合条件, +函数会将事件ID写入 eventId 指向的地址,并返回 LOS_OK;如果没有事件符合条件, +函数会根据轮询模式返回相应的错误码(如 LOS_ERRNO_EVENT_UNAVAILABLE)。 +此函数通常与其他事件管理函数配合使用,用于实现任务的等待和事件驱动的机制。 +通过轮询事件,任务可以根据不同的事件状态来决定后续的操作, +实现异步事件处理和任务调度的功能。*/ extern UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode); /** @@ -263,6 +374,24 @@ extern UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode); * @see LOS_EventPoll | LOS_EventWrite * @since Huawei LiteOS V100R001C00 */ +/*UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) +是 LiteOS 操作系统中的一个函数,用于读取事件。 +参数说明: +eventCB 是一个指向事件控制块结构体 EVENT_CB_S 的指针,表示要读取的事件控制块。 +eventMask 是一个无符号整数,表示希望读取的事件掩码。 +mode 是一个无符号整数,表示读取模式,可以是以下几种值之一: +OS_EVENT_OR:等待任意一个在事件掩码中设置的事件。 +OS_EVENT_AND:等待所有在事件掩码中设置的事件。 +timeout 是一个无符号整数,表示超时时间,单位为系统时钟节拍数。 +如果超过指定时间仍未满足读取条件,则函数返回超时错误码。 +函数的返回值 UINT32 是一个无符号整数,表示函数执行的结果或错误码。 +通常,如果函数成功执行,则返回 LOS_OK 表示成功;如果发生错误或超时,则返回对应的错误码。 +调用 LOS_EventRead 函数可以等待指定的事件触发,并根据指定的模式检查事件是否已经触发。 +如果有事件符合条件,函数会返回 LOS_OK;如果没有事件符合条件, +函数会根据读取模式等待事件的触发,直到满足条件或超时。在等待期间,任务可能会被挂起, +直到事件满足读取条件。 +此函数通常与其他事件管理函数配合使用,用于实现任务的等待和事件驱动的机制。通过读取事件, +任务可以根据不同的事件状态来决定后续的操作,实现异步事件处理和任务调度的功能。*/ extern UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout); /** @@ -311,6 +440,17 @@ extern UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events); * @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite * @since Huawei LiteOS V100R001C00 */ +/*UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) 是 LiteOS 操作系统中的一个函数,用于写入事件。 +参数说明: +eventCB 是一个指向事件控制块结构体 EVENT_CB_S 的指针,表示要写入事件的事件控制块。 +events 是一个无符号整数,表示要写入的事件掩码。 +函数的返回值 UINT32 是一个无符号整数,表示函数执行的结果或错误码。 +通常,如果函数成功执行,则返回 LOS_OK 表示成功;如果发生错误,则返回对应的错误码。 +调用 LOS_EventWrite 函数可以向指定的事件控制块写入事件。 +事件掩码表示一个或多个事件的状态,通过将相应的事件位设置为 1 来表示事件已经触发。 +当事件写入后,等待该事件的任务可能会被唤醒,根据事件的状态来决定后续的操作。 +此函数通常与其他事件管理函数配合使用,用于实现任务之间的同步与通信。 +通过写入事件,任务可以触发其他任务的执行,实现任务的协调与同步的功能。*/ extern UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events); /** @@ -333,6 +473,22 @@ extern UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events); * @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite * @since Huawei LiteOS V100R001C00 */ +/*UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) 是 LiteOS 操作系统中的一个函数,用于销毁事件控制块。 +参数说明: + +eventCB 是一个指向事件控制块结构体 EVENT_CB_S 的指针,表示要销毁的事件控制块。 +函数的返回值 UINT32 是一个无符号整数,表示函数执行的结果或错误码。 +通常,如果函数成功执行,则返回 LOS_OK 表示成功;如果发生错误,则返回对应的错误码。 + +调用 LOS_EventDestroy 函数可以销毁一个事件控制块,释放该事件控制块所占用的资源。 +一旦事件控制块被销毁,将不能再使用该事件控制块进行事件管理操作。 + +在实际应用中,当不再需要某个事件控制块时, +可以通过调用 LOS_EventDestroy 函数来释放相关资源,防止资源泄漏和系统资源浪费。 + +需要注意的是,在销毁事件控制块之前, +需要确保没有任务正在等待该事件或者使用该事件进行同步操作, +否则可能会导致系统行为异常。*/ extern UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB); #ifdef __cplusplus diff --git a/src/kernel/include/los_exc.h b/src/kernel/include/los_exc.h index 07c38e9..56ec150 100644 --- a/src/kernel/include/los_exc.h +++ b/src/kernel/include/los_exc.h @@ -61,6 +61,23 @@ extern "C" { * los_exc.h: the header file that contains the API declaration. * @since Huawei LiteOS V100R001C00 */ +/*LOS_Panic(const CHAR *fmt, ...) 是 LiteOS 操作系统中的一个函数,用于触发系统崩溃。 +参数说明: +fmt 是一个格式化字符串,表示崩溃信息的格式。 +... 是可变参数列表,根据格式化字符串 fmt 的要求,传入相应的参数。 +该函数没有返回值。 + +调用 LOS_Panic 函数会导致系统进入崩溃状态,即系统无法正常继续执行下去。 +通常情况下,该函数用于处理严重错误或不可恢复的异常情况, +以防止系统继续执行可能导致更严重问题的代码。 + +该函数允许通过格式化字符串传递一些额外的信息, +从而提供关于崩溃原因、位置或其他相关信息的描述。这 +些信息可能对于调试和排查问题非常有用。 + +需要注意的是,LOS_Panic 函数应该谨慎使用,仅在必要时使用。 +由于该函数触发系统崩溃,会导致系统停止运行并且无法继续恢复, +因此应该避免在正常的业务逻辑中调用该函数,以免造成不必要的系统中断。*/ VOID LOS_Panic(const CHAR *fmt, ...); /** @@ -79,8 +96,22 @@ VOID LOS_Panic(const CHAR *fmt, ...); * los_exc.h: the header file that contains the API declaration. * @since Huawei LiteOS V200R005C10 */ +/*VOID LOS_BackTrace(VOID) 是 LiteOS 操作系统中的函数,用于获取当前线程的函数调用栈信息。 +该函数没有参数,也没有返回值。 +调用 LOS_BackTrace 函数会获取当前线程的函数调用栈信息, +包括每个函数的调用地址以及相应的函数名。这些信息对于调试和排查问题非常有用, +可以帮助开发人员了解程序执行时的函数调用流程,定位问题所在。 + +通常情况下,LOS_BackTrace 函数用于调试目的,在程序出现异常或错误时, +可以通过打印函数调用栈信息来辅助分析问题原因。 +这对于定位崩溃、死锁或其他异常情况非常有帮助。 + +需要注意的是,LOS_BackTrace 函数的实现可能依赖于具体的硬件平台和编译器, +不同的平台和编译器可能会有不同的实现方式和限制。 +因此,在使用该函数时需要了解相关的平台和编译器特性,以确保获取到准确的函数调用栈信息。*/ extern VOID LOS_BackTrace(VOID); #define OsBackTrace LOS_BackTrace +//宏定义将 OsBackTrace 替换为 LOS_BackTrace,意味着在代码中使用 OsBackTrace 时,实际上是调用 LOS_BackTrace 函数。 /** * @ingroup los_exc @@ -99,9 +130,28 @@ extern VOID LOS_BackTrace(VOID); * los_exc.h: the header file that contains the API declaration. * @since Huawei LiteOS V100R001C00 */ +/*VOID LOS_TaskBackTrace(UINT32 taskID) 是 LiteOS 操作系统中的函数,用于获取指定任务的函数调用栈信息。 +参数说明: +taskID 是一个无符号整数,表示要获取函数调用栈信息的目标任务的任务ID。 +该函数没有返回值。 + +调用 LOS_TaskBackTrace 函数可以获取指定任务的函数调用栈信息, +包括每个函数的调用地址以及相应的函数名。这些信息对于调试和排查问题非常有用, +可以帮助开发人员了解指定任务执行时的函数调用流程,定位问题所在。 + +通常情况下,LOS_TaskBackTrace 函数用于调试目的,在特定任务出现异常或错误时, +可以通过打印该任务的函数调用栈信息来辅助分析问题原因。 +这对于定位崩溃、死锁或其他异常情况非常有帮助。 + +需要注意的是,LOS_TaskBackTrace 函数的实现可能依赖于具体的硬件平台和编译器, +不同的平台和编译器可能会有不同的实现方式和限制。 +因此,在使用该函数时需要了解相关的平台和编译器特性,以确保获取到准确的函数调用栈信息。 + +另外,需要确保指定的任务ID是有效的、存在的任务ID, +否则可能导致获取不到正确的函数调用栈信息。*/ extern VOID LOS_TaskBackTrace(UINT32 taskID); #define OsTaskBackTrace LOS_TaskBackTrace - +//宏定义将 OsTaskBackTrace 替换为 LOS_TaskBackTrace,意味着在代码中使用 OsTaskBackTrace 时,实际上是调用 LOS_TaskBackTrace 函数。 #ifdef LOSCFG_SHELL_EXCINFO_DUMP /** * @ingroup los_exc @@ -122,7 +172,14 @@ extern VOID LOS_TaskBackTrace(UINT32 taskID); * * @since Huawei LiteOS V200R005C10 */ +/*这是一个函数指针类型的定义。它定义了一个名为 LogReadWriteFunc 的函数指针类型, +该函数指针指向一个返回类型为 VOID 的函数, +函数参数为 UINTPTR startAddr、UINT32 space、UINT32 rwFlag 和 CHAR *buf。 +这种定义方式可以用来声明符合特定函数签名的函数指针类型,以便在代码中使用。*/ typedef VOID (*LogReadWriteFunc)(UINTPTR startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf); +/*这是一个宏定义,将 log_read_write_fn 替换为 LogReadWriteFunc。 +注释中指出这是一个旧的API,并建议避免使用它。通过这个宏定义, +可以将 log_read_write_fn 在整个代码中替换为 LogReadWriteFunc,以达到简化和统一的目的。*/ #define log_read_write_fn LogReadWriteFunc /* old API since V200R002C00, please avoid use of it */ /** @@ -146,6 +203,22 @@ typedef VOID (*LogReadWriteFunc)(UINTPTR startAddr, UINT32 space, UINT32 rwFlag, * * @since Huawei LiteOS V200R002C00 */ +/*函数 LOS_ExcInfoRegHook 是在 LiteOS 操作系统中的一个函数。它的作用是设置异常信息寄存器的回调钩子函数。 + +该函数有四个参数: + +startAddr:异常信息寄存器的起始地址。 +space:异常信息寄存器的大小(以字节为单位)。 +buf:用于存储异常信息寄存器内容的缓冲区。 +hook:回调钩子函数,类型为 LogReadWriteFunc,即函数指针类型。 +具体来说,当发生异常时,LiteOS 将会调用 LOS_ExcInfoRegHook 函数, +并将异常信息寄存器的起始地址、大小和缓冲区作为参数传递给它。 +然后,在 LOS_ExcInfoRegHook 函数内部, +可以通过回调钩子函数 hook 来处理异常信息寄存器的内容。 + +这个功能可以用于自定义异常处理和异常信息记录。通过设置回调钩子函数, +可以在异常发生时获取并处理异常信息寄存器的内容, +以便进行进一步的分析或记录。*/ VOID LOS_ExcInfoRegHook(UINTPTR startAddr, UINT32 space, CHAR *buf, LogReadWriteFunc hook); #endif diff --git a/src/kernel/include/los_hw.h b/src/kernel/include/los_hw.h index db1cf00..2105a21 100644 --- a/src/kernel/include/los_hw.h +++ b/src/kernel/include/los_hw.h @@ -59,9 +59,10 @@ extern "C" { * los_hw.h: the header file that contains the API declaration. * @since Huawei LiteOS V200R003C00 */ +/*这段代码定义了一个静态内联函数 LOS_CpuInfo,该函数返回一个指向常量字符的指针。*/ STATIC INLINE const CHAR *LOS_CpuInfo(VOID) { - return ArchCpuInfo(); + return ArchCpuInfo();//函数会根据当前的硬件平台调用对应的底层函数,以获取关于CPU的信息,例如型号、频率、核心数等等。这个函数的实现通常是与硬件平台紧密相关的,并且可能需要一些底层的寄存器读取或其他特定平台相关的操作。 } #ifdef __cplusplus diff --git a/src/kernel/include/los_hwi.h b/src/kernel/include/los_hwi.h index 95233f2..4603103 100644 --- a/src/kernel/include/los_hwi.h +++ b/src/kernel/include/los_hwi.h @@ -48,12 +48,16 @@ extern "C" { * @ingroup los_hwi * Count of interrupts. */ +/*这行代码声明了一个名为g_intCount的数组,但它的定义并不在当前的源文件中。 +关键字"extern"告诉编译器该数组是在其他地方定义的,这通常意味着它在其他源文件或库中。 +在链接阶段,编译器会去找到实际的g_intCount的定义,然后将其与当前的代码进行链接。*/ extern size_t g_intCount[]; /** * An interrupt is active. */ -extern size_t IntActive(VOID); + +extern size_t IntActive(VOID);//IntActive(VOID)函数是用于获取当前活动的中断数量的函数。该函数没有参数,返回类型为无符号整数类型(size_t)。 /** * @ingroup los_hwi @@ -61,6 +65,16 @@ extern size_t IntActive(VOID); * * @see OS_INT_INACTIVE */ + + /*在LiteOS操作系统中,#define OS_INT_ACTIVE IntActive() 是一个预处理指令,用来定义一个宏。它将OS_INT_ACTIVE 定义为调用 IntActive() 函数的结果。 + + 宏定义是一种在代码中使用的文本替换机制。在这种情况下, + 当代码中出现 OS_INT_ACTIVE 时,预处理器会将其替换为 IntActive() 函数的调用,从 + 而实际上就是将函数调用作为一个宏使用。 + + 这种宏定义的目的可能是为了简化代码书写或提高代码的可读性。 + 通过定义宏,可以通过简单的名称(OS_INT_ACTIVE)来表示复杂的函数调用(IntActive()), + 从而使代码更加简洁和易于理解。*/ #define OS_INT_ACTIVE IntActive() /** @@ -71,6 +85,21 @@ extern size_t IntActive(VOID); * * @see OS_INT_ACTIVE */ +/*在LiteOS操作系统中,#define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) 是一个预处理指令, +用来定义一个宏。它将OS_INT_INACTIVE 定义为对 OS_INT_ACTIVE 取反的结果。 + +具体来说,OS_INT_ACTIVE 是一个宏,表示调用 IntActive() 函数的结果。 +而 OS_INT_INACTIVE 是另一个宏,表示对 OS_INT_ACTIVE 取反的结果。 +在这种情况下,使用逻辑非运算符 ! 将 OS_INT_ACTIVE 的结果取反。 + +这个宏定义的目的可能是用于表示当前中断是否处于非活动状态。 +如果 OS_INT_ACTIVE 为真(非零),则表示中断处于活动状态; +而 OS_INT_INACTIVE 则为假(零),表示中断处于非活动状态。 + +通过这种方式定义宏,可以方便地在代码中判断中断状态并进行相应的处理。 +代码中使用 OS_INT_INACTIVE 可以更加直观地表示中断是否处于非活动状态, +提高代码的可读性和可维护性。 +*/ #define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) /** @@ -78,6 +107,18 @@ extern size_t IntActive(VOID); * Highest priority of a hardware interrupt.This is an external parameter. * The priority range is [OS_HWI_PRIO_HIGHEST, OS_HWI_PRIO_HIGHEST + LOSCFG_HWI_PRIO_LIMIT - 1]. */ +/*在LiteOS操作系统中,#define OS_HWI_PRIO_HIGHEST 0 是一个预处理指令, +用来定义一个宏。它将 OS_HWI_PRIO_HIGHEST 定义为数字 0。 + +在LiteOS操作系统中,中断(Interrupt)也被称为硬件中断(Hardware Interrupt), +简称为 HWI。HWI具有不同的优先级(Priority),优先级越高,中断响应的时间越短。 +OS_HWI_PRIO_HIGHEST 是一个表示最高中断优先级的宏,其值为 0。 + +在LiteOS操作系统中,中断的优先级是用数字表示的,数字越小表示优先级越高。 +因此,OS_HWI_PRIO_HIGHEST 表示的是最高中断优先级,也就是数字最小的中断优先级。 +在一些特定场景下,需要使用最高中断优先级, +这时候可以使用 OS_HWI_PRIO_HIGHEST 宏来表示最高中断优先级的数字值 0, +从而方便地进行代码编写。*/ #define OS_HWI_PRIO_HIGHEST 0 /** @@ -85,12 +126,36 @@ extern size_t IntActive(VOID); * This represents the interrupt priority range, the larger number, the lower priority, the interrupt processor is * modified uniformly. */ +/*在LiteOS操作系统中, +#define OS_HWI_PRIO_LOWEST (LOSCFG_HWI_PRIO_LIMIT - 1) 是一个预处理指令, +用来定义一个宏。它将 OS_HWI_PRIO_LOWEST 定义为 LOSCFG_HWI_PRIO_LIMIT 减去 1 的结果。 + +在LiteOS操作系统中,中断(Interrupt)也被称为硬件中断(Hardware Interrupt), +简称为 HWI。HWI具有不同的优先级(Priority),优先级越高,中断响应的时间越短。OS_HWI_PRIO_LOWEST 是一个表示最低中断优先级的宏,其值为 LOSCFG_HWI_PRIO_LIMIT - 1。 + +LOSCFG_HWI_PRIO_LIMIT 是一个配置参数,用于表示系统支持的最大中断优先级数。 +因此,OS_HWI_PRIO_LOWEST 表示的是最低中断优先级,也就是数字最大的中断优先级, +其值等于最大中断优先级数减去 1。 +在一些特定场景下,需要使用最低中断优先级, +这时候可以使用 OS_HWI_PRIO_LOWEST 宏来表示最低中断优先级的数字值,从而方便地进行代码编写。*/ #define OS_HWI_PRIO_LOWEST (LOSCFG_HWI_PRIO_LIMIT - 1) /** * @ingroup los_hwi * The lower priority number, the higher priority, so OS_HWI_PRIO_LOWEST big than OS_HWI_PRIO_HIGHEST. */ +/*该宏接受一个参数 pri,表示要判断的中断优先级值。 +宏的定义使用了逻辑与运算符 && 和比较运算符 >=、<=。 +具体解释如下: + +((pri) >= OS_HWI_PRIO_HIGHEST) 表示判断 pri 是否大于等于最高中断优先级(OS_HWI_PRIO_HIGHEST)。如果 pri 大于等于最高中断优先级,则该条件结果为真(非零);否则为假(零)。 +((pri) <= OS_HWI_PRIO_LOWEST) 表示判断 pri 是否小于等于最低中断优先级(OS_HWI_PRIO_LOWEST)。如果 pri 小于等于最低中断优先级,则该条件结果为真(非零);否则为假(零)。 +整个宏定义将以上两个条件使用逻辑与运算符 && 连接起来, +即 (((pri) >= OS_HWI_PRIO_HIGHEST) && ((pri) <= OS_HWI_PRIO_LOWEST))。 +只有当 pri 同时满足大于等于最高中断优先级和小于等于最低中断优先级时, +该条件结果为真(非零),表示中断优先级有效;否则为假(零),表示中断优先级无效。 +这个宏的作用是在进行中断优先级的判断和设置时, +确保所使用的中断优先级值在有效范围内,避免出现错误的中断优先级设置。*/ #define HWI_PRI_VALID(pri) (((pri) >= OS_HWI_PRIO_HIGHEST) && ((pri) <= OS_HWI_PRIO_LOWEST)) /** @@ -105,6 +170,23 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用来定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_NUM_INVALID 是一个表示无效中断号的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成, +它接受两个参数:模块号和错误码值。 +其中,LOS_MOD_HWI 表示HWI模块的模块号,0x00 表示错误码值。 +因此,LOS_ERRNO_HWI_NUM_INVALID 的值就是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_NUM_INVALID 是 LOS_ERRNO_HWI_NUM_INVALID 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示无效中断号的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在配置和使用中断时,如果遇到了无效的中断号, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_NUM_INVALID 或 OS_ERRNO_HWI_NUM_INVALID, +来判断中断号是否有效,进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) #define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_HWI_NUM_INVALID @@ -120,6 +202,22 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用来定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_PROC_FUNC_NULL 是一个表示中断处理函数为空的错误码。该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成, +它接受两个参数:模块号和错误码值。 +其中,LOS_MOD_HWI 表示HWI模块的模块号,0x01 表示错误码值。 +因此,LOS_ERRNO_HWI_PROC_FUNC_NULL 的值就是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_PROC_FUNC_NULL 是 LOS_ERRNO_HWI_PROC_FUNC_NULL 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示中断处理函数为空的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在配置和使用中断时,如果中断处理函数为空, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_PROC_FUNC_NULL 或 OS_ERRNO_HWI_PROC_FUNC_NULL,来判断中断处理函数是否正确设置, +进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) #define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_HWI_PROC_FUNC_NULL @@ -132,6 +230,18 @@ extern size_t IntActive(VOID); * Solution: This error code is not in use temporarily. * @deprecated This error code is obsolete since LiteOS 5.0.0. */ +/**/ +/*定义了一个错误码,表示硬件中断(HWI)回调函数不可用的情况。 +具体解释如下: + +OS_ERRNO_HWI_CB_UNAVAILABLE 是用来表示硬件中断(HWI)回调函数不可用的错误码。 +它由 LOS_ERRNO_OS_ERROR 宏生成,该宏接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x02 表示错误码值。 +因此,OS_ERRNO_HWI_CB_UNAVAILABLE 的值是根据模块号和错误码值计算得出的。 +这个错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在设置和注册中断回调函数时,如果回调函数不可用, +可以通过检查返回的错误码是否等于 OS_ERRNO_HWI_CB_UNAVAILABLE,来判断回调函数的可用性, +从而进行相应的错误处理。*/ #define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) /** @@ -146,6 +256,21 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用来定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误。它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_NO_MEMORY 是一个表示无法分配内存的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成,它接受两个参数:模块号和错误码值。 +其中,LOS_MOD_HWI 表示HWI模块的模块号,0x03 表示错误码值。 +因此,LOS_ERRNO_HWI_NO_MEMORY 的值就是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_NO_MEMORY 是 LOS_ERRNO_HWI_NO_MEMORY 的别名。通过将其定义为相同的值, +可以在代码中使用更简洁的名称来表示无法分配内存的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在设置和注册中断处理函数时,如果出现无法分配内存的情况, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_NO_MEMORY 或 OS_ERRNO_HWI_NO_MEMORY, +来判断内存是否分配成功,进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) #define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_HWI_NO_MEMORY @@ -162,6 +287,22 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用于定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_ALREADY_CREATED 是一个表示中断已经被创建的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成,它接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x04 表示错误码值。 +因此,LOS_ERRNO_HWI_ALREADY_CREATED 的值是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_ALREADY_CREATED 是 LOS_ERRNO_HWI_ALREADY_CREATED 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示中断已经被创建的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在创建中断时,如果中断已经被创建, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_ALREADY_CREATED 或 OS_ERRNO_HWI_ALREADY_CREATED, +来判断中断是否已经存在,从而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) #define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_HWI_ALREADY_CREATED @@ -177,6 +318,22 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用于定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_PRIO_INVALID 是一个表示中断优先级无效的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成,它接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x05 表示错误码值。 +因此,LOS_ERRNO_HWI_PRIO_INVALID 的值是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_PRIO_INVALID 是 LOS_ERRNO_HWI_PRIO_INVALID 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示中断优先级无效的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在设置中断优先级时,如果提供了无效的优先级值, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_PRIO_INVALID 或 OS_ERRNO_HWI_PRIO_INVALID,来判断优先级是否有效, +进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) #define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_HWI_PRIO_INVALID @@ -189,6 +346,18 @@ extern size_t IntActive(VOID); * Solution: This error code is not in use temporarily. * @deprecated This error code is obsolete since LiteOS 5.0.0. */ +/*是一个预处理指令,用于定义错误码。 + +该错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误, +具体来说是中断模式无效的错误。 +它是通过使用LiteOS提供的错误码宏 LOS_ERRNO_OS_ERROR 来定义的。 +该宏接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x06 表示错误码值。 +因此,OS_ERRNO_HWI_MODE_INVALID 的值是根据模块号和错误码值计算得出的。 +这个错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在设置中断模式时,如果提供了无效的模式值, +可以通过检查返回的错误码是否等于 OS_ERRNO_HWI_MODE_INVALID , +来判断模式是否有效,进而进行相应的错误处理。*/ #define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) /** @@ -200,6 +369,19 @@ extern size_t IntActive(VOID); * Solution: This error code is not in use temporarily. * @deprecated This error code is obsolete since LiteOS 5.0.0. */ +/*是一个预处理指令,用于定义错误码。 + +该错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误, +具体来说是快速中断模式已经被创建的错误。 +它是通过使用LiteOS提供的错误码宏 LOS_ERRNO_OS_ERROR 来定义的。 +该宏接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x07 表示错误码值。 +因此,OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED 的值是根据模块号和错误码值计算得出的。 + +这个错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在创建快速中断模式时,如果该模式已经被创建, +可以通过检查返回的错误码是否等于 OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED , +来判断快速中断模式是否已经存在,从而进行相应的错误处理。*/ #define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) /** @@ -214,6 +396,23 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用于定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误,具体来说是硬件中断发生错误的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_INTERR 是一个表示硬件中断发生错误的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成, +它接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x08 表示错误码值。 +因此,LOS_ERRNO_HWI_INTERR 的值是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_INTERR 是 LOS_ERRNO_HWI_INTERR 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示硬件中断发生错误的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在中断处理函数中,如果硬件中断发生错误, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_INTERR 或 OS_ERRNO_HWI_INTERR, +来判断中断是否发生了错误,进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08) #define OS_ERRNO_HWI_INTERR LOS_ERRNO_HWI_INTERR @@ -230,6 +429,22 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用于定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误,具体来说是共享中断错误的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_SHARED_ERROR 是一个表示共享中断错误的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成,它接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x09 表示错误码值。 +因此,LOS_ERRNO_HWI_SHARED_ERROR 的值是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_SHARED_ERROR 是 LOS_ERRNO_HWI_SHARED_ERROR 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示共享中断错误的错误码。 +这些错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在设置共享中断时,如果发生了错误, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_SHARED_ERROR 或 OS_ERRNO_HWI_SHARED_ERROR, +来判断共享中断是否设置成功,进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09) #define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_HWI_SHARED_ERROR @@ -242,6 +457,20 @@ extern size_t IntActive(VOID); * Solution: This error code is not in use temporarily. * @deprecated This error code is obsolete since LiteOS 5.0.0. */ +/*是一个预处理指令,用于定义错误码。 + +这个错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误,具体来说是硬件中断参数无效的错误。 +它是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +OS_ERRNO_HWI_ARG_INVALID 是一个表示硬件中断参数无效的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成,它接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x0a 表示错误码值。 +因此,OS_ERRNO_HWI_ARG_INVALID 的值是根据模块号和错误码值计算得出的。 +这个错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在注册硬件中断处理函数时,如果传递给函数的参数无效, +可以通过检查返回的错误码是否等于 OS_ERRNO_HWI_ARG_INVALID,来判断参数是否有效, +进而进行相应的错误处理。*/ #define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a) /** @@ -257,6 +486,22 @@ extern size_t IntActive(VOID); *
  • Please use macros starting with LOS, and macros starting with OS will not be supported.
  • * */ +/*是两个预处理指令,用于定义错误码。 + +这些错误码用于表示在操作系统的硬件中断(HWI)模块中发生的错误,具体来说是硬件中断号未创建的错误。 +它们是通过使用LiteOS提供的错误码宏来定义的。 +具体解释如下: + +LOS_ERRNO_HWI_HWINUM_UNCREATE 是一个表示硬件中断号未创建的错误码。 +该错误码的值由 LOS_ERRNO_OS_ERROR 宏生成,它接受两个参数:模块号和错误码值。 +在这里,LOS_MOD_HWI 表示HWI模块的模块号,0x0b 表示错误码值。 +因此,LOS_ERRNO_HWI_HWINUM_UNCREATE 的值是根据模块号和错误码值计算得出的。 +OS_ERRNO_HWI_HWINUM_UNCREATE 是 LOS_ERRNO_HWI_HWINUM_UNCREATE 的别名。 +通过将其定义为相同的值,可以在代码中使用更简洁的名称来表示硬件中断号未创建的错误码。 +这个错误码可以在编程过程中用于判断和处理HWI模块相关的错误情况。 +例如,在请求处理某个硬件中断时,如果指定的中断号未创建, +可以通过检查返回的错误码是否等于 LOS_ERRNO_HWI_HWINUM_UNCREATE 或 OS_ERRNO_HWI_HWINUM_UNCREATE, +来判断中断号是否有效,进而进行相应的错误处理。*/ #define LOS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b) #define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_HWI_HWINUM_UNCREATE @@ -264,18 +509,21 @@ extern size_t IntActive(VOID); * @ingroup los_hwi * Define the type HWI_HANDLE_T for a hardware interrupt number, the type is an unsigned int. */ +//这行代码定义了一个新的类型 HWI_HANDLE_T,它被定义为 UINT32,即无符号32位整数。在这里,HWI_HANDLE_T 被用来表示硬件中断的句柄或标识符。 typedef UINT32 HWI_HANDLE_T; /** * @ingroup los_hwi * Define the type HWI_PRIOR_T for a hardware interrupt priority, the type is an unsigned short. */ +//这行代码定义了一个新的类型 HWI_PRIOR_T,它被定义为 UINT16,即无符号16位整数。在这里,HWI_PRIOR_T 被用来表示硬件中断的优先级。 typedef UINT16 HWI_PRIOR_T; /** * @ingroup los_hwi * Define the type HWI_MODE_T for hardware interrupt mode configurations, the type is an unsigned short. */ +//这行代码定义了一个新的类型 HWI_MODE_T,它被定义为 UINT16,即无符号16位整数。在这里,HWI_MODE_T 被用来表示硬件中断的模式配置。 typedef UINT16 HWI_MODE_T; /** @@ -283,6 +531,9 @@ typedef UINT16 HWI_MODE_T; * Define the type HWI_ARG_T for the parameter used for the hardware interrupt creation function. * The function of this parameter varies among platforms. */ +/*这行代码定义了一个新的类型 HWI_ARG_T,它被定义为 UINTPTR, +即一个无符号整数,其大小与指针大小相同。 +在这里,HWI_ARG_T 被用来表示硬件中断创建函数的参数,其具体含义会因平台而异。*/ typedef UINTPTR HWI_ARG_T; /** @@ -303,6 +554,8 @@ typedef UINTPTR HWI_ARG_T; * @see LOS_HwiCreate * @since Huawei LiteOS V100R001C00 */ +/*这行代码定义了一个函数指针类型 HWI_PROC_FUNC,它指向一个没有参数和返回值的函数。 +在这里,HWI_PROC_FUNC 被用来表示硬件中断处理函数的类型。*/ typedef VOID (*HWI_PROC_FUNC)(VOID); /** @@ -311,12 +564,22 @@ typedef VOID (*HWI_PROC_FUNC)(VOID); * * The flag only used by the kernel as part of the IRQ handling routines. */ +/*这个宏定义了一个常量 IRQF_SHARED,其值为 0x8000U。 +在这里,IRQF_SHARED 用于表示一个共享的硬件中断。*/ #define IRQF_SHARED 0x8000U /** * @ingroup los_hwi * The hardware interrupt parameter for #LOS_HwiDelete and interrupt handler in #LOS_HwiCreate. */ +/*这个代码定义了一个名为 HWI_IRQ_PARAM_S 的结构体类型,结构体内包含了以下成员: +int swIrq: 表示中断号的整数变量。 +VOID *pDevId: 表示触发中断的设备ID的指针变量。 +const CHAR *pName: 表示中断名称的指针变量。 + +这个结构体类型 HWI_IRQ_PARAM_S 用作 LOS_HwiDelete 函数和 LOS_HwiCreate 函数中的硬件中断参数。 +通过使用这个结构体, +可以传递中断号、设备ID和中断名称等信息给函数,以进行相应的操作或处理。*/ typedef struct tagIrqParam { int swIrq; /**< The interrupt number */ VOID *pDevId; /**< The pointer to the device ID that launches the interrupt */ @@ -340,6 +603,27 @@ typedef struct tagIrqParam { * @see LOS_IntRestore * @since Huawei LiteOS V100R001C00 */ +/*这段代码定义了一个静态内联函数 LOS_IntLock(),具体解释如下: + +STATIC INLINE: + +STATIC 关键字指示该函数的作用域为当前文件,在其他文件中不可见。 +INLINE 关键字告诉编译器将该函数的代码插入到调用处,而不是生成函数调用。 +UINT32: + +UINT32 表示返回值类型为无符号32位整数。 +LOS_IntLock(VOID): + +LOS_IntLock 是函数的名称,它接受一个 VOID 参数,表示没有输入参数。 +return ArchIntLock();: + +这行代码调用了 ArchIntLock() 函数,并将其返回值作为 LOS_IntLock() 函数的返回值。 +ArchIntLock() 是一个硬件相关的函数,用于禁用中断,并返回之前的中断状态。 +因为函数声明为内联函数且函数体非常简单, +所以编译器会在调用处直接插入 ArchIntLock() 的代码,提高执行效率。 +总结:LOS_IntLock() 函数是一个内联函数, +它调用底层的 ArchIntLock() 函数来禁用中断,并返回之前的中断状态。 +这个函数的目的是为了保护关键代码区域,防止被中断打断,以确保数据的一致性和可靠性。*/ STATIC INLINE UINT32 LOS_IntLock(VOID) { return ArchIntLock(); @@ -361,6 +645,13 @@ STATIC INLINE UINT32 LOS_IntLock(VOID) * * @see LOS_IntLock */ +/*return ArchIntUnlock();: + +这行代码调用了 ArchIntUnlock() 函数,并将其返回值作为 LOS_IntUnLock() 函数的返回值。 +ArchIntUnlock() 是一个硬件相关的函数,用于恢复之前被禁用的中断状态。 +总结:LOS_IntUnLock() 函数是一个内联函数, +它调用底层的 ArchIntUnlock() 函数来恢复之前被禁用的中断状态。 +这个函数的目的是为了在临界区执行完毕后,恢复中断,允许其他中断事件发生。*/ STATIC INLINE UINT32 LOS_IntUnLock(VOID) { return ArchIntUnlock(); @@ -384,6 +675,14 @@ STATIC INLINE UINT32 LOS_IntUnLock(VOID) * @see LOS_IntLock * @since Huawei LiteOS V100R001C00 */ +/*ArchIntRestore(intSave);: + +这行代码调用了 ArchIntRestore() 函数,将之前保存的中断状态作为参数传递给它。 +ArchIntRestore() 是一个硬件相关的函数,用于根据传入的中断状态值恢复中断。 +总结:LOS_IntRestore() 函数是一个内联函数, +它调用底层的 ArchIntRestore() 函数来根据之前保存的中断状态恢复中断。 +这个函数的目的是在一段被禁用中断的代码执行完毕后,恢复中断状态,允许其他中断事件发生。 +由于函数没有返回值,所以不会返回任何结果。*/ STATIC INLINE VOID LOS_IntRestore(UINT32 intSave) { ArchIntRestore(intSave); @@ -430,11 +729,11 @@ STATIC INLINE VOID LOS_IntRestore(UINT32 intSave) * @see LOS_HwiDelete * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, - HWI_PRIOR_T hwiPrio, - HWI_MODE_T hwiMode, - HWI_PROC_FUNC hwiHandler, - HWI_IRQ_PARAM_S *irqParam); +extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,//表示中断号或中断向量的标识。 + HWI_PRIOR_T hwiPrio,//表示中断的优先级。 + HWI_MODE_T hwiMode,//表示中断的模式(如边沿触发、电平触发等)。 + HWI_PROC_FUNC hwiHandler,//表示中断处理函数的指针。 + HWI_IRQ_PARAM_S *irqParam);//表示中断参数的结构体指针。 /** * @ingroup los_hwi @@ -470,6 +769,9 @@ extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, * @see LOS_HwiCreate * @since Huawei LiteOS V100R001C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中删除一个中断处理程序。 +/*HWI_HANDLE_T hwiNum 是函数的第一个参数,表示要删除的中断号或中断向量的标识。 +HWI_IRQ_PARAM_S *irqParam 是函数的第二个参数,表示中断参数的结构体指针。*/ extern UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam); /** @@ -492,6 +794,8 @@ extern UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam); * * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中触发一个指定的中断。 +//HWI_HANDLE_T hwiNum 是函数的参数,表示要触发的中断号或中断向量的标识。 extern UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum); /** @@ -513,6 +817,10 @@ extern UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum); * * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中清除(复位)一个指定的中断。 +/*HWI_HANDLE_T hwiNum 是函数的参数,表示要清除的中断号或中断向量的标识。 +函数的作用是根据指定的中断号,将相应的中断标志位清除,即将中断状态复位。 +通过调用该函数,可以清除中断触发后的状态,以便重新准备下一次中断处理。*/ extern UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum); /** @@ -536,6 +844,10 @@ extern UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum); * @see LOS_HwiDisable * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中使能(启用)一个指定的中断。 +/*HWI_HANDLE_T hwiNum 是函数的参数,表示要使能的中断号或中断向量的标识。 +函数的作用是根据指定的中断号,将相应的中断使能位设置为有效,即启用该中断。 +启用中断后,当满足中断触发条件时,系统将会跳转执行对应的中断处理程序。*/ extern UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum); /** @@ -558,6 +870,10 @@ extern UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum); * @see LOS_HwiEnable * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中禁用(关闭)一个指定的中断。 +/*HWI_HANDLE_T hwiNum 是函数的参数,表示要禁用的中断号或中断向量的标识。 +函数的作用是根据指定的中断号,将相应的中断使能位设置为无效,即禁用该中断。 +禁用中断后,即使满足中断触发条件,系统也不会跳转执行对应的中断处理程序。*/ extern UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum); #ifdef LOSCFG_KERNEL_SMP @@ -582,6 +898,11 @@ extern UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum); * * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中向指定的处理器发送中断请求。 +/*HWI_HANDLE_T hwiNum 是函数的第一个参数,表示要发送的中断号或中断向量的标识。 +UINT32 cpuMask 是函数的第二个参数,表示中断发送的目标处理器掩码,用于指定将中断发送到哪些处理器上。 +函数的作用是向指定的处理器发送中断请求, +即通过中断控制器向目标处理器发送中断信号,触发相应的中断处理操作。*/ extern UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask); /** @@ -605,6 +926,12 @@ extern UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask); * * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中设置指定中断的亲和性(Affinity)。 +/*HWI_HANDLE_T hwiNum 是函数的第一个参数,表示要设置亲和性的中断号或中断向量的标识。 +UINT32 cpuMask 是函数的第二个参数,表示要设置的中断亲和性掩码,用于指定该中断可以在哪些处理器上执行。 +函数的作用是设置指定中断的亲和性,即将中断与特定的处理器相关联。当中断被触发时, +只有与中断亲和性相关的处理器才会尝试执行中断处理程序, +从而避免了不必要的中断传递和处理开销。*/ extern UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask); #endif /* LOSCFG_KERNEL_SMP */ @@ -632,6 +959,11 @@ extern UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask); * @see None * @since Huawei LiteOS V200R005C00 */ +//是一个函数声明,用于在 LiteOS 操作系统中设置指定中断的优先级(Priority)。 +/*HWI_HANDLE_T hwiNum 是函数的第一个参数,表示要设置优先级的中断号或中断向量的标识。 +HWI_PRIOR_T priority 是函数的第二个参数,表示要设置的中断优先级。 +函数的作用是设置指定中断的优先级,即确定中断在系统中的相对执行优先级。 +较高优先级的中断将优先获得处理器资源,并在其他中断之前得到响应和执行。*/ extern UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority); #ifdef LOSCFG_KERNEL_LOWPOWER @@ -652,6 +984,10 @@ extern UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority); * @see None. * @since Huawei LiteOS V200R005C10 */ +//是一个函数指针类型的定义。 +/*这部分定义了函数指针所指向的函数的参数列表,其中包含一个名为 hwiNum 的参数,其类型为 HWI_HANDLE_T。 +因此,整体来说,typedef VOID (*WAKEUPFROMINTHOOK)(HWI_HANDLE_T hwiNum) 定义了一个函数指针类型 WAKEUPFROMINTHOOK, +它指向一个不返回数值的函数,并且该函数接受一个 HWI_HANDLE_T 类型的参数 hwiNum。*/ typedef VOID (*WAKEUPFROMINTHOOK)(HWI_HANDLE_T hwiNum); /** @@ -671,6 +1007,11 @@ typedef VOID (*WAKEUPFROMINTHOOK)(HWI_HANDLE_T hwiNum); * @see None. * @since Huawei LiteOS V200R005C10 */ +//是用于注册中断唤醒钩子函数的外部声明。 +/*WAKEUPFROMINTHOOK hook 是函数的参数,它是一个指向中断唤醒钩子函数的指针。 +函数的作用是注册中断唤醒钩子函数, +即将指定的函数指针(指向中断唤醒处理函数的指针)注册到系统中, +以便在特定的中断事件发生时执行相应的处理操作。*/ extern VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook); #endif