gpt4 book ai didi

c - Linux USB 设备驱动的误解

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:33:46 25 4
gpt4 key购买 nike

我的问题会相当含糊,但我会尽可能详细地解释我要解决的问题。

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

我花了几天时间学习内核的 USB API,并得出了如何制作它的结论。我的驱动程序旨在让我的电路板通过 USB 电缆连接到 PC,就像一个简单的 USB 闪存驱动器一样。然后我可以使用我编写的新版本固件轻松地对其进行编程。

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

简单地在由 USB 核心子系统创建的 /proc/* 文件描述符上使用 cat 我调查了负责与交互的接口(interface)闪存包含充当“描述符”的批量端点(同样,该术语来自 USB 规范 CMIIAW)。 Linux 内核 USB 核心子系统提供简洁的接口(interface)来与不同类型的端点通信,无论是控制中断批量还是异步 端点。

现在我离我的问题更近了。

此外,两个 USB 设备之间通信的主要传输单元是称为 urb 的抽象 - 你分配它,填充它,将它发送到 USB Core 子系统,如果它是 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 将文件的偏移量设置为 0x00100write 系统调用提供了一个缓冲区(之前编译过的二进制文件)和它的长度。

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

但是我找不到一种方法来指定先前由 lseek 设置的 OFFSET。我想念什么吗?也许我错过了一些概念,或者我看错了方向?

最佳答案

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

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

关于c - Linux USB 设备驱动的误解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23070748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com