提交 3759e9fe 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

多处理器支持和异常处理部分代码注释

搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
上级 e97fa9f1
......@@ -52,9 +52,9 @@
#define OS_EXCEPT_SWI 0x02 //软件定时器中断
#define OS_EXCEPT_PREFETCH_ABORT 0x03 //预取异常
#define OS_EXCEPT_DATA_ABORT 0x04 //数据异常
#define OS_EXCEPT_FIQ 0x05 //快中断
#define OS_EXCEPT_FIQ 0x05 //快中断异常
#define OS_EXCEPT_ADDR_ABORT 0x06 //地址异常
#define OS_EXCEPT_IRQ 0x07 //普通中断
#define OS_EXCEPT_IRQ 0x07 //普通中断异常
/* Define core num */
#ifdef LOSCFG_KERNEL_SMP
......
......@@ -79,9 +79,9 @@ STATIC UINT32 g_currHandleExcCpuID = INVALID_CPUID;
VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr);
UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 };//
BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM];//记录CPU core 是否在用户态运行
STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook;//函数指针 ->hook
STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook;//全局异常处理钩子
#if (LOSCFG_KERNEL_SMP == YES)
STATIC SPIN_LOCK_INIT(g_excSerializerSpin);
STATIC SPIN_LOCK_INIT(g_excSerializerSpin);//初始化异常系列化自旋锁
STATIC UINT32 g_currHandleExcPID = OS_INVALID_VALUE;
STATIC UINT32 g_nextExcWaitCpu = INVALID_CPUID;
#endif
......@@ -223,10 +223,10 @@ UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT3
return LOS_ERRNO_VM_NOT_FOUND;
}
}
//异常类型
STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr)
{
/* undefinited exception handling or software interrupt */
/* undefinited exception handling or software interrupt */ //未定义的异常处理或软件中断
if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) {
if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */
excBufAddr->PC = excBufAddr->PC - ARM_INSTR_LEN;
......@@ -309,7 +309,7 @@ STATIC VOID OsExcSysInfo(UINT32 excType, const ExcContext *excBufAddr)
PrintExcInfo("fp = 0x%x\n", excBufAddr->R11);//FP(frame pointer)栈帧寄存器R11
}
//异常情况下打印各寄存器的信息
STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr)
{
/*
......@@ -335,7 +335,7 @@ STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr)
excBufAddr->R7, excBufAddr->R8, excBufAddr->R9, excBufAddr->R10,
excBufAddr->R11, excBufAddr->R12, excBufAddr->regCPSR);
}
//注册hook
//注册异常处理钩子
LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook)
{
UINT32 intSave;
......
......@@ -304,11 +304,11 @@ LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID)//硬件中断初始化
return;
}
//创建一个硬中断
LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
HWI_PRIOR_T hwiPrio,
HWI_MODE_T hwiMode,
HWI_PROC_FUNC hwiHandler,
HwiIrqParam *irqParam)
LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, //硬中断句柄编号 默认范围[0-127]
HWI_PRIOR_T hwiPrio, //硬中断优先级
HWI_MODE_T hwiMode, //硬中断模式 共享和非共享
HWI_PROC_FUNC hwiHandler,//硬中断处理函数
HwiIrqParam *irqParam) //硬中断处理函数参数
{
UINT32 ret;
......
......@@ -147,8 +147,8 @@ STATIC INLINE UINTPTR Get_Fp(VOID)
* los_exc.h: the header file that contains the API declaration.
* @see None.
*/
typedef VOID (*EXC_PROC_FUNC)(UINT32, ExcContext *, UINT32, UINT32);
typedef VOID (*EXC_PROC_FUNC)(UINT32, ExcContext *, UINT32, UINT32);//定义异常处理函数钩子
//此API用于根据异常处理函数的类型定义异常处理函数钩子并记录异常
/**
* @ingroup los_exc
* @brief Register an exception handling hook.
......@@ -165,7 +165,7 @@ typedef VOID (*EXC_PROC_FUNC)(UINT32, ExcContext *, UINT32, UINT32);
* los_exc.h: the header file that contains the API declaration.
* @see None.
*/
extern UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook);
extern UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook);//注册异常处理钩子
/**
* @ingroup los_exc
......
......@@ -282,9 +282,9 @@ extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM];
* @par Dependency:
* <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
* @see LOS_IntRestore
*///在所有中断被禁用之前获得的CPSR值
STATIC INLINE UINT32 LOS_IntLock(VOID)
{//此API用于禁用CPSR中的所有IRQ和FIQ中断。
*/
STATIC INLINE UINT32 LOS_IntLock(VOID)//在所有中断被禁用之前获得的CPSR值 /|\
{//此API用于禁用CPSR中的所有IRQ和FIQ中断。CPSR:程序状态寄存器(current program status register)
return ArchIntLock();
}//IRQ(Interrupt Request):指中断模式。FIQ(Fast Interrupt Request):指快速中断模式。
......@@ -307,8 +307,8 @@ STATIC INLINE UINT32 LOS_IntLock(VOID)
* @par Dependency:
* <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
* @see LOS_IntLock
*///启用所有中断后获得的CPSR值
STATIC INLINE UINT32 LOS_IntUnLock(VOID)
*/
STATIC INLINE UINT32 LOS_IntUnLock(VOID)//启用所有中断后获得的CPSR值
{//此API用于启用CPSR中的所有IRQ和FIQ中断。
return ArchIntUnlock();
}
......@@ -333,8 +333,8 @@ STATIC INLINE UINT32 LOS_IntUnLock(VOID)
* @par Dependency:
* <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
* @see LOS_IntLock
*///在所有中断被禁用之前获得的CPSR值
STATIC INLINE VOID LOS_IntRestore(UINT32 intSave)
*/
STATIC INLINE VOID LOS_IntRestore(UINT32 intSave)//在所有中断被禁用之前获得的CPSR值
{//只有在禁用所有中断之后才能调用此API,并且输入参数值应为LOS_IntLock返回的值。
ArchIntRestore(intSave);
}
......
......@@ -369,7 +369,7 @@ extern LosProcessCB *g_runProcess[LOSCFG_KERNEL_CORE_NUM];//运行进程,并
extern UINT32 g_processMaxNum;//进程最大数量
#define OS_PID_CHECK_INVALID(pid) (((UINT32)(pid)) >= g_processMaxNum)
//内联函数 进程ID是否有效
STATIC INLINE BOOL OsProcessIDUserCheckInvalid(UINT32 pid)
{
return ((pid >= g_processMaxNum) || (pid == 0));
......@@ -390,7 +390,7 @@ STATIC INLINE VOID OsCurrProcessSet(const LosProcessCB *process)
{
g_runProcess[ArchCurrCpuid()] = (LosProcessCB *)process;
}
//以不完全的方式获取进程ID,鸿蒙Unsafe和safe的区别在于有没有加锁.
STATIC INLINE UINT32 OsCpuProcessIDGetUnsafe(UINT16 cpuID)
{
LosProcessCB *runProcess = g_runProcess[cpuID];
......
......@@ -330,7 +330,7 @@ typedef struct {
#if (LOSCFG_KERNEL_SMP_LOCKDEP == YES)
LockDep lockDep;
#endif
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES) //调度统计开关,显然打开这个开关性能会受到影响,鸿蒙默认是关闭的
SchedStat schedStat; /**< Schedule statistics */ //调度统计
#endif
#endif
......@@ -350,7 +350,7 @@ typedef struct {
BOOL accessMap[LOSCFG_BASE_CORE_TSK_LIMIT];//访问图,指的是task之间是否能访问的标识,LOSCFG_BASE_CORE_TSK_LIMIT 为任务池总数
#endif
} LosTaskCB;
//LosTask结构体是给外部用的
//LosTask结构体是给外部使用的
typedef struct {
LosTaskCB *runTask;
LosTaskCB *newTask;
......
......@@ -60,12 +60,12 @@ extern "C" {
/* Memory pool information structure */
typedef struct {
VOID *pool; /* Starting address of a memory pool */
UINT32 poolSize; /* Memory pool size */
UINT32 flag; /* Whether the memory pool supports expansion */
#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES)
UINT32 poolWaterLine; /* Maximum usage size in a memory pool */
UINT32 poolCurUsedSize; /* Current usage size in a memory pool */
VOID *pool; /* Starting address of a memory pool */ //内存池开始地址
UINT32 poolSize; /* Memory pool size */ //内存池大小
UINT32 flag; /* Whether the memory pool supports expansion */ //内存池是否支持扩展
#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) //警戒线
UINT32 poolWaterLine; /* Maximum usage size in a memory pool */ //内存池中的最大使用大小
UINT32 poolCurUsedSize; /* Current usage size in a memory pool */ //当前已使用内存池大小
#endif
#ifdef LOSCFG_MEM_MUL_POOL
VOID *nextPool;
......@@ -1369,7 +1369,7 @@ STATIC UINT32 DoOsMemIntegrityCheck(LosMemDynNode **tmpNode, const VOID *pool, c
}
return LOS_OK;
}
//内存池完整性检查
STATIC UINT32 OsMemIntegrityCheck(const VOID *pool, LosMemDynNode **tmpNode, LosMemDynNode **preNode)
{
const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool;
......@@ -1397,7 +1397,7 @@ STATIC UINT32 OsMemIntegrityCheck(const VOID *pool, LosMemDynNode **tmpNode, Los
return LOS_OK;
}
#ifdef LOSCFG_MEM_LEAKCHECK
#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检查开关
STATIC VOID OsMemNodeBacktraceInfo(const LosMemDynNode *tmpNode,
const LosMemDynNode *preNode)
{
......@@ -1460,7 +1460,7 @@ STATIC VOID OsMemNodeInfo(const LosMemDynNode *tmpNode,
PRINTK("\n---------------------------------------------\n");
}
}
//内存池完整性检查错误
STATIC VOID OsMemIntegrityCheckError(const LosMemDynNode *tmpNode,
const LosMemDynNode *preNode,
UINT32 intSave)
......@@ -1504,7 +1504,7 @@ STATIC VOID OsMemIntegrityCheckError(const LosMemDynNode *tmpNode,
* Input : pool --Pointer to memory pool
* Return : LOS_OK --memory pool integrate or LOS_NOK--memory pool impaired
*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(const VOID *pool)
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(const VOID *pool) //内存池完整性检查
{
LosMemDynNode *tmpNode = NULL;
LosMemDynNode *preNode = NULL;
......
......@@ -435,7 +435,7 @@ STATIC VOID OsProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosT
SCHEDULER_UNLOCK(intSave);
}
}
//shell task -a
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqBuf, UINT16 flag)
{
UINT32 size;
......
......@@ -40,6 +40,12 @@
extern "C" {
#endif
#endif /* __cplusplus */
/*******************************************************
多CPU核的操作系统3种处理模式(SMP+AMP+BMP) 鸿蒙实现的是 SMP 的方式
非对称多处理(Asymmetric multiprocessing,AMP)每个CPU内核运行一个独立的操作系统或同一操作系统的独立实例(instantiation)。
对称多处理(Symmetric multiprocessing,SMP)一个操作系统的实例可以同时管理所有CPU内核,且应用并不绑定某一个内核。
混合多处理(Bound multiprocessing,BMP)一个操作系统的实例可以同时管理所有CPU内核,但每个应用被锁定于某个指定的核心。
********************************************************/
#if (LOSCFG_KERNEL_SMP == YES)
//给target对应位CPU发送调度信号
......@@ -63,7 +69,7 @@ VOID OsMpScheduleHandler(VOID)
*/
OsPercpuGet()->schedFlag = INT_PEND_RESCH;//贴上调度标签
}
//硬中断调度处理函数
//硬中断暂停处理函数
VOID OsMpHaltHandler(VOID)
{
(VOID)LOS_IntLock();
......@@ -71,7 +77,7 @@ VOID OsMpHaltHandler(VOID)
while (1) {}//陷入空循环,也就是空闲状态
}
//MP定时器处理函数, 递归检查所有可用任务
VOID OsMpCollectTasks(VOID)
{
LosTaskCB *taskCB = NULL;
......@@ -86,7 +92,7 @@ VOID OsMpCollectTasks(VOID)
continue;
}
/*
/* 虽然任务状态不是原子的,但此检查可能成功,但无法完成删除,此删除将在下次运行之前处理
* though task status is not atomic, this check may success but not accomplish
* the deletion; this deletion will be handled until the next run.
*/
......@@ -98,14 +104,14 @@ VOID OsMpCollectTasks(VOID)
}
}
}
//MP(multiprocessing) 多核处理器初始化
UINT32 OsMpInit(VOID)
{
UINT16 swtmrId;
(VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD,
(SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);
(VOID)LOS_SwtmrStart(swtmrId);
(VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, //创建一个周期性,持续时间为 100个tick的定时器
(SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);//OsMpCollectTasks为超时回调函数
(VOID)LOS_SwtmrStart(swtmrId);//开始定时任务
return LOS_OK;
}
......
......@@ -336,11 +336,11 @@ extern UINT32 __heap_end; // 堆区结束地址
/****************************** SMP module configuration **************************/
#ifndef LOSCFG_KERNEL_SMP
#define LOSCFG_KERNEL_SMP NO //SMP一般指对称多处理。对称多处理"(Symmetrical Multi-Processing)
#define LOSCFG_KERNEL_SMP NO //SMP指对称多处理(Symmetrical Multi-Processing),多核时要设为 YES
#endif
#ifndef LOSCFG_KERNEL_SMP_LOCKDEP
#define LOSCFG_KERNEL_SMP_LOCKDEP NO
#define LOSCFG_KERNEL_SMP_LOCKDEP NO //死锁检测模块 Lockdep
#endif
#ifndef LOSCFG_KERNEL_SMP_TASK_SYNC
......@@ -348,20 +348,20 @@ extern UINT32 __heap_end; // 堆区结束地址
#endif
#ifndef LOSCFG_KERNEL_SCHED_STATISTICS
#define LOSCFG_KERNEL_SCHED_STATISTICS NO
#define LOSCFG_KERNEL_SCHED_STATISTICS NO //对任务调度的统计
#endif
#if (LOSCFG_KERNEL_SMP == YES)
#define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM
#define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM //多核情况下支持的CPU核数
#else
#define LOSCFG_KERNEL_CORE_NUM 1
#define LOSCFG_KERNEL_CORE_NUM 1 //单核配置
#endif
#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1)
#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1) //CPU掩码,每一个核占用一个位,用于计算和定位具体CPU核
/****************************** trace module configuration **************************/
#ifndef LOSCFG_KERNEL_TRACE
#define LOSCFG_KERNEL_TRACE NO
#define LOSCFG_KERNEL_TRACE NO //内核追踪开关
#endif
/**
......@@ -369,7 +369,7 @@ extern UINT32 __heap_end; // 堆区结束地址
* It's the total size of trace buffer. It's in the unit of char
*/
#if (LOSCFG_KERNEL_TRACE == YES)
#define LOS_TRACE_BUFFER_SIZE 2048
#define LOS_TRACE_BUFFER_SIZE 2048 //内核追踪缓存大小 2K
#endif
/**
......@@ -383,28 +383,28 @@ extern UINT32 __heap_end; // 堆区结束地址
/**
* @ingroup los_config
* The Version number of Public
* The Version number of Public //Public的版本号 ,每个占8位,刚好一个字节
*/
#define KERNEL_MAJOR 2
#define KERNEL_MINOR 0
#define KERNEL_PATCH 0
#define KERNEL_ITRE 35
#define KERNEL_MAJOR 2 //主版本号
#define KERNEL_MINOR 0 //小版本号
#define KERNEL_PATCH 0 //补丁版本号
#define KERNEL_ITRE 35 //内部定义版本号
#define VERSION_NUM(a, b, c, d) (((a) << 24) | ((b) << 16) | (c) << 8 | (d))
#define KERNEL_OPEN_VERSION_NUM VERSION_NUM(KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE)
/****************************** Dynamic loading module configuration **************************/
#ifndef OS_AUTOINIT_DYNLOADER
#define OS_AUTOINIT_DYNLOADER YES
#define OS_AUTOINIT_DYNLOADER YES //是否支持动态加载ELF运行
#endif
/****************************** exception information configuration ******************************/
#ifdef LOSCFG_SHELL_EXCINFO
#ifdef LOSCFG_SHELL_EXCINFO //异常信息开关
/**
* @ingroup los_config
* the size of space for recording exception information
*/
#define EXCINFO_RECORD_BUF_SIZE (16 * 1024)
#define EXCINFO_RECORD_BUF_SIZE (16 * 1024) //记录异常信息缓存大小 16K
/**
* @ingroup los_config
......@@ -416,7 +416,7 @@ extern UINT32 __heap_end; // 堆区结束地址
* </ul>
*
*/
#define EXCINFO_RECORD_ADDR (0xffffffff)
#define EXCINFO_RECORD_ADDR (0xffffffff) //记录异常信息的空间地址
/**
* @ingroup los_config
......@@ -440,7 +440,7 @@ extern UINT32 __heap_end; // 堆区结束地址
* @par Dependency:
* <ul><li>los_config.h: the header file that contains the type defination.</li></ul>
* @see
*/
*/ //定义用于读取或写入异常信息的指针函数类型
typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf);
/**
......@@ -469,6 +469,13 @@ typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag,
* <ul><li>los_config.h: the header file that contains the API declaration.</li></ul>
* @see
*/
/**
* 此API用于注册记录异常信息函数,并指定位置、空间和大小
* startAddr: 保存发送异常的地址信息的启始地址
* space: buf的大小
* buf: 缓存区
* hook: 读写异常信息的函数
*/
VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook);
#endif
......
......@@ -45,12 +45,12 @@ extern CONSOLE_CB *g_console[];
#define IS_UARTSHELL_ID(taskID) (((taskID) == shellCB->shellTaskHandle) || \
((taskID) == shellCB->shellEntryHandle))
//判断是否为空闲任务
STATIC BOOL IsIdleTask(UINT32 taskID)
{
UINT32 i;
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {//检查每个CPU core的空闲任务
if (taskID == g_percpu[i].idleTaskID) {
return TRUE;
}
......@@ -58,12 +58,12 @@ STATIC BOOL IsIdleTask(UINT32 taskID)
return FALSE;
}
//判断是否为定时器任务
STATIC BOOL IsSwtTask(UINT32 taskID)
{
UINT32 i;
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {//检查每个CPU core的定时器任务
if (taskID == g_percpu[i].swtmrTaskID) {
return TRUE;
}
......@@ -71,14 +71,14 @@ STATIC BOOL IsSwtTask(UINT32 taskID)
return FALSE;
}
//检查互动任务,或者叫中间态任务,怎么理解?可理解为其他任务而服务的任务.
UINT32 OsExcInteractionTaskCheck(const TSK_INIT_PARAM_S *initParam)
{
if (initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)OsIdleTask) {
if (initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)OsIdleTask) {//空闲任务是属于这种类型
return LOS_OK;
}
if ((initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellTask) ||
(initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellEntry)) {
if ((initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellTask) ||//shell 属于这种类型
(initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellEntry)) {//@note_thinking 暂没理解它和 ShellTask的区别
return LOS_OK;
}
return LOS_NOK;
......
......@@ -42,11 +42,11 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_SHELL_EXCINFO
STATIC log_read_write_fn g_excInfoRW = NULL; /* the hook of read-writing exception information */
STATIC CHAR *g_excInfoBuf = NULL; /* pointer to the buffer for storing the exception information */
STATIC UINT32 g_excInfoIndex = 0xFFFFFFFF; /* the index of the buffer for storing the exception information */
STATIC UINT32 g_recordAddr = 0; /* the address of storing the exception information */
STATIC UINT32 g_recordSpace = 0; /* the size of storing the exception information */
STATIC log_read_write_fn g_excInfoRW = NULL; /* the hook of read-writing exception information *///读写异常信息的钩子
STATIC CHAR *g_excInfoBuf = NULL; /* pointer to the buffer for storing the exception information *///指向存储异常信息的缓冲区的指针
STATIC UINT32 g_excInfoIndex = 0xFFFFFFFF; /* the index of the buffer for storing the exception information *///用于存储异常信息的缓冲区的索引
STATIC UINT32 g_recordAddr = 0; /* the address of storing the exception information */ //存储异常信息的地址
STATIC UINT32 g_recordSpace = 0; /* the size of storing the exception information */ //存储异常信息的大小
VOID SetExcInfoRW(log_read_write_fn func)
{
......@@ -97,7 +97,7 @@ UINT32 GetRecordSpace(VOID)
{
return g_recordSpace;
}
//vsnprintf 为C标准库可变参数的实现函数 见于 ..\third_party\musl\kernel\src\stdio\vsnprintf.c
VOID WriteExcBufVa(const CHAR *format, va_list arglist)
{
errno_t ret;
......@@ -112,16 +112,15 @@ VOID WriteExcBufVa(const CHAR *format, va_list arglist)
g_excInfoIndex += ret;
}
}
//写异常信息到系统异常信息中心
VOID WriteExcInfoToBuf(const CHAR *format, ...)
{
va_list arglist;
va_start(arglist, format);
WriteExcBufVa(format, arglist);
va_end(arglist);
va_list arglist;//va_arg
va_start(arglist, format);//从任务栈中取出入栈参数
WriteExcBufVa(format, arglist);//入栈参数列表作为实参传入交由vsnprintf处理
va_end(arglist);//释放资源
}
//用于注册记录异常信息函数,并指定位置、空间和大小
VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook)
{
if ((hook == NULL) || (buf == NULL)) {
......@@ -135,7 +134,7 @@ VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_writ
g_excInfoRW = hook;
#ifdef LOSCFG_FS_VFS
los_vfs_init();
los_vfs_init();//初始化虚拟文件系统
#endif
}
......
......@@ -47,25 +47,25 @@ STATIC VOID OsMagicTaskShow(VOID);
STATIC VOID OsMagicPanic(VOID);
STATIC VOID OsMagicMemCheck(VOID);
STATIC MagicKeyOp g_magicMemCheckOp = {
STATIC MagicKeyOp g_magicMemCheckOp = {//快捷键内存检查
.opHandler = OsMagicMemCheck,
.helpMsg = "Check system memory(ctrl+e) ",
.magicKey = 0x05 /* ctrl + e */
};
STATIC MagicKeyOp g_magicPanicOp = {
.opHandler = OsMagicPanic,
STATIC MagicKeyOp g_magicPanicOp = {//panic 表示kernel走到了一个不知道该怎么走下一步的状况,
.opHandler = OsMagicPanic, //一旦到这个情况,kernel就尽可能把它此时能获取的全部信息都打印出来.
.helpMsg = "System panic(ctrl+p) ",
.magicKey = 0x10 /* ctrl + p */
};
STATIC MagicKeyOp g_magicTaskShowOp = {
STATIC MagicKeyOp g_magicTaskShowOp = { //快捷键显示任务操作
.opHandler = OsMagicTaskShow,
.helpMsg = "Show task information(ctrl+t) ",
.magicKey = 0x14 /* ctrl + t */
};
STATIC MagicKeyOp g_magicHelpOp = {
STATIC MagicKeyOp g_magicHelpOp = { //快捷键帮助操作
.opHandler = OsMagicHelp,
.helpMsg = "Show all magic op key(ctrl+z) ",
.magicKey = 0x1a /* ctrl + z */
......@@ -99,7 +99,7 @@ STATIC VOID OsMagicHelp(VOID)
PRINTK("\n");
return;
}
//执行 shell task -a 命令
STATIC VOID OsMagicTaskShow(VOID)
{
const CHAR *arg = "-a";
......@@ -113,7 +113,7 @@ STATIC VOID OsMagicPanic(VOID)
LOS_Panic("Magic key :\n");
return;
}
//快捷键触发内存检查
STATIC VOID OsMagicMemCheck(VOID)
{
if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) {
......@@ -125,10 +125,10 @@ STATIC VOID OsMagicMemCheck(VOID)
INT32 CheckMagicKey(CHAR key)
{
#ifdef LOSCFG_ENABLE_MAGICKEY
#ifdef LOSCFG_ENABLE_MAGICKEY //魔法键开关
INT32 i;
STATIC UINT32 magicKeySwitch = 0;
if (key == 0x12) { /* ctrl + r */
if (key == 0x12) { /* ctrl + r */ //用0x12 来打开和关闭魔法键开关
magicKeySwitch = ~magicKeySwitch;
if (magicKeySwitch != 0) {
PRINTK("Magic key on\n");
......
......@@ -40,10 +40,10 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
typedef struct {
VOID (*opHandler)(VOID);
CHAR *helpMsg;
CHAR magicKey;
typedef struct { //魔法键处理结构体
VOID (*opHandler)(VOID); //触发执行函数
CHAR *helpMsg; //消息提示
CHAR magicKey; //魔法键
} MagicKeyOp;
extern INT32 CheckMagicKey(CHAR key);
......
......@@ -234,13 +234,13 @@ __attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...)
OsVprintf(fmt, ap, EXC_OUTPUT);
va_end(ap);
}
//打印异常信息
VOID PrintExcInfo(const CHAR *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
/* uart output without print-spinlock */
OsVprintf(fmt, ap, EXC_OUTPUT);
OsVprintf(fmt, ap, EXC_OUTPUT);//异常信息打印主体函数
#ifdef LOSCFG_SHELL_EXCINFO
WriteExcBufVa(fmt, ap);
#endif
......
......@@ -84,7 +84,26 @@ LITE_OS_SEC_TEXT STATIC VOID OsCpupCmdHelp(VOID)
" 1 SysCpuUsage in 1s\n"
" others SysCpuUsage in all time\n");
}
/******************************************************
命令功能
cpup命令用于查询系统CPU的占用率。
命令格式
cpup [mode] [taskID]
参数 参数说明 取值范围
mode
● 缺省:显示系统最近10s内的CPU占用率。
● 0:显示系统最近10s内的CPU占用率。
● 1:显示系统最近1s内的CPU占用率。
● 其他数字:显示系统启动至今总的CPU 占用率。
taskID 任务ID号 [0,0xFFFFFFFF]
使用指南
参数缺省时,显示系统10s前的CPU占用率。
只有一个参数时,该参数为mode,显示系统相应时间前的CPU占用率。
输入两个参数时,第一个参数为mode,第二个参数为taskID,显示对应ID号任务的相应时间前的CPU占用率。
举例:输入cpup 1 5 表示 显示5号任务最近1s内的CPU占用率
******************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdCpup(INT32 argc, const CHAR **argv)
{
size_t mode, pid;
......@@ -111,15 +130,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdCpup(INT32 argc, const CHAR **argv)
}
if (mode > CPUP_ALL_TIME) {
mode = CPUP_ALL_TIME;
mode = CPUP_ALL_TIME;//统计所有CPU的耗时
}
if (argc == 1) {
OsCmdCpupOperateOneParam(mode);
OsCmdCpupOperateOneParam(mode);//处理只有一个参数的情况 例如 cpup 1
return LOS_OK;
}
pid = strtoul(argv[1], &bufID, 0);
pid = strtoul(argv[1], &bufID, 0);//musl标准库函数,将字符串转成无符号整型
if (OsProcessIDUserCheckInvalid(pid) || (*bufID != 0)) {
PRINTK("\nUnknown pid: %s\n", argv[1]);
return LOS_OK;
......@@ -132,7 +151,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdCpup(INT32 argc, const CHAR **argv)
/* when the parameters number is two */
if (argc == 2) {
OsCmdCpupOperateTwoParam(mode, pid);
OsCmdCpupOperateTwoParam(mode, pid);//处理有两个参数的情况 例如 cpup 1 5
return LOS_OK;
}
......
......@@ -139,9 +139,9 @@ typedef struct tagCpupInfo {
* Query the CPU usage of the system.
*/
enum {
CPUP_LAST_TEN_SECONDS = 0, /**< Display CPU usage in the last ten seconds. */
CPUP_LAST_ONE_SECONDS = 1, /**< Display CPU usage in the last one seconds. */
CPUP_ALL_TIME = 0xffff /**< Display CPU usage from system startup to now. */
CPUP_LAST_TEN_SECONDS = 0, /**< Display CPU usage in the last ten seconds. */ //显示最近10秒的CPU使用情况。
CPUP_LAST_ONE_SECONDS = 1, /**< Display CPU usage in the last one seconds. */ //显示最近1秒的CPU使用情况。
CPUP_ALL_TIME = 0xffff /**< Display CPU usage from system startup to now. */ //显示从系统启动到现在的CPU使用情况
};
......
......@@ -106,7 +106,7 @@ typedef enum { //输出类型
NO_OUTPUT = 0,
UART_OUTPUT = 1, //串口输出
CONSOLE_OUTPUT = 2, //控制台输出
EXC_OUTPUT = 3 //只输出当前CPU所执行任务的Log
EXC_OUTPUT = 3 //出现异常时的输出
} OutputType;
extern VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type);
......
......@@ -190,7 +190,7 @@ LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
* @see LOS_SpinLock
*/
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
{//自旋锁是不切换任务上下文的,忙等状态.锁的是细颗粒的操作,代码量小,运行时间的临界区
{//自旋锁是不切换任务上下文的,忙等状态.锁的是细颗粒的操作,代码量小,运行时间极短的临界区
*intSave = LOS_IntLock();
LOS_SpinLock(lock);
}
......@@ -286,9 +286,9 @@ LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
{
(VOID)lock;
}
//自旋锁是不切换任务上下文的,忙等状态.锁的是细颗粒的操作,代码量小,运行时间极短的临界区
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
{//自旋锁是不切换任务上下文的,忙等状态.锁的是细颗粒的操作,代码量小,运行时间端的临界区
{
(VOID)lock;
*intSave = LOS_IntLock();
}
......
......@@ -401,9 +401,9 @@ VOID HalIrqInit(VOID)
#if (LOSCFG_KERNEL_SMP == YES)
/* register inter-processor interrupt *///注册寄存器处理器间中断处理函数,啥意思?就是当前CPU核向其他CPU核发送中断信号
//处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。
LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//中断处理函数
LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数
LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数
LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0); //唤醒处理函数
LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//调度处理函数
LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpScheduleHandler, 0); //暂停处理函数
#endif
}
......
git add -A
git commit -m 'prinf,可变参数是如何实现的? 用到了musl的哪些标准C库代码
git commit -m '多处理器支持和异常处理部分代码注释
搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册