【发布时间】:2014-04-14 21:26:10
【问题描述】:
我的问题会比较模糊,但我会尽可能详细地解释我要解决的问题。
尝试学习 Linux 内核 USB 堆栈我已经开始考虑为我的基于 ARM M0+ MCU 的 Atmel 评估板制作一个简单的 USB 驱动程序,以脱离 Windows 工具(Visual Studio 插件)。
我花了几天时间学习内核的 USB API 并得出了如何制作这个的结论。我的驱动程序旨在使我的板通过 USB 电缆连接到 PC,就像一个简单的 USB 闪存驱动器一样。然后,我可以轻松地使用我编写的新版本固件对其进行编程。
我发现我需要找出包含端点(管道) 负责与闪存交互。然后我可以将其映射到字符设备,并使用struct file_operations 结构中描述的标准 I/O 操作与它进行交互。
只需在由 USB 核心子系统创建的 /proc/* 文件描述符上使用 cat 我调查了负责与闪存交互的 接口 持有批量端点(同样,这些术语来自充当“描述符”的 USB 规范 (CMIIAW)。 Linux 内核 USB 核心子系统提供了简洁的接口来与不同类型的端点进行通信,无论是 control、interrupt、bulk 还是 asynchronous em> 端点。
现在我离我的问题更近了。
另外,两个 USB 设备之间通信的主要传输单元是称为 urb 的抽象 - 你分配它,你填充它,你把它发送到 USB 核心子系统,如果它是 IN 类型,你读取它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 和 write 系统调用提供一个缓冲区(二进制之前编译的)和它的长度。
在内核空间中,我将不得不在write系统调用处理程序中分配urb,用从用户空间发送的缓冲区填充它并将这个urb提交到USB核心。
但是我找不到如何指定lseek 之前设置的偏移量的方法。我错过了什么吗?也许我错过了一些概念,或者我看错了?
【问题讨论】:
-
设备必须运行一些代码(bootloader)来处理传入的请求块。 Atmel 微控制器通常具有SAM-BA。他们已经有免费的 Linux 工具来做你描述的事情,所以我不确定是否有任何关于用于与 SAM-BA 通信的协议的文档;我认为这就是您需要找到(或通过 USB 嗅探观察)来完成您的驱动程序的内容。
-
@NominalAnimal 是的,你是对的。写下这个作为答案,我会撞到它并发表评论,解释我在您对 SAM-BA 的建议后发现的内容。
-
回答并接受你自己的问题是完全可以的,在这种情况下,我认为这也是很有道理的。你应该描述你最初错过了什么,以及你的发现是什么。 (我关心事实和帮助,而不是声誉或社会问题。)请记住,未来的读者可能会通过网络搜索找到您的问题,尝试解决类似的问题,以及您是否可以为他们提供足够的信息来帮助他们解决他们的问题,这肯定值得您付出一些努力吗?
-
@NominalAnimal 当然。今晚晚些时候我会做出答复。
-
在内核中没有理由这样做。如果它真的是一个 USB 大容量存储设备,那么内核的驱动程序应该处理它。否则,在用户空间使用 libusb 或直接使用用户空间 USB API 与它交谈。如果它是一个损坏的大容量存储设备(例如第一代 ST 发现板),在告诉内核大容量存储驱动程序忽略它之后,您可能仍想在用户空间与它交谈。跨度>
标签: c linux linux-kernel usb linux-device-driver