سؤال

My question is going to be rather vague but I will try to explain as detailed as I can what I am trying to resolve.

Trying to learn Linux kernel USB stack I have started to think of making a simple USB driver for my Atmel evaluation board based on ARM M0+ MCU to run away from Windows tools (Visual Studio plugin).

I have spent few days learning kernel's USB API and come to conclusion of how to make this. My driver aims to make my board connected to PC through USB cable act like a simple USB flash drive. Making that I then can easily program it with a new version of firmware written by me.

I have found that I need to find out specific interface (I am talking about interface in terms of USB specification, not interface we used to use as a code abstraction) that holds an endpoint (pipe) responsible for interaction with flash memory. And then I can map it to character device and interact with it using standard I/O operations that are described in struct file_operations structure.

Simply using cat on /proc/* file descriptor that was created by USB Core subsystem I have investigated that interface responsible for interaction with flash memory holds bulk endpoint (likewise, this terms come from USB specification, CMIIAW) that act as a "descriptor". Linux kernel USB Core subsystem gives neat interfaces to talk to different kind of endpoints whether it control, interrupt, bulk or asynchronous endpoint.

Now I have come closer to my very question.

Also the main transfer unit in communication between two USB devices is abstraction called urb - you allocate it, you fill it, you send it to USB Core subsystem, you read it if it was IN type of urb and, finally, you free it. What is confusing for me and tightly related to my question is the next 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)

Assume I have obtained an information from board's datasheet about where to write a program code. Let's say, we have 0x00100 - 0x10000 memory region. I will compile my code, obtain a binary and then using standard Linux tools or writing a simple user-space wrapper application I will use lseek to set file's offset to 0x00100 and write system call provided with a buffer (binary compiled previously) and it's length.

In kernel space, I will have to allocate urb in write system call handler, fill it with a buffer sent from user space and submit this urb to USB Core.

BUT I can not find a way how to specify an OFFSET set earlier by lseek. Do I miss something? Maybe I missed some concepts or, perhaps, I am watching in a wrong way?

هل كانت مفيدة؟

المحلول 2

There is no way to specify offset using USB subsystem's API. I misunderstood whole conception of USB as communication protocol, unwise me. You must first learn underlying protocol your device uses to communicate with others.

If your device acts as a USB HID device then learning specification of how to exchange data with USB HID device is the way to go. If there is something proprietary then you can do nothing but reverse engineer it (listening USB packets with a sniffer on system where a driver for your device exists).

As for my board it has embedded debugger that serves as a communication module besides being debugger itself. Specifically, my device is equipped with EDBG and here is a link on description of protocol it uses for communication.

نصائح أخرى

When your embedded Linux device acts as a USB mass storage device, the flash as a peripheral on Linux device is unmounted, and the gadget driver is loaded. Linux then loses control to the flash, and now the PC connected to your Linux device fully controls the flash. This is because a flash as a USB device can only has one USb host.

The gadget driver works purely in kernel space. It does not receive or transmit data from/to user space. It calls vfs_read() and vfs_write() to access the files on the flash, with an field offset. The offset is got from the USB commands sent from your host - Windows PC.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top