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

开始对 lite ipc模块注解

搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
上级 3e51bc82
......@@ -2,27 +2,26 @@
[鸿蒙源码分析系列篇 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA ](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages) 从 HarmonyOS 架构层视角整理成文, 并首创用生活场景讲故事的方式试图去解构内核,一窥究竟。
# **[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note): 鸿蒙内核源码注释中文版**
[![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)
每个码农,职业生涯,都应精读一遍内核源码. 鸿蒙内核源码就是很好的精读项目.一旦熟悉内核代码级实现,将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
项目中文注解鸿蒙官方内核源码,图文并茂,详细阐述鸿蒙架构和代码设计细节,每个码农,学职生涯,都应精读一遍内核源码.
精读内核源码最大的好处是:将孤立知识点织成一张高浓度,高密度底层网,对计算机底层体系化理解形成永久记忆,从此高屋建瓴分析/解决问题.
## **做了些什么呢**
**[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note)** 是在鸿蒙官方开源项目 **[OpenHarmony/kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a)** 基础上给源码加上中文注解的版本,目前几大核心模块加注已基本完成,正持续加注完善中...
**[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note)** 是在鸿蒙官方开源项目 **[OpenHarmony/kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a)** 基础上给源码加上中文注解的版本,目前几大核心模块加注已基本完成,**整体加注完成70%**,其余正持续加注完善中...
- ### **为何想给鸿蒙源码加上中文注释**
源于注者大学时阅读linux 2.6 内核痛苦经历,一直有个心愿,想让更多计算机尤其是内核感兴趣的减少阅读时间,加速对计算机系统级的理解,不至于过早的放弃.但因过程种种,一直没有成行,基本要放弃这件事了. 但9月10日鸿蒙正式开源,重新激活了注者多年的心愿,就有那么点一发不可收拾了 :|P
源于大学时阅读linux 2.6 内核痛苦经历,一直有个心愿,想让更多计算机尤其是内核感兴趣的减少阅读时间,加速对计算机系统级的理解,不至于过早的放弃.但因过程种种,一直没有成行,基本要放弃这件事了. 但9月10日鸿蒙正式开源,重新激活了注者多年的心愿,就有那么点一发不可收拾了 :|P
- ### **致敬鸿蒙内核开发者**
感谢开放原子开源基金会,鸿蒙内核开发者提供了如此优秀的源码,一了多年的夙愿,津津乐道于此.越深入精读内核源码,越能感受到设计者的精巧用心,创新突破. 向开发者致敬. 可以毫不夸张的说 **[OpenHarmony/kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a)** 可作为大学C语言,数据结构,操作系统,汇编语言 四门课程的教学项目.如此宝库,不深入研究实在是太可惜了.
感谢开放原子开源基金会,鸿蒙内核开发者提供了如此优秀的源码,一了多年的夙愿,津津乐道于此.越深入精读内核源码,越能感受到设计者的精巧用心,创新突破, 向开发者致敬. 可以毫不夸张的说鸿蒙内核源码可作为大学C语言,数据结构,操作系统,汇编语言 四门课程的教学项目.如此宝库,不深入研究实在是暴殄天物,于心不忍.
### **在加注的源码中有哪些特殊的记号**
- ### **在加注的源码中有哪些特殊的记号**
搜索 **[@note_pic]()** 可查看绘制的全部字符图
......@@ -32,19 +31,15 @@
- ### **理解内核的三个层级**
笔者认为理解内核需分三个层级:
第一: **普通概念映射级** 这一级不涉及专业知识,用大众所熟知的公共认知就能听明白是个什么概念,也就是说用一个普通人都懂的概念去诠释或者映射一个他们从没听过的概念.说别人能听得懂的话这很重要!!! 一个没学过计算机知识的卖菜大妈就不可能知道内核的基本运作了吗? NO!,笔者在系列篇中试图用 **[鸿蒙源码分析系列篇|张大爷系列故事【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)** 去构建这一层级的认知,希望能卷入更多的人来关注基础软件,尤其是那些有钱的投资人加大对国家基础软件的投入.
第二: **专业概念抽象级** 这一级是抽象出一个专业的逻辑概念,让学过点计算机知识的人能听得懂,可以不用去了解具体的细节点, 比如虚拟内存,老百姓是听不懂的,学过计算机的人都懂,具体怎么实现的很多人又都不懂了,但这并不妨碍成为一个优秀的上层应用程序员,笔者试图用 **[鸿蒙源码分析系列篇 【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)** 去构建这一层级的认知,希望能卷入更多对内核感兴趣的应用软件人才流入基础软件生态, 应用软件咱们是无敌宇宙,但基础软件却很薄弱.
笔者认为理解内核可分三个层级:
三: **具体微观代码级** 这一级是具体到每一行代码的实现,到了用代码指令级的地步, **[鸿蒙内核源码注释中文版 kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note)** 试图解构这一层级的认知,英文是天生适合设计成编程语言的人类语言,计算机的01码映射到人类世界的26个字母,诞生了太多的伟大奇迹.但我们的母语注定了很大部分人存在着语言层级的映射,希望注释中文版能让更多爱好者参与进来一起研究,拔高咱基础软件的地位.
一: **普通概念映射级** 这一级不涉及专业知识,用大众所熟知的公共认知就能听明白是个什么概念,也就是说用一个普通人都懂的概念去诠释或者映射一个他们从没听过的概念.说别人能听得懂的话这很重要!!! 一个没学过计算机知识的卖菜大妈就不可能知道内核的基本运作了吗? NO!,笔者在系列篇中试图用 **[鸿蒙源码分析系列篇|张大爷系列故事【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)** 去引导这一层级的认知,希望能卷入更多的人来关注基础软件,尤其是那些有钱的投资人加大对基础软件的投入.
鸿蒙是面向未来设计的系统,高瞻远瞩,格局远大,设计精良, 知识点巨多, 把研究过程心得写成鸿蒙源码分析系列篇,如此 源码中文注释+系列篇文章 将加速理解鸿蒙内核实现过程.
第二: **专业概念抽象级** 这一级是抽象出一个专业的逻辑概念,让学过点计算机知识的人能听得懂,可以不用去了解具体的细节点, 比如虚拟内存,老百姓是听不懂的,学过计算机的人都懂,具体怎么实现的很多人又都不懂了,但这并不妨碍成为一个优秀的上层应用程序员,笔者试图用 **[鸿蒙源码分析系列篇 【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)** 从宏观尺度去构建这一层级的认知,希望能卷入更多对内核感兴趣的应用软件人才流入基础软件生态, 应用软件咱们是无敌宇宙,但基础软件却很薄弱.
系列篇文章 进入 >\> [鸿蒙系统源码分析(总目录) 【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)查看,两大站点持续更新,感谢CSDN和OSCHINA对博客的推荐支持.
第三: **具体微观代码级** 这一级是具体到每一行代码的实现,到了用代码指令级的地步,这段代码是什么意思?为什么要这么设计? **[鸿蒙内核源码注释中文版 kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note)** 试图从细微处去拆解这一层级的认知,英文是天生适合设计成编程语言的人类语言,计算机的01码映射到人类世界的26个字母,诞生了太多的伟大奇迹.但我们的母语注定了很大部分人存在着自然语言层级的映射,希望注释中文版能让更多爱好者快速的理解内核,参与到基础软件的研究和开发中.
注释中文版 进入 >\> [鸿蒙内核源码注释中文版 【 Gitee仓](https://gitee.com/weharmony/kernel_liteos_a_note) | [CSDN仓](https://codechina.csdn.net/kuangyufei/kernel_liteos_a_note) | [Github仓](https://github.com/kuangyufei/kernel_liteos_a_note) | [Coding仓 】](https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files)阅读,四大仓库每日同步更新...
鸿蒙是面向未来设计的系统,高瞻远瞩,格局远大,设计精良, 海量知识点, 目前做的只是冰山一角,把研究过程心得写成鸿蒙源码分析系列篇,如此源码中文注释+系列篇文章 将加速理解鸿蒙内核实现过程.
- ### **加注释方式是怎样的?**
......@@ -56,9 +51,9 @@
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201028154344813.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t1YW5neXVmZWk=,size_16,color_FFFFFF,t_70#pic_center)
- ### **仰望星空还是埋头走路**
- ### **干困难事,必有所得**
精读内核源码当然是件很困难的事,时间上要以月为单位,但正因为很难才值得去做! 内心不渴望的永远不可能靠近自己.笔者一直坚信兴趣是最好的老师,加注也是在做自己感兴趣的事.如果能让更多人参与到内核的研究,减少学习的成本,哪怕就节省一天的时间,这么多人能节省多少时间, 这是件多好玩,多有意义的事情啊. 时代需要仰望星空的人,但也需要埋头走路的人, 从鸿蒙一行行的代码中笔者能深深体会到各中艰辛和坚持,及鸿蒙生态对未来的价值,只因心中有目标,就不怕道阻且长.
精读内核源码当然是件很困难的事,时间上要以月为单位,正因为很难才值得去做! 内心不渴望的永远不可能靠近自己.笔者一直坚信兴趣是最好的老师,加注也是在做自己感兴趣的事.如果能让更多人参与到内核的研究,减少学习的成本,哪怕就节省一天的时间,这么多人能节省多少时间, 这是件多好玩,多有意义的事情. 从内核一行行的代码中能深深体会到开发者各中艰辛与坚持,及鸿蒙生态对未来的价值,笔者坚信鸿蒙大势所趋,未来可期,是其坚定的追随者和传播者.
- ### **新增的zzz目录是干什么的?**
......@@ -69,13 +64,11 @@
2. [新建 Issue](https://gitee.com/weharmony/kernel_liteos_a_note/issues)
- ### **联系方式**
kuangyufei@126.com
kuangyufei@126.com,有事请邮件/私信笔者, 抱歉因加注占用了全部空闲时间,所以无法微信回复.
---
系列篇文章 进入 >\> [鸿蒙系统源码分析(总目录) 【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) | [OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)查看
注释中文版 进入 >\> [鸿蒙内核源码注释中文版 【 Gitee仓](https://gitee.com/weharmony/kernel_liteos_a_note) | [CSDN仓](https://codechina.csdn.net/kuangyufei/kernel_liteos_a_note) | [Github仓](https://github.com/kuangyufei/kernel_liteos_a_note) | [Coding仓 】](https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files)阅读
# ![](https://oscimg.oschina.net/oscnet/up-c1f5f5e88b38fcb25f274a2062384b0c61e.png)
\ No newline at end of file
\ No newline at end of file
......@@ -109,7 +109,7 @@ typedef struct ProcessCB {
UINTPTR sigHandler; /**< signal handler */ //信号处理函数,处理如 SIGSYS 等信号
sigset_t sigShare; /**< signal share bit */ //信号共享位
#if (LOSCFG_KERNEL_LITEIPC == YES)
ProcIpcInfo ipcInfo; /**< memory pool for lite ipc */ //用于进程间通讯的 内存文件系统,设备装载点为 /dev/litepc
ProcIpcInfo ipcInfo; /**< memory pool for lite ipc */ //用于进程间通讯的虚拟设备文件系统,设备装载点为 /dev/lite_ipc
#endif
LosVmSpace *vmSpace; /**< VMM space for processes */ //进程空间
#ifdef LOSCFG_FS_VFS
......
......@@ -346,7 +346,7 @@ typedef struct {
a specific child process, or any child process */
#if (LOSCFG_KERNEL_LITEIPC == YES)
UINT32 ipcStatus; //IPC状态
LOS_DL_LIST msgListHead; //消息队列头结点
LOS_DL_LIST msgListHead; //消息队列头结点,上面挂的都是任务要读的消息
BOOL accessMap[LOSCFG_BASE_CORE_TSK_LIMIT];//访问图,指的是task之间是否能访问的标识,LOSCFG_BASE_CORE_TSK_LIMIT 为任务池总数
#endif
} LosTaskCB;
......
......@@ -53,27 +53,27 @@
#define LITE_IPC_POOL_NAME "liteipc" //ipc池名称
#define LITE_IPC_POOL_PAGE_MAX_NUM 64 /* 256KB */
#define LITE_IPC_POOL_PAGE_DEFAULT_NUM 16 /* 64KB */
#define LITE_IPC_POOL_MAX_SIZE (LITE_IPC_POOL_PAGE_MAX_NUM << PAGE_SHIFT)
#define LITE_IPC_POOL_DEFAULT_SIZE (LITE_IPC_POOL_PAGE_DEFAULT_NUM << PAGE_SHIFT)
#define LITE_IPC_POOL_MAX_SIZE (LITE_IPC_POOL_PAGE_MAX_NUM << PAGE_SHIFT) //最大IPC池 256K
#define LITE_IPC_POOL_DEFAULT_SIZE (LITE_IPC_POOL_PAGE_DEFAULT_NUM << PAGE_SHIFT)//默认IPC池 64K
#define LITE_IPC_POOL_UVADDR 0x10000000
#define INVAILD_ID (-1)
#define LITEIPC_TIMEOUT_MS 5000UL //超时时间单位毫秒
#define LITEIPC_TIMEOUT_NS 5000000000ULL //超时时间单位纳秒
typedef struct {
LOS_DL_LIST list;
typedef struct {//IPC使用节点
LOS_DL_LIST list;//通过它挂到对应g_ipcUsedNodelist[processID]上
VOID *ptr;
} IpcUsedNode;
LosMux g_serviceHandleMapMux;
#if (USE_TASKID_AS_HANDLE == YES)
HandleInfo g_cmsTask;
#if (USE_TASKID_AS_HANDLE == YES)// @note_why 前缀cms是何意思? 猜测是Content Management System(内容管理系统)
HandleInfo g_cmsTask; //任务句柄消息
#else
HandleInfo g_serviceHandleMap[MAX_SERVICE_NUM];
HandleInfo g_serviceHandleMap[MAX_SERVICE_NUM];//服务句柄数组,默认等于任务数 128
#endif
STATIC LOS_DL_LIST g_ipcPendlist;//阻塞链表,上面挂等待读/写消息的任务
STATIC LOS_DL_LIST g_ipcUsedNodelist[LOSCFG_BASE_CORE_PROCESS_LIMIT];//IPC节点池,默认等于进程数
STATIC LOS_DL_LIST g_ipcPendlist;//阻塞链表,上面挂等待读/写消息的任务LosTaskCB
STATIC LOS_DL_LIST g_ipcUsedNodelist[LOSCFG_BASE_CORE_PROCESS_LIMIT];//每个进程使用的IPC节点链表情况,上面挂IpcUsedNode节点
/* ipc lock */
SPIN_LOCK_INIT(g_ipcSpin);//初始化IPC自旋锁
......@@ -88,7 +88,7 @@ STATIC UINT32 LiteIpcWrite(IpcContent *content);
STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID);
STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback);
//实现VFS接口函数,对liteIpc进行操作
//实现VFS接口函数,以文件的方式操作IPC
STATIC const struct file_operations_vfs g_liteIpcFops = {
LiteIpcOpen, /* open */
LiteIpcClose, /* close */
......@@ -168,7 +168,7 @@ UINT32 IpcInfoCheck(IpcTraceFrame *ipcInfo)
return LOS_OK;
}
//打印IPC跟踪信息
LITE_OS_SEC_TEXT STATIC VOID IpcTracePrint(UINT32 cpuID, IpcTraceFrame *ipcInfo)
{
IdArg *idArg = (IdArg *)&ipcInfo->idInfo;
......@@ -216,7 +216,7 @@ VOID IpcBacktrace(VOID)
}
}
#endif
//liteIpc 初始化
//初始化liteIpc驱动
LITE_OS_SEC_TEXT_INIT UINT32 LiteIpcInit(VOID)
{
UINT32 ret, i;
......@@ -229,11 +229,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LiteIpcInit(VOID)
if (ret != LOS_OK) {
return ret;
}
ret = (UINT32)register_driver(LITEIPC_DRIVER, &g_liteIpcFops, DRIVER_MODE, NULL);
ret = (UINT32)register_driver(LITEIPC_DRIVER, &g_liteIpcFops, DRIVER_MODE, NULL);//注册字符设备驱动程序
if (ret != LOS_OK) {
PRINT_ERR("register lite_ipc driver failed:%d\n", ret);
}
LOS_ListInit(&(g_ipcPendlist));
LOS_ListInit(&(g_ipcPendlist));//初始化任务阻塞队列
for (i = 0; i < LOSCFG_BASE_CORE_PROCESS_LIMIT; i++) {
LOS_ListInit(&(g_ipcUsedNodelist[i]));
}
......@@ -245,12 +245,12 @@ LITE_OS_SEC_TEXT_INIT UINT32 LiteIpcInit(VOID)
#endif
return ret;
}
//实现 vfs open接口
LITE_OS_SEC_TEXT STATIC int LiteIpcOpen(FAR struct file *filep)
{
return 0;
}
//实现 vfs close接口
LITE_OS_SEC_TEXT STATIC int LiteIpcClose(FAR struct file *filep)
{
return 0;
......@@ -262,7 +262,7 @@ LITE_OS_SEC_TEXT STATIC BOOL IsPoolMapped(VOID)
return (pcb->ipcInfo.pool.uvaddr != NULL) && (pcb->ipcInfo.pool.kvaddr != NULL) &&
(pcb->ipcInfo.pool.poolSize != 0);
}
//实现IPC地址映射
LITE_OS_SEC_TEXT STATIC INT32 DoIpcMmap(LosProcessCB *pcb, LosVmMapRegion *region)
{
UINT32 i;
......@@ -309,13 +309,13 @@ LITE_OS_SEC_TEXT STATIC INT32 DoIpcMmap(LosProcessCB *pcb, LosVmMapRegion *regio
(VOID)LOS_MuxRelease(&pcb->vmSpace->regionMux);
return ret;
}
//映射IPC线性区,IPC是单独
LITE_OS_SEC_TEXT STATIC int LiteIpcMmap(FAR struct file* filep, LosVmMapRegion *region)
{
int ret = 0;
LosVmMapRegion *regionTemp = NULL;
LosProcessCB *pcb = OsCurrProcessGet();
if ((region == NULL) || (region->range.size > LITE_IPC_POOL_MAX_SIZE) ||
if ((region == NULL) || (region->range.size > LITE_IPC_POOL_MAX_SIZE) ||//线性区判断
(!LOS_IsRegionPermUserReadOnly(region)) || (!LOS_IsRegionFlagPrivateOnly(region))) {
ret = -EINVAL;
goto ERROR_REGION_OUT;
......@@ -359,7 +359,7 @@ ERROR_REGION_OUT:
pcb->ipcInfo.pool.kvaddr = NULL;
return ret;
}
//ipc池初始化
LITE_OS_SEC_TEXT_INIT UINT32 LiteIpcPoolInit(ProcIpcInfo *ipcInfo)
{
ipcInfo->pool.uvaddr = NULL;
......@@ -368,7 +368,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LiteIpcPoolInit(ProcIpcInfo *ipcInfo)
ipcInfo->ipcTaskID = INVAILD_ID;
return LOS_OK;
}
//重置ipc池
LITE_OS_SEC_TEXT UINT32 LiteIpcPoolReInit(ProcIpcInfo *child, const ProcIpcInfo *parent)
{
child->pool.uvaddr = parent->pool.uvaddr;
......@@ -402,9 +402,9 @@ LITE_OS_SEC_TEXT VOID LiteIpcPoolDelete(ProcIpcInfo *ipcInfo)
}
}
}
/* Only when kernenl no longer access ipc node content, can user free the ipc node */
LITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(UINT32 processID, VOID *buf)
//只有当内核不再访问ipc节点内容时,用户才能释放ipc节点
/* Only when kernel no longer access ipc node content, can user free the ipc node */
LITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(UINT32 processID, VOID *buf)//用户释放一个在使用的IPC节点
{
UINT32 intSave;
IpcUsedNode *node = (IpcUsedNode *)malloc(sizeof(IpcUsedNode));
......@@ -415,7 +415,7 @@ LITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(UINT32 processID, VOID *buf
IPC_UNLOCK(intSave);
}
}
//分配一个IPC节点
LITE_OS_SEC_TEXT STATIC VOID* LiteIpcNodeAlloc(UINT32 processID, UINT32 size)
{
VOID *ptr = LOS_MemAlloc(OS_PCB_FROM_PID(processID)->ipcInfo.pool.kvaddr, size);
......@@ -423,20 +423,20 @@ LITE_OS_SEC_TEXT STATIC VOID* LiteIpcNodeAlloc(UINT32 processID, UINT32 size)
processID, OS_PCB_FROM_PID(processID)->ipcInfo.pool.kvaddr, ptr, size);
return ptr;
}
//释放一个IPC节点
LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcNodeFree(UINT32 processID, VOID *buf)
{
PRINT_INFO("LiteIpcNodeFree pid:%d, pool:%x buf:%x\n",
processID, OS_PCB_FROM_PID(processID)->ipcInfo.pool.kvaddr, buf);
return LOS_MemFree(OS_PCB_FROM_PID(processID)->ipcInfo.pool.kvaddr, buf);
}
//是否是IPC节点
LITE_OS_SEC_TEXT STATIC BOOL IsIpcNode(UINT32 processID, const VOID *buf)
{
IpcUsedNode *node = NULL;
UINT32 intSave;
IPC_LOCK(intSave);
LOS_DL_LIST_FOR_EACH_ENTRY(node, &g_ipcUsedNodelist[processID], IpcUsedNode, list) {
LOS_DL_LIST_FOR_EACH_ENTRY(node, &g_ipcUsedNodelist[processID], IpcUsedNode, list) {//遍历节点
if (node->ptr == buf) {
LOS_ListDelete(&node->list);
IPC_UNLOCK(intSave);
......@@ -447,14 +447,14 @@ LITE_OS_SEC_TEXT STATIC BOOL IsIpcNode(UINT32 processID, const VOID *buf)
IPC_UNLOCK(intSave);
return FALSE;
}
//获得IPC用户空间地址
LITE_OS_SEC_TEXT STATIC INTPTR GetIpcUserAddr(UINT32 processID, INTPTR kernelAddr)
{
IpcPool pool = OS_PCB_FROM_PID(processID)->ipcInfo.pool;
INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr);
return kernelAddr + offset;
}
//获得IPC内核空间地址
LITE_OS_SEC_TEXT STATIC INTPTR GetIpcKernelAddr(UINT32 processID, INTPTR userAddr)
{
IpcPool pool = OS_PCB_FROM_PID(processID)->ipcInfo.pool;
......@@ -569,17 +569,17 @@ LITE_OS_SEC_TEXT STATIC BOOL HasServiceAccess(UINT32 serviceHandle)
}
return OS_TCB_FROM_TID(serviceTid)->accessMap[curProcessID];
}
//设置ipc任务ID
LITE_OS_SEC_TEXT STATIC UINT32 SetIpcTask(VOID)
{
if (OsCurrProcessGet()->ipcInfo.ipcTaskID == INVAILD_ID) {
OsCurrProcessGet()->ipcInfo.ipcTaskID = LOS_CurTaskIDGet();
OsCurrProcessGet()->ipcInfo.ipcTaskID = LOS_CurTaskIDGet();//将当前任务ID设为IPC任务ID
return OsCurrProcessGet()->ipcInfo.ipcTaskID;
}
PRINT_ERR("curprocess %d IpcTask already set!\n", OsCurrProcessGet()->processID);
return -EINVAL;
}
//是否设置ipc任务ID
LITE_OS_SEC_TEXT BOOL IsIpcTaskSet(VOID)
{
if (OsCurrProcessGet()->ipcInfo.ipcTaskID == INVAILD_ID) {
......@@ -587,7 +587,7 @@ LITE_OS_SEC_TEXT BOOL IsIpcTaskSet(VOID)
}
return TRUE;
}
//获取
LITE_OS_SEC_TEXT STATIC UINT32 GetIpcTaskID(UINT32 processID, UINT32 *ipcTaskID)
{
if (OS_PCB_FROM_PID(processID)->ipcInfo.ipcTaskID == INVAILD_ID) {
......@@ -596,7 +596,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 GetIpcTaskID(UINT32 processID, UINT32 *ipcTaskID)
*ipcTaskID = OS_PCB_FROM_PID(processID)->ipcInfo.ipcTaskID;
return LOS_OK;
}
//发送死亡消息
LITE_OS_SEC_TEXT STATIC UINT32 SendDeathMsg(UINT32 processID, UINT32 serviceHandle)
{
UINT32 ipcTaskID;
......@@ -700,7 +700,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 SetCms(UINTPTR maxMsgSize)
(VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
return -EEXIST;
}
//是否注册了CMS服务
LITE_OS_SEC_TEXT STATIC BOOL IsCmsSet(VOID)
{
#if (USE_TASKID_AS_HANDLE == YES)
......@@ -1014,7 +1014,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 CheckPara(IpcContent *content, UINT32 *dstTid)
}
return LOS_OK;
}
//写IPC消息队列
LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content)
{
UINT32 ret, intSave;
......@@ -1043,10 +1043,10 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content)
PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
goto ERROR_COPY;
}
/* add data to list and wake up dest task */
/* add data to list and wake up dest task *///向列表添加数据并唤醒目标任务
SCHEDULER_LOCK(intSave);
LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid);
LOS_ListTailInsert(&(tcb->msgListHead), &(buf->listNode));
LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid);//找到目标任务ID,需要哪些任务去读
LOS_ListTailInsert(&(tcb->msgListHead), &(buf->listNode));//从尾部挂入任务的消息链表
#if (LOSCFG_KERNEL_TRACE == YES)
IpcTrace(&buf->msg, WRITE, tcb->ipcStatus, buf->msg.type);
#endif
......@@ -1281,7 +1281,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleCmsCmd(CmsCmdContent *content)
}
return ret;
}
//设置IPC控制参数
LITE_OS_SEC_TEXT int LiteIpcIoctl(FAR struct file *filep, int cmd, unsigned long arg)
{
UINT32 ret = LOS_OK;
......
......@@ -43,34 +43,39 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define LITEIPC_DRIVER "/dev/lite_ipc"
#define DRIVER_MODE 0666
#define MAX_SERVICE_NUM LOSCFG_BASE_CORE_TSK_LIMIT
/****************************************************
什么是句柄?
从形象意义的理解,跟门的把柄一样,握住门柄就控制了整个大门.
句柄是给用户程序使用的一个数字凭证,能以小博大,通过柄
能牵动内核模块工作.
****************************************************/
#define LITEIPC_DRIVER "/dev/lite_ipc" //设备位置
#define DRIVER_MODE 0666 //权限, chmod 666
#define MAX_SERVICE_NUM LOSCFG_BASE_CORE_TSK_LIMIT //最大服务数等于任务数 默认128
#define USE_TIMESTAMP YES
typedef enum {
HANDLE_NOT_USED,
HANDLE_REGISTING,
HANDLE_REGISTED
typedef enum { //句柄状态
HANDLE_NOT_USED, //未使用
HANDLE_REGISTING, //注册中
HANDLE_REGISTED //已注册
} HandleStatus;
typedef struct {//句柄信息
HandleStatus status; //状态
UINT32 taskID; //任务ID,以任务句柄
UINT32 taskID; //任务ID,以任务标识句柄
UINTPTR maxMsgSize;//最大消息大小
} HandleInfo;
typedef struct {
VOID *uvaddr;
VOID *kvaddr;
UINT32 poolSize;
typedef struct {// ipc池
VOID *uvaddr; //用户空间虚拟地址
VOID *kvaddr; //内核空间虚拟地址
UINT32 poolSize;//ipc池大小
} IpcPool;
typedef struct {
IpcPool pool;
UINT32 ipcTaskID;
UINT32 access[LOSCFG_BASE_CORE_TSK_LIMIT];
//见于进程结构体: LosProcessCB.ipcInfo
typedef struct {//进程IPC信息
IpcPool pool; //ipc池
UINT32 ipcTaskID; //
UINT32 access[LOSCFG_BASE_CORE_TSK_LIMIT]; //访问的任务数组
} ProcIpcInfo;
typedef enum {
......@@ -101,15 +106,15 @@ typedef struct {
ObjContent content;
} SpecialObj;
typedef enum {
MT_REQUEST,
MT_REPLY,
MT_FAILED_REPLY,
MT_DEATH_NOTIFY,
typedef enum { //消息的类型
MT_REQUEST, //请求
MT_REPLY, //回复
MT_FAILED_REPLY,//回复失败
MT_DEATH_NOTIFY,//通知死亡
MT_NUM
} MsgType;
/* lite ipc ioctl */
/* lite ipc ioctl */// 控制命令
#define IPC_IOC_MAGIC 'i'
#define IPC_SET_CMS _IO(IPC_IOC_MAGIC, 1)
#define IPC_CMS_CMD _IOWR(IPC_IOC_MAGIC, 2, CmsCmdContent)
......@@ -134,38 +139,38 @@ typedef enum {
} IpcFlag;
typedef struct {
MsgType type; /**< cmd type, decide the data structure below*/
SvcIdentity target; /**< serviceHandle or targetTaskId, depending on type */
UINT32 code; /**< service function code */
UINT32 flag;
MsgType type; /**< cmd type, decide the data structure below*/ //命令类型,决定下面的数据结构
SvcIdentity target; /**< serviceHandle or targetTaskId, depending on type */ //因命令类型不同而异
UINT32 code; /**< service function code */ //服务功能代码
UINT32 flag; //标签
#if (USE_TIMESTAMP == YES)
UINT64 timestamp;
UINT64 timestamp; //时间戳
#endif
UINT32 dataSz; /**< size of data */
VOID *data;
UINT32 spObjNum;
VOID *offsets;
UINT32 processID; /**< filled by kernel, processId of sender/reciever */
UINT32 taskID; /**< filled by kernel, taskId of sender/reciever */
#ifdef LOSCFG_SECURITY_CAPABILITY
UINT32 userID;
UINT32 gid;
UINT32 dataSz; /**< size of data */ //消息内容大小
VOID *data; //消息的内容,真正要传递的消息
UINT32 spObjNum; // ..
VOID *offsets; // ..
UINT32 processID; /**< filled by kernel, processId of sender/reciever */ //由内核填充,发送/接收消息的进程ID
UINT32 taskID; /**< filled by kernel, taskId of sender/reciever */ //由内核填充,发送/接收消息的任务ID
#ifdef LOSCFG_SECURITY_CAPABILITY
UINT32 userID; //用户ID
UINT32 gid; //组ID
#endif
} IpcMsg;
typedef struct {
IpcMsg msg;
LOS_DL_LIST listNode;
typedef struct { //IPC 内容节点
IpcMsg msg; //内容体
LOS_DL_LIST listNode;//通过它挂到LosTaskCB.msgListHead链表上
} IpcListNode;
#define SEND (1 << 0)
#define RECV (1 << 1)
#define SEND (1 << 0) //发送
#define RECV (1 << 1) //接收
#define BUFF_FREE (1 << 2)
typedef struct {
UINT32 flag; /**< size of writeData */
IpcMsg *outMsg; /**< data to send to target */
IpcMsg *inMsg; /**< data reply by target */
typedef struct { //IPC消息内容回路,记录消息周期
UINT32 flag; /**< size of writeData */ //IPC标签 (SEND,RECV,BUFF_FREE)
IpcMsg *outMsg; /**< data to send to target */ //发给给目标任务的消息内容
IpcMsg *inMsg; /**< data reply by target */ //目标任务回复的消息内容
VOID *buffToFree;
} IpcContent;
......@@ -187,21 +192,21 @@ typedef enum {
OPERATION_NUM
} IpcOpertion;
typedef struct {
UINT32 srcTid : 8;
UINT32 srcPid : 8;
UINT32 dstTid : 8;
UINT32 dstPid : 8;
typedef struct {//进程/任务ID 参数
UINT32 srcTid : 8; //源任务ID
UINT32 srcPid : 8; //源进程ID
UINT32 dstTid : 8; //目标任务ID
UINT32 dstPid : 8; //目标进程ID
} IdArg;
typedef struct {
UINT32 msgType : 8;
UINT32 code : 8;
UINT32 operation : 8;
UINT32 ipcStatus : 8;
typedef struct {//消息参数
UINT32 msgType : 8; //消息类型
UINT32 code : 8; //消息码
UINT32 operation : 8; //具体操作
UINT32 ipcStatus : 8; //IPC状态
} MsgArg;
typedef struct {
typedef struct {
UINT32 idInfo;
UINT32 msgInfo;
UINT64 timestamp;
......
#git fetch
git pull gitee_origin master
git pull origin master
#git pull --rebase origin master
git add -A
git commit -m '字符图说明posix消息队列内在运行逻辑
git commit -m '开始对 lite ipc模块注解
搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册