linux – create / dev / fakeDevice支持read,write和ioctl
我有一个在嵌入式设备上运行的软件(x86,最近的
linux).为了简化开发,使用自动化测试等,我想在我的主机系统上运行它.代码编译很好,对构建系统进行了一些调整.下一步将是创建“虚拟设备”.
应用程序不使用任何类型的库,而是通过读取,写入和ioctl调用直接与多个设备通信.这些设备代表具有自定义协议的自定义硬件.要创建虚拟环境,我需要响应此调用.一种可能的方法是: >为每个需要的设备创建设备驱动程序(/ dev / deviceA,/ dev / deviceB,/ dev / deviceC,…) 如果没有通过Linux内核的往返,有没有更简单的方法呢? 解决方法
回到这个项目并回答我自己的问题:是的,必须完成内核的往返.但是有一个图书馆正在进行咕噜咕噜的工作:CUDA(谢谢,CL).
文档感觉有点稀缺(或者我正在查看错误的地方)并且提供的cuda示例中充满了其他一些处理参数或缓冲区处理的融合方式.所以这里有另一个例子(更简单,这里没有任何用处……): 设备“驱动程序”(cusetest.c): #define FUSE_USE_VERSION 30 #define _FILE_OFFSET_BITS 64 #include <fuse/cuse_lowlevel.h> #include <fuse/fuse_opt.h> #include <stdio.h> #define LOG(...) do { fprintf(stderr,__VA_ARGS__); puts(""); } while (0) static void cusetest_open(fuse_req_t req,struct fuse_file_info *fi) { LOG("open"); fuse_reply_open(req,fi); } static void cusetest_read(fuse_req_t req,size_t size,off_t off,struct fuse_file_info *fi) { LOG("read"); fuse_reply_buf(req,"Hello",size > 5 ? 5 : size); } static void cusetest_write(fuse_req_t req,const char *buf,struct fuse_file_info *fi) { LOG("write (%u bytes)",size); fuse_reply_write(req,size); } static void cusetest_ioctl(fuse_req_t req,int cmd,void *arg,struct fuse_file_info *fi,unsigned flags,const void *in_buf,size_t in_bufsz,size_t out_bufsz) { LOG("ioctl %d: insize: %u outsize: %u",cmd,in_bufsz,out_bufsz); switch (cmd) { case 23: if (in_bufsz == 0) { struct iovec iov = { arg,sizeof(int) }; fuse_reply_ioctl_retry(req,&iov,1,NULL,0); } else { LOG(" got value: %d",*((int*)in_buf)); fuse_reply_ioctl(req,0); } break; case 42: if (out_bufsz == 0) { struct iovec iov = { arg,1); } else { LOG(" write back value"); int v = 42; fuse_reply_ioctl(req,&v,sizeof(int)); } break; } } static const struct cuse_lowlevel_ops cusetest_clop = { .open = cusetest_open,.read = cusetest_read,.write = cusetest_write,.ioctl = cusetest_ioctl,}; int main(int argc,char** argv) { // -f: run in foreground,-d: debug ouput // Compile official example and use -h const char* cusearg[] = {"test","-f","-d"}; const char* devarg[] = {"DEVNAME=cusetest" }; struct cuse_info ci; memset(&ci,0x00,sizeof(ci)); ci.flags = CUSE_UNRESTRICTED_IOCTL; ci.dev_info_argc=1; ci.dev_info_argv = devarg; return cuse_lowlevel_main(3,(char**) &cusearg,&ci,&cusetest_clop,NULL); } 编译并运行:gcc -Wall -g -lfuse cusetest.c -o cusetest&& sudo ./cusetest 测试程序(testcusetest.c): #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <sys/ioctl.h> int main() { int fd = open("/dev/cusetest",O_RDWR); const char* msg = "Fooooo"; write(fd,msg,strlen(msg)); int v = 63; ioctl(fd,23,&v); fprintf(stderr,"value is now: %dn",v); ioctl(fd,42,v); close(fd); return 0; } 编译并运行:gcc -Wall testcusetest.c -o testcusetest&& ./testcusetest 它还有很多工作要做,但应该足以获得新手.陷阱是CUSE_UNRESTRICTED_IOCTL.如果in-或outputbuffer的长度为零,则需要使用fuse_reply_ioctl_retry()进行回复.将填充缓冲区再次调用回调. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |