SylixOS IO层源代码解析

    SylixOS  IO

open 函数

第313行是默认的权限,第318行的va_start() 是与va_arg (),va_end()配合一起使用的,是gcc提供函数,va_start()是初始化,va_arg()是取下一个参数,当标志位iFlag为创建时,通过va_arg()读取iFlag后面参数,赋值给权限位。然后调用_IoOpen()函数。

第130行是获取当前的IO环境,也就是读取当前线程是在文件系统的按个路径。第118行是声明的一个IO环境的结构体变量,结构体很简单,是路径名和文件的权限。

下面是获得当前默认IO环境,

第368 声明了一个线程控制块变量。如果在中断中使用则使用默认的IO路径,如果不是中断,首先获取当前的线程控制块。

再在宏定义LW_TCB_GET_CUR_SAFE

通过调用关系,最后会调用LW_CPU_GET_CUR() 函数获取当前cpu信息,查看LW_CPU_GET_CUR()函数

会调用LW_CPU_GET_CUR_ID()函数获取当前cpu ID号,不考虑多核smp,只关注单核,系统中配置单核此函数会默认返回0,_K_cpuTable 为cpu结构体数组,结构体包含了cpu的信息,包含系统控制块。

在返回_IosEnvGetDef 函数,只考虑提供模块加载服务,可进入第381行vprocIoEnvGet函数,

判断线程控制块和线程上下文指针是否存在,这个TCB_pvVProcessContext 指针指向进程控制块地址,系统在创建线程时会将该指针指向进程控制块。

在1530行转换成进程控制块后,进程结构体中包含当前的IO环境。IO路径会再程序进程启动时系统给填写进去。将IO环境的结构体返回。

回到_IoOpen函数第152行,经过前面获取IO环境并且检测要打开的name

,这里调用ioFullFileNameGet  从参数可以看出要通过pcName 获得设备名和完整的文件名。这里的完整文件名后面会有讲解,假设pcName为/dev/can1,

ioFullFileNameGet 调用的函数是API_IoFullFileNameGet

在第1013行,_PathGetDef 还是获取当前的路径名。_PathCat

第213行的查找设备,将/dev/can1 传入,并且将会获得设备名的尾指针位置

API_IosDevFind 在system->ioLib->ioSys.c

在611行调用了API_IosDevMatch函数,根据假设API_IosDevMatch(“/dev/can1”)

API_IosDevMatch函数在659行调用了__rootFsDevMatch(“/dev/can1),

为什么会调用rootFs,这是因为在unix系统中一切都是以“/”开始的。

在__rootFsDevMatch 在235 行如果传入pcname为“/”则直接返回根设备,否则调用__rootFsFindNode

在pcName假设等于“/dev/can1”, 第91行处理后pcTempName 等于“dev/can1”将根号除去

在第122行获取当前根节点的孩子节点,经过128-133行,pcNext指向了下一个目录,pcNode指向当前目录。即pcNode值为“dev”pcNext指向了“can1”,因为查找到“dev”是目录,所以进入到173行,和目录的值比较,比较完成后再次进入循环,此时pcNode指向“can1”,pcNext为空。因为dev目录下是设备,所以进入第140行,第144行获得设备名中最后“/”的指针位置,即“/can1”,在149行变成“can1”在152行和pcNode比对值相同(备注:dev name 是存放着整个绝对路径的名字比如“/dev/can1”),跳转到第188行

如果ppcTail不为空指向了/can1,最后返回“dev”对应的node节点。

如果为空则直接指向末尾,由于__rootFsDevMatch 传入空,所以直接指向末尾

最后返回找到的PLW_ROOTFS_NODE

返回到__rootFsDevMatch 函数

在247行找到设备对应的node后,由于是设备,进入到第250行,获得到node里的设备,然后返回PLW_DEV_HDR类型。

可以看到rootfs的node结点中包含指向设备的指针。获得设备后__rootFsDevMatch 返回找到的设备地址。回到API_IosDevMatch函数也返回指向设置的指针。此时返回到API_IosDevFind函数

第613行确认找到设备后将pcTail指向设备名尾部,根据假设pcName是值

“/dev/can1”,设备名pdevhdrMatch->DEVHDR_pcName为 “/dev/can1”

pcTail指向了设备名的尾指针。最后返回得到指向设备的指针。

此时返回到了_PathCat函数

由于此时pcTail执行了设置尾部,即pcTail是指向/dev/can1的尾指针 而pcFilename指向/dev/can1,所以不相等,将pcFilename值复制给pcResult。

返回API_IoFullFileNameGet函数,在1029行再次调用iosDevFind函数

因为在_PathCath函数中可能没有查找到,但是因为尾指针不等于头部了没有返回错误。

我们查找到设备pcTail指向的是“/dev/can1”尾部的尾指针。回到_IoOpen 函数

IosFdNew函数,cFullFileName 现在值为“/dev/can1”

iosFdNew 实际上是API_IosFdNew 函数

在900行调用_IosFileNew 函数,创建一个新的PLW_FD_ENTRY

进入IosFileNew函数

pcName和dev name的长度加上FD_ENTRY 结构体长度申请空间,然后将名字合并,pcName值为/dev/can1 ,pdevhdrHdr->DEVHDR_pcName 为/dev/can1合并后目录pfdentry的名字为/dev/can1 。

回到API_IosFdNew函数,第906行_IosFileDup

当pid不为0的时候会调用_S_pfuncFileDup 绑定的函数

在loader_shell.c中API_LoaderInit 在函数 中_S_pfuncFileDup绑定了

vprocIoFileDup

函数首先获取进程控制块,每个进程都有一个自己的文件描述符数组

在数组中找到空闲位置将dentry放入,将位置返回。回到_IoOpen函数的第158行此时iFd值就是数组的下标。第169行调用iosOpen函数,iosOpen是API_IosOpen函数

__LW_DEV_MAINDRV 宏定义是设备的驱动号

从驱动表中根据驱动号找到驱动对应的函数,调用驱动函数打开。

以can驱动安装为例

1091行进去iosDrvInstall 函数,iosDrvInstall实际上是API_IosDrvInstall函数

找到一个空闲位置,将驱动函数绑定,返回数组的下标为驱动号。最终调用的open函数是__canOpen函数

 

回到_IoOpen函数 退出165行的for循环后201行,会调用API_IosFdSet

第822行是同归iFd号获取到当前的PLW_FD_ENTRY,第828行将PLW_FD_ENTRY 类型pfdentry 和设备pdevhdrHdr 绑定。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值