Linux USB设备驱动程序的误解

时间:2014-04-14 21:26:11

标签: c linux linux-kernel usb linux-device-driver

我的问题会比较模糊,但我会尽量详细解释我想要解决的问题。

尝试学习Linux内核USB堆栈我已经开始考虑为基于ARM M0 + MCU的Atmel评估板制作一个简单的USB驱动程序,以便远离Windows工具(Visual Studio插件)。

我花了几天时间学习内核的USB API,然后得出如何做到这一点的结论。我的驱动程序旨在通过USB线将我的主板连接到PC,就像一个简单的USB闪存驱动器。然后,我可以使用我编写的新版固件轻松编程。

我发现我需要找到特定的接口(我说的是关于USB规范的接口,而不是我们以前用作代码抽象的接口),它包含一个端点(管道)负责与闪存的交互。然后我可以映射到字符设备并使用struct file_operations结构中描述的标准I / O操作与其进行交互。

在USB核心子系统创建的cat文件描述符上简单地使用/proc/*我已经调查了负责与闪存交互的接口保存批量端点< / em>(同样,这个术语来自USB规范,CMIIAW)充当&#34;描述符&#34;。 Linux内核USB核心子系统提供简洁的接口,可以与不同类型的端点通信,无论是控制中断批量还是异步端点。

现在我已接近我的问题了。

两个USB设备之间通信的主传输单元是抽象称为 urb - 你分配它,你填充它,你把它发送到USB核心子系统,如果它是IN类型你读它of urb ,最后,你释放它。令我感到困惑的是,与我的问题紧密相关的是下一个API include/linux/usb.h

static inline void usb_fill_bulk_urb(struct urb *urb,
                                     struct usb_device *dev,
                                     unsigned int pipe,
                                     void *transfer_buffer,
                                     int buffer_length,
                                     usb_complete_t complete_fn,
                                     void *context)

假设我已从主板的数据表中获取有关编写程序代码的位置的信息。我们说,我们有0x00100 - 0x10000内存区域。我将编译我的代码,获取二进制文件,然后使用标准Linux工具或编写一个简单的用户空间包装器应用程序,我将使用lseek将文件的偏移量设置为0x00100和{{1系统调用提供缓冲区(先前已编译的二进制文件)及其长度。

在内核空间中,我必须在write系统调用处理程序中分配 urb ,用从用户空间发送的缓冲区填充它并提交此 urb 到USB Core。

但我找不到如何通过write指定早期OFFSET的方法。我错过了什么吗?也许我错过了一些概念,或许,我正在以错误的方式观看?

2 个答案:

答案 0 :(得分:0)

当您的嵌入式Linux设备充当USB大容量存储设备时,将卸载作为Linux设备上的外围设备的闪存,并加载小工具驱动程序。 Linux然后失去对闪存的控制,现在连接到Linux设备的PC完全控制闪存。这是因为作为USB设备的闪存只能有一个USb主机。

小工具驱动程序纯粹在内核空间中工作。它不从/向用户空间接收或传输数据。它调用vfs_read()和vfs_write()来访问闪存上的文件,并使用字段偏移量。偏移量来自主机发送的USB命令 - Windows PC。

答案 1 :(得分:0)

无法使用USB子系统的API指定偏移量。我误解了USB作为通信协议的整体概念,不明智。您必须首先学习设备用来与他人通信的基础协议。

如果您的设备充当USB HID设备,那么学习如何与USB HID设备交换数据的规范是可行的方法。如果有专有的东西那么你只能对它进行逆向工程(在你的设备的驱动程序存在的系统上使用嗅探器监听USB数据包)。

至于我的主板,除了作为调试器本身之外,它还有嵌入式调试器作为通信模块。具体来说,我的设备配备了EDBG,here是用于通信的协议描述链接。