- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在为具有三种不同读/写操作(闪存、EEPROM 和 I2C)的 USB 设备编写驱动程序,每种操作都有不同的实现。我一直在摸不着头脑,因为我是整个 linux 内核开发世界的新手。我读过我应该不惜一切代价避免使用 ioctl,但我不知道如何实现它。由于 linux 中的所有内容都是一个文件,我可以为每个位置创建多个端点来写入吗?我什至会怎么做呢?我会定义多个 usb_class_driver
结构吗?
另一方面,我是否应该在单个端点中包含所有功能并使用 ioctl?将同一个驱动程序的工作分开还是将所有功能整合到一个地方更好?
我不能使用 libusb,因为它对等时传输的限制和对 dma 传输缺乏直接控制(两者都需要产品最终产品)。
更新:在尝试对每个端点使用多个通用文件操作并获得 -98 的响应代码(已注册)之后,我想我将不得不使用带有 ioctl 的单个端点。无效的代码如下:
在adriver.h中
static struct usb_class_driver adriver_eeprom_class = {
.name = "usb/adriver_eeprom%d",
.fops = &adriver_eeprom_fops,
.minor_base = USB_SKEL_MINOR_BASE,
};
static struct usb_class_driver adriver_flash_class = {
.name = "usb/adriver_flash%d",
.fops = &adriver_flash_fops,
.minor_base = USB_SKEL_MINOR_BASE,
};
static struct usb_class_driver adriver_i2c_class = {
.name = "usb/adriver_i2c%d",
.fops = &adriver_i2c_fops,
.minor_base = USB_SKEL_MINOR_BASE,
};
static struct usb_class_driver driver_fifo_class = {
.name = "usb/driver_fifo%d",
.fops = &driver_fifo_fops,
.minor_base = USB_SKEL_MINOR_BASE,
};
static struct usb_class_driver adriver_class = {
.name = "usb/adriver%d",
.fops = &adriver_fops,
.minor_base = USB_SKEL_MINOR_BASE,
};
在adriver.c
static int adriver_probe(struct usb_interface *interface, const struct usb_device_id *id) {
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_adriver *gdev;
int retval = -ENOMEM;
gdev = kmalloc(sizeof(struct usb_adriver), GFP_KERNEL);
if(gdev == NULL)
{
dev_err(&interface->dev, "Out of memory\n");
goto error;
}
memset(gdev, 0x00, sizeof(*gdev));
kref_init(&gdev->kref);
gdev->udev = usb_get_dev(udev);
usb_set_intfdata(interface,gdev);
retval = usb_register_dev(interface, &adriver_eeprom_class);
if (retval) {
/* something prevented us from registering this driver */
pr_err("Not able to get a minor for this device.");
usb_set_intfdata(interface, NULL);
goto error;
}
retval = usb_register_dev(interface, &adriver_flash_class);
if (retval) {
/* something prevented us from registering this driver */
pr_err("Not able to get a minor for this device.");
usb_set_intfdata(interface, NULL);
goto error;
}
retval = usb_register_dev(interface, &adriver_i2c_class);
if (retval) {
/* something prevented us from registering this driver */
pr_err("Not able to get a minor for this device.");
usb_set_intfdata(interface, NULL);
goto error;
}
retval = usb_register_dev(interface, &adriver_fifo_class);
if (retval) {
/* something prevented us from registering this driver */
pr_err("Not able to get a minor for this device.");
usb_set_intfdata(interface, NULL);
goto error;
}
retval = usb_register_dev(interface, &adriver_class);
if (retval) {
/* something prevented us from registering this driver */
pr_err("Not able to get a minor for this device.");
usb_set_intfdata(interface, NULL);
goto error;
}
dev_info(&interface->dev, "USB adriver device now attached\n");
return 0;
error:
if (gdev)
kref_put(&gdev->kref, adriver_delete);
return retval;
}
最佳答案
设备驱动程序可以按照您最初的建议创建 3 个设备。如果设备上只有一个 IRQ,这个模型就更合适了。
凭借一点运气和技巧(可能更多的是后者),驱动程序的读写例程只需要实现为一个用于读取的函数和一个用于传递额外参数的写入函数,或者读/写例程推断通过检查它的 struct file *
参数(如果命名为 f
,则 MINOR(f -> f_dentry -> d_inode -> i_rdev
) 给出设备的次要设备 ID。由于您使用 device_create()
在 probe()
函数中控制次要设备分配,因此您可以利用它来关联有用的类型信息。
通过这种方式,很容易避免 ioctl,对于简单的读写操作,确实应该避免。这使得通过 bash 脚本、命令行等方式使用该设备变得很容易。如果涉及 ioctl,则意味着需要一种编程语言才能使用它。ioctl()
的手册页说
The [ioctl] call is used as a catch-all for operations that don't cleanly fit the UNIX stream I/O model.
关于c - 具有多个读取操作、ioctl 或 fops 的 Linux USB 驱动程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22365997/
我正在努力做到这一点 在我的操作中从数据库获取对象列表(确定) 在 JSP 上打印(确定) 此列表作为 JSP 中的可编辑表出现。我想修改然后将其提交回同一操作以将其保存在我的数据库中(失败。当我使用
我有以下形式的 Linq to Entities 查询: var x = from a in SomeData where ... some conditions ... select
我有以下查询。 var query = Repository.Query() .Where(p => !p.IsDeleted && p.Article.ArticleSections.Cou
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
以下代码产生错误 The nested query is not supported. Operation1='Case' Operation2='Collect' 问题是我做错了什么?我该如何解决?
我已经为 HA redis 集群(2 个副本、1 个主节点、3 个哨兵)设置了本地 docker 环境。只有哨兵暴露端口(10021、10022、10023)。 我使用的是 stackexchange
我正在 Desk.com 中构建一个“集成 URL”,它使用 Shopify Liquid 模板过滤器语法。对于开始日期为 7 天前而结束日期为现在的查询,此 URL 需要包含“开始日期”和“结束日期
你一定想过。然而情况却不理想,python中只能使用类似于 i++/i--等操作。 python中的自增操作 下面代码几乎是所有程序员在python中进行自增(减)操作的常用
我需要在每个使用 github 操作的手动构建中显示分支。例如:https://gyazo.com/2131bf83b0df1e2157480e5be842d4fb 我应该显示分支而不是一个。 最佳答
我有一个关于 Perl qr 运算符的问题: #!/usr/bin/perl -w &mysplit("a:b:c", /:/); sub mysplit { my($str, $patt
我已经使用 ArgoUML 创建了一个 ERD(实体关系图),我希望在一个类中创建两个操作,它们都具有 void 返回类型。但是,我只能创建一个返回 void 类型的操作。 例如: 我能够将 book
Github 操作仍处于测试阶段并且很新,但我希望有人可以提供帮助。我认为可以在主分支和拉取请求上运行 github 操作,如下所示: on: pull_request push: b
我正在尝试创建一个 Twilio 工作流来调用电话并记录用户所说的内容。为此,我正在使用 Record,但我不确定要在 action 参数中放置什么。 尽管我知道 Twilio 会发送有关调用该 UR
我不确定这是否可行,但值得一试。我正在使用模板缓冲区来减少使用此算法的延迟渲染器中光体积的过度绘制(当相机位于体积之外时): 使用廉价的着色器,将深度测试设置为 LEQUAL 绘制背面,将它们标记在模
有没有聪明的方法来复制 和 重命名 文件通过 GitHub 操作? 我想将一些自述文件复制到 /docs文件夹(:= 同一个 repo,不是远程的!),它们将根据它们的 frontmatter 重命名
我有一个 .csv 文件,其中第一列包含用户名。它们采用 FirstName LastName 的形式。我想获取 FirstName 并将 LastName 的第一个字符添加到它上面,然后删除空格。然
Sitecore 根据 Sitecore 树中定义的项目名称生成 URL, http://samplewebsite/Pages/Sample Page 但我们的客户有兴趣降低所有 URL(页面/示例
我正在尝试进行一些计算,但是一旦我输入金额,它就会完成。我只是希望通过单击按钮而不是自动发生这种情况。 到目前为止我做了什么: Angular JS - programming-fr
我的公司创建了一种在环境之间移动文件的复杂方法,现在我们希望将某些构建的 JS 文件(已转换和缩小)从一个 github 存储库移动到另一个。使用 github 操作可以实现这一点吗? 最佳答案 最简
在我的代码中,我创建了一个 JSONArray 对象。并向 JSONArray 对象添加了两个 JSONObject。我使用的是 json-simple-1.1.jar。我的代码是 package j
我是一名优秀的程序员,十分优秀!