山东省和住房城乡建设厅网站,企业邮箱要收费吗,河北工程信息网官网,有没有做淘宝的网站QNX操作系统是一个类Unix实时操作系统#xff0c;遵从POSIX规范#xff0c;驱动程序具有良好的可移植性。编写任何驱动程序都会遇到同样的一个问题#xff1a;应用程序与驱动程序之间是如何进行交互的。其实这个问题很简单#xff0c;QNX有大量资料说明这一点。当客户端调用…QNX操作系统是一个类Unix实时操作系统遵从POSIX规范驱动程序具有良好的可移植性。编写任何驱动程序都会遇到同样的一个问题应用程序与驱动程序之间是如何进行交互的。其实这个问题很简单QNX有大量资料说明这一点。当客户端调用fd open(“dev/mydevice”,O_RDWR)打开设备mydevice并期望从设定的地址上读写数据时这个问题就产生了。实际上QNX提供了一套灵活的消息交互机制大致上可以分为以下三个步骤第一加载驱动程序创建服务线程把底层IO函数与POSIX函数进行连接在命名空间注册设备名通过Event loop或Threadpool等待消息的接收同时使父进程在后台运行以加载其他应用程序。第二当应用程序调用open()函数时process manger受到请求在命名空间中找到名为dev/mydevice的resourcemangerQNX内核库打开它应用程序通过返回的句柄与之建立连接。第三随后当调用read (fd, buf, 512)函数时内核库发送了一个_IO_READ的消息此时之前建立的Event loop或Threadpool就可以接收到这个消息通过判断消息的类型调用到相应的IO函数比如int io_read (resmgr_context_t *ctp, io_read_t *msgRESMGR_OCB_T*ocb)其实可以看出来了fd, buf, 512这几个参数主要就是通过io_read_t *msg这个参数传过来的。其实client主要指定了一个设备希望向这个设备的某个地址读取长度为512字节的数据然后放到buf当中。接下来发生的事情就比较简单了就是在自己实现的io_read函数中解析这个消息传递来的参数并给出回复。在client-server消息交互模型中此时client就处在了replyblocked的状态等待server的回复。在io_read中做了哪些事情呢首先要验证下传来的消息是否是正确的io_read消息同时检查到底是否是nonblock方式打开。然后解析msg-i.nbytes来确定需要传递多少个数据然后调用底层函数读取硬件数据通过_IO_SET_READ_NBYTES(ctp, msg-i.nbytes);来告诉client可以返回的数据量。对于如何回复数据来说QNX确实提供了不少简单的方法。可以使用return(ENOMEM)返回一个错误或者使用return(EOK)返回操作成功。如果想返回一定量数据的话可以设置IOV数组返回比如通过设置IOV来返回一个或多个数组比如SETIOV (ctp-iov, buffer, nbytes);return (_RESMGR_NPARTS(1));或者直接调用宏返回一个完整的bufferreturn (_RESMGR_PTR(ctp, buffer, nbytes));写数据的操作与读数据的操作类似不再赘述。这样就完成了上层数据请求下层数据读取并返回的过程server重新回到receive blocked的状态。细心的朋友可能已经看出来了既然是读写数据那么地址是如何设置的呢其实是通过devctl来设置的其格式为int devctl( int fd, int dcmd, void *data, size_t nbytes, int * return_info);其中最值得一提的就是int dcmd这个参数这是一个自定义的命令可以通过这个命令传递一个结构体指针比如Typedef struct{Uint32_t addr_t;Uint32_t status_r;} my_cfg_t;#define MYCMD_SET_ADDR __DIOT(_DCMD_MISC, 0x01, my_cfg_t)在client应用程序中定义my_cfg_t addr;通过命令Devctl(fd, MYCMD_SET_ADDR, addr,sizeof(my_cfg_t),NULL)完成设置。对于底层来说就比较简单了主要分为获取数据指针解析传来的命令获得数据就可以了。