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

内存,进程,task模块注释基本完成. 正在更新: 进程间IPC通讯消息队列模块代码注释...

                鸿蒙内核源码分析系列 https://blog.csdn.net/kuangyufei https://my.oschina.net/u/3751245
上级 12aca2ab
......@@ -76,7 +76,7 @@ typedef struct {
UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
LOS_DL_LIST memList; /**< Pointer to the memory linked list */
} LosQueueCB;
} LosQueueCB;//读写队列分离
/* queue state */
/**
......
......@@ -232,7 +232,7 @@ STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *
}
*bufferSize = msgDataSize;//通过入参 带走消息的大小
} else {//只有读写两种操作,这里就是写队列了.写也分两步走
} else {//只有读写两种操作,这里就是写队列了.写也分两步走 , @@@@@ 这里建议鸿蒙加上 OS_QUEUE_IS_WRITE 判断
if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) {//1.写入消息内容长度 UINT32表示
PRINT_ERR("store message failed\n");
return;
......@@ -244,65 +244,65 @@ STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *
}
}
}
//队列操作参数检查
STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID,
UINT32 operateType, const UINT32 *bufferSize)
{
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {//队列ID和状态判断
return LOS_ERRNO_QUEUE_NOT_CREATE;
}
if (OS_QUEUE_IS_READ(operateType) && (*bufferSize < (queueCB->queueSize - sizeof(UINT32)))) {
if (OS_QUEUE_IS_READ(operateType) && (*bufferSize < (queueCB->queueSize - sizeof(UINT32)))) {//读时判断
return LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL;
} else if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {
} else if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {//写时判断
return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;
}
return LOS_OK;
}
//队列操作.是读是写由operateType定
UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout)
{
LosQueueCB *queueCB = NULL;
LosTaskCB *resumedTask = NULL;
UINT32 ret;
UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);
UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);//获取读写操作标识
UINT32 intSave;
SCHEDULER_LOCK(intSave);
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//获取对应的队列控制块
ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);//参数检查
if (ret != LOS_OK) {
goto QUEUE_END;
}
if (queueCB->readWriteableCnt[readWrite] == 0) {
if (timeout == LOS_NO_WAIT) {
if (queueCB->readWriteableCnt[readWrite] == 0) {//没有数据
if (timeout == LOS_NO_WAIT) {//不等待直接退出
ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL;
goto QUEUE_END;
}
if (!OsPreemptableInSched()) {
if (!OsPreemptableInSched()) {//不能抢占式调度
ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK;
goto QUEUE_END;
}
ret = OsTaskWait(&queueCB->readWriteList[readWrite], timeout, TRUE);
ret = OsTaskWait(&queueCB->readWriteList[readWrite], timeout, TRUE);//任务等待
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
ret = LOS_ERRNO_QUEUE_TIMEOUT;
goto QUEUE_END;
}
} else {
queueCB->readWriteableCnt[readWrite]--;
queueCB->readWriteableCnt[readWrite]--;//对应队列中计数器--
}
OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);
OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);//发起读或写队列操作
if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) {
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));
OsTaskWake(resumedTask);
if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) {//另外的operateType中还有其他消息时,如果 operateType=read,这时去查write队列,读写交互操作
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));//拿到拥有这个队列节点的任务
OsTaskWake(resumedTask);//唤醒任务去处理队列的值
SCHEDULER_UNLOCK(intSave);
LOS_MpSchedule(OS_MP_CPU_ALL);
LOS_Schedule();
LOS_MpSchedule(OS_MP_CPU_ALL);//让所有CPU参与调度
LOS_Schedule();//申请调度
return LOS_OK;
} else {
queueCB->readWriteableCnt[!readWrite]++;
......
......@@ -131,7 +131,7 @@ STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count)
}
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray);
}
//队列检查
VOID OsQueueCheck(VOID)
{
LosQueueCB queueNode = {0};
......
......@@ -43,33 +43,33 @@ extern "C" {
#if (LOSCFG_KERNEL_SMP == YES)
VOID LOS_MpSchedule(UINT32 target)
VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core
{
UINT32 cpuid = ArchCurrCpuid();
target &= ~(1U << cpuid);
HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);
HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//处理器间中断(IPI)
}
//硬中断唤醒处理函数
VOID OsMpWakeHandler(VOID)
{
/* generic wakeup ipi, do nothing */
}
//硬中断调度处理函数
VOID OsMpScheduleHandler(VOID)
{
{//将调度标志设置为与唤醒功能不同,这样就可以在硬中断结束时触发调度程序。
/*
* set schedule flag to differ from wake function,
* so that the scheduler can be triggered at the end of irq.
*/
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
OsPercpuGet()->schedFlag = INT_PEND_RESCH;//贴上调度标签
}
//硬中断调度处理函数
VOID OsMpHaltHandler(VOID)
{
(VOID)LOS_IntLock();
OsPercpuGet()->excFlag = CPU_HALT;
OsPercpuGet()->excFlag = CPU_HALT;//让当前Cpu停止工作
while (1) {}
while (1) {}//陷入空循环,也就是空闲状态
}
VOID OsMpCollectTasks(VOID)
......
......@@ -45,9 +45,9 @@ extern "C" {
#define OS_MP_GC_PERIOD 100 /* ticks */
typedef enum {
LOS_MP_IPI_WAKEUP,
LOS_MP_IPI_SCHEDULE,
LOS_MP_IPI_HALT,
LOS_MP_IPI_WAKEUP, //唤醒CPU
LOS_MP_IPI_SCHEDULE,//调度CPU
LOS_MP_IPI_HALT, //停止CPU
} MP_IPI_TYPE;
#if (LOSCFG_KERNEL_SMP == YES)
......
......@@ -144,10 +144,11 @@ VOID HalIrqInit(VOID)
GIC_REG_32(GICD_CTLR) = 1;
#if (LOSCFG_KERNEL_SMP == YES)
/* register inter-processor interrupt */
(VOID)LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);
(VOID)LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);
(VOID)LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpHaltHandler, 0);
/* 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);//中断处理函数
#endif
}
......
......@@ -399,10 +399,11 @@ VOID HalIrqInit(VOID)
HalIrqInitPercpu();
#if (LOSCFG_KERNEL_SMP == YES)
/* register inter-processor interrupt */
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);
/* 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);//中断处理函数
#endif
}
......
......@@ -171,16 +171,16 @@ LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
return LOS_NOK;
}
#if (LOSCFG_KERNEL_SMP == YES)
#if (LOSCFG_KERNEL_SMP == YES)//多核支持
PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1);
release_secondary_cores();
release_secondary_cores();//让CPU其他核也开始工作,真正的并行开始了.
#endif
CPU_MAP_SET(0, OsHwIDGet());
OsStart();
OsStart();//内核初始化完成,正式开始工作
while (1) {
__asm volatile("wfi");
__asm volatile("wfi");//让cpu进入idle状态
}
}
git add -A
git commit -m '鸿蒙源码分析系列篇 https://blog.csdn.net/kuangyufei
https://my.oschina.net/u/3751245'
git commit -m '内存,进程,task模块注释基本完成. 正在更新: 进程间IPC通讯消息队列模块代码注释...
鸿蒙内核源码分析系列 https://blog.csdn.net/kuangyufei https://my.oschina.net/u/3751245'
git push origin
git push gitee_origin master
git push github_origin master
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册