Reading from usb as a comport - c

I'm quite a beginner in the embedded world, since I'm always at the "other side of the wire" as a SW engineer so please don't crucify me for a question that might seem silly.
When I'm working with a Bluetooth device that connects to the computer, it is usually presented as a virtual COM-port which I connect and read the data from using winapi. Now our embedded engineer presented me a device that sends the same data through a USB cable which also presents as a virtual comport at my system which I read the same (meaning, for me it is completely transparent).
Now I wonder, in any other devices that use a USB connection, I don't see the device as a comport (like a mouse, or a keyboard), yet the info is sent. Why there is a need in a comport in this case, and what other reading options available?

You should read some basic USB information.
The difference you've noticed is because USB supports something called "device classes", that basically control how the computer (the host) views the device.
One such class is "USB communications device" which often becomes a virtual COM port, for instance.
Another is the very commonly seen "USB mass storage device" which is what e.g. flash drives use.
A third is the one you mention for mouses and keyboards, which is called "USB human interface device".
Which class a particular device uses is communicated when it's first connected on the bus, so that the host can load the proper driver. You cannot magically force a device to switch classes, the class is typically a "hard" (non-modifiable) part of the device's implementation, chosen by the designers of the device.

Related

Linux Device Tree: How to make the device file?

On my ARM system (Tegra based), I'm running the mainline linux kernel. It uses the device tree system.
I have enabled a hardware driver for the General-Memory-Bus (part of the SoC) in the .dts file by setting its status="okay". Recompiled the dtb and booted the kernel. But no device (/dev/xx) appears.
The driver is compiled into the kernel and can be seen by
cat /lib/modules/$(uname -r)/modules.builtin
The command
cat /sys/firmware/devicetree/base/<path to device>/status
returns "okay".
Do I need to make some kind of "mknod"?
What else is nessesary?
The traditional UNIX "stream of bytes" device model is a pretty high-level abstraction of most modern hardware, and as such there are plenty of drivers which do not create /dev entries for the devices they control largely because they don't fit that model. Bus drivers in particular are very much a case of that - they exist, but only for the sake of discovering and allowing access to the devices behind them; there is no /dev/sata that lets you interact with the actual host controller, sending out raw commands on any old port regardless of what's connected or not; there is no /dev/usb that lets you attempt arbitrary transfers to arbitrary endpoints which may or may not exist.
Furthermore, your typical 'external interface' controller as in this case is orders of magnitude less complex than an interface like SATA or USB - the 'device' itself is often little more than a register block controlling some clocks and a chip-select multiplexer. Even if the driver did create something you could interact with directly, there's not exactly much you could do with it.
The correct way to proceed in this situation is to describe your FPGA device in the DT as a child of the GMI bus, accurately reflecting the hardware, no less, then develop your own driver for that. The bus driver itself just sits transparently in the middle. And if you do want a quick and dirty way to get started by just reading and writing bus addresses directly, well, it's behind a memory-mapped I/O region; that's exactly what /dev/mem exists for.

How to use "control endpoint" (default endpoint) in client application?

I have USB HID device, which has only control endpoint. "USB Device Viewer" by Microsoft indicates 0 endpoints as it never counts control endpoints.
I don't know much about this device - it's basically black box to me. All I know is, that it's HID class and it's capable of simple serial communication (there's 1-Wire on "the other end of a cable").
As for HW, there's AVR MCU(not much help there). And as for FW, it uses VID, PID, which doesn't say anything to google (clearly made up).
I red here that after USB device is configured, one can use control endpoint for device specific use.
My question is:
Is it possible under Windows 7 using WDK to use control endpoint in user space application?
If not, is there any other way?
If yes, how?
HidD_GetHidGuid(&guid); doesn't even list my device. Probably due to the fact that device claims to be class 0x00 not only in device descriptor:
*bDeviceClass: 0x00 -> This is an Interface Class Defined Device*
but in interface descriptor too:
bInterfaceClass: 0x00
*!*CAUTION: 0 is a Reserved USB Device Interface Class
Did you run Wireshark? (Though I believe Wireshark doesn't monitor USB on windows - not sure about that. There are other USB packet sniffers around)
With wireshark you can monitor all communications to the device.
Though I don't know the WDK, I have the impression that many, if not most people use libusb (http://libusb.info/). There is a Windows version which can run on both 32 and 64-bit versions. This library is fairly easy to use, and has access to all endpoints.

Linux USB device driver misconception

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?
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.
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.

How a wireless NIC works on the hardware level and the capabilities?

I couldn't think of a better title name, but to the point.
I wanted to know how the wireless NIC/NIC operates with the system it is connected to (not over a connection, but an internal one or a pci, or usb, or any other peripheral), and what can the card itself do with the system (besides connecting to some router or AP, or anything not dealing with the hardware internals), or what it can communicate to the local system?
I'm not sure if these are defined at the assembly level or in the user-space level, so I would also like to know that as well, if possible.
External wireless NICs attach over USB; internal ones typically use PCI or PCIe.
The details of how these devices communicate with the host are all device-specific. In many cases, the NIC runs a firmware which the host must upload to the device at startup. The details of what this firmware must contain are basically never documented. A few wireless NICs (typically the older ones) actually implement hardware commands to perform operations like associating with an AP, but most do not.
There are no standards here. Every device is a little bit different. There is also almost never any documentation. If you want to learn more, your best bet is to find the source code for a Linux driver for the device you're interested in, dig into it, and hope it's well-commented.

reading USB port in Linux

I am writing a program to read data from a Bluetooth USB dongle. I am using Linux, so I suspect there may be a POSIX library to read from it, or perhaps there is a predefined file descriptor for each USB drive. How do I read a stream of data from a USB port in C?
The most common way of interacting with random USB device is libusb. This provides low-level access to the device, so if you want something more complex (for example, if it's an actual USB drive with a filesystem on it), you might want to use some existing driver for the device rather than trying to interact with it directly.
OK, given the answer above: the PS3 controller is, almost certainly, a HID device. You pair with it like you do any other Bluetooth HID device. It will appear as a joystick (or mouse, or keyboard, as appropriate) automatically once paired, with no software required on your part. This site seems to have a guide, though obviously I haven't tested it: http://www.ydl.net/support/solutions/ydl_6.x/ps3_bluetooth_sixaxis.shtml

Resources