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" { *