请教xtang先生,

用于开发应用程序的OPEN 、devctl和设备驱动程序中的io_open、io_devctl之间的参数是如何对应的,开发手册上没有写清楚。只写到io_open、io_devctl用到三个结构(上下文信息、属性结构、装载结构),但它们与OPEN 、DEVCTL函数的参数之间是如何关联的。请指教

这个有点长了。devctl()比较容易,先说devctl()吧。

用户程序调用devctl(fd, dcmd, data, nbytes, infop); infop 是用来取得返回信息的,fd用来指出同服务器的连接,其余的传入服务器。

服务器的io_devctl()服务程序的是 io_devctl(ctp, msg, ocb); ctp主要含有用户的信息,ocb是在open时赋于的,msg 是一个io_devctl_t结构。看/usr/include/sys/iomsg.h,io_devctl_t 实际上是一个 _io_devctl (输入) 和 _io_devctl_reply(输出)的联合体。

msg->i.type <— 类型,在这里是 _IO_DEVCTL
msg->i.combin_len <— 长度,在这里是 sizeof(msg->i)
msg->i.dcmd <— 用户devctl() 里的第二个参数
msg->i.nbytes <— 用户devctl() 里的第四个参数

接下来的(msg->i.nbytes)字节,是用户data指针里的数据。所以你可以用

char *user_data = (char *)msg + sizeof(msg.i);

来取得用户数据。或者,你可以用已定义好的宏。

char *user_data = (char *)_DEVCTL_DATA(msg);

你的服务器最后应该返回一个msg.o结构。可以参考mqueue的io_devctl()函数。

再说说open(). 用户的open() 可以有两种。

open(path, ioflag)
open(path, ioflag, mode) (如果ioflag有O_CREAT的话)

在管理器端,io_open(ctp, msg, handle, extra). ctp 一样包含了用户端信息,handle是你在resmgr_attach()时传进去的handle,通常指向 iofunc_attr_t,extra是为别类open操作准备的,通常open时,不会用到。

msg 是io_open_t,可以在/usr/include/sys/iomsg.h里找到。它实际上就是一个_io_connect结构。_io_connect结构相当复杂,原因是它被用在很多东西中。不过对于open()来说,ioflag在msg->connect.ioflag里,mode在msg->connect.mode 里。至于path,在msg->connect.path里,有一个msg->connect.path_len告诉你它的长度。

需要注意的是,path是相对于你的attach point的。如果你resmgr_attach()了"/dev/mydev" (一个文件),那你得到的path就是NULL。因为只有用户open("/dev/mydev", …) 才会调用到你,别的open(),你不会收到。如果你resmgr_attach()了"/dev/mydevdir/"(一个目录),而用户open("/dev/mydevdir/dev1", …),你会收到一个path为"dev1" (相对你的/dev/mydevdir/ )

最后,http://cvs.qnx.com/cgi-bin/cvsweb.cgi/services/mqueue/下是一个完整的服务器源码,可以参考。