How to extend the BOS descriptor in FunctionFS? - linux

I'm trying to implement a simple WebUSB device on a Raspberry Pi 4. I've created a Linux USB Gadget for this purpose with a FunctionFS function. Currently I've taken the usb/ffs-test.c example from the Linux kernel as a basis.
According to this excellent Google blog by Reilly Grant on "Building a Device for WebUSB", I have to extend the Binary device Object Store (BOS) with the Microsoft OS compatibility descriptors to get this to work on Windows. I could also add the WebUSB descriptors to it but this is not a functional requirement.
However I'm stuck on this step, how do I extend the BOS with FunctionFS? This is my first experience with FunctionFS or USB for that matter, so I could be missing something obvious. I've found some usb_os_desc_header struct defined here in usb/functionfs.h, but I don't know if this is what I need or how I should use it.

Related

WebUSB API, for pushing commands/configuration to the device through webApp

I am doing some research on the WebUSB API for our company because we are going to start to manufacture devices in house.
Our current device manufacture comes with an application so the team can plug the device into a computer and diagnose it. Their application allows us to read outputs from the device, as well as pushing commands/configuration to the device over a wired connection.
Since this device is 100% ours, we are also responsible for building out the diagnostic tooling. We need some sort of interface that allows a user to read outputs and send commands/configuration to the device over a wired USB connection.
Is the webUSB the correct API? If not, what are some suggestions for accomplishing the requirement? Are we limited to building some sort of desktop or mobile application?
I would recommend resources below to read to help you understand if the WebUSB API fits your needs or not:
https://web.dev/devices-introduction/ helps you pick the appropriate API to communicate with a hardware device of your choice.
https://web.dev/build-for-webusb/ explains how to build a device to take full advantage of the WebUSB API.
From what you describe, WebUSB isn't strictly required but won't hurt either.
First and foremost, you will need to implement the USB interfaces reading data and sending configurations. It will be a custom protocol, and not one of the standard USB device classes such as HID, video or mass storage. The details of the protocol and if you use control, interrupt or bulk transfers is your choice.
I'm assuming you will connect the devices to Windows PCs, and you likely don't want to put money into writing device drivers. If so, the easiest approach is to add the required descriptors and control requests required for Microsoft OS 2.0 Descriptors. That way, the WinUSB driver will be installed automatically when the device is plugged in.
Using the WinUSB API, a Windows application will then be able to communicate with the USB device. No additional drivers are needed. (On macOS and Linux it's even easier as you don't need the Microsoft OS 2.0 Descriptors in the first place.)
On top of that you can implement the additional descriptors and control requests for WebUSB. It will provide the additional benefit that you can write a web application (instead of a native application) for communicating with the USB device. (Currently, you are restricted to the Chrome browser.) WebUSB devices should implement the WinUSB descriptors as the alternative (.INF files, manual installation process) is a pain.
The already mentioned web page https://web.dev/build-for-webusb/ is a complete example of how to implement it.

What OS commands are needed to control USB?

I am a college undergrad studying computer engineering and trying to send signals using USB to an FPGA from a windows computer connected to the FPGA using usb. What commands can i use to output/input data from my computer?
For background:
I am working on a windows 10 laptop. I am using python currently to run a program that gets the data from the user. The data is literally just a set of binary bits (up to about 75 bits), our project is to do with encoding, so our fpga is supposed to take the data then encode it using block codes, then send the data back, then the data is to be slightly corrupted, sent back to the FPGA, then error checked and decoded and sent to the computer again. The FPGA we have is a Cyclone 5 (Model Number: 5csema5f31c6).
I have recently started taking an OS class and since the OS controls how hardware is used by programs, i assume my programs will need to issue certain commands to the OS which will then tell the USB to do what we want.
The answer depends on what specific driver you are using to talk to your device. If your device is just a generic USB device and doesn't fit into an existing category (like a keyboard or printer), then I'd recommend using the driver named WinUSB.
You would need to write (and sign) an INF file or use a technology called Microsoft OS 2.0 Descriptors to tell Windows that you want your device to use WinUSB.
After you've done that, you can use a Microsoft-provided DLL called winusb.dll which helps you send the commands that the WinUSB driver expects. You'd also need to use SetupAPI to find your device in the first place. Using those two Microsoft APIs directly can be difficult and it makes your code non-portable, so you might consider using a USB abstraction library like libusb or libusbp instead.

Yocto Project usb sensor access

I've never worked with the Yocto Project, and barely knows what it is. But I'm investigating the possibility to use a Simatic 2040 as a gateway between an USB hall sensor and industrial PLC network.
The sensor that we want to use is this one. It's designed to use with an Windows desktop PC, connected via USB.
Now my main question is, would it be possible to write software in the Yocto device to capture the sensors data, and share this information with an industrial PLC network.
The industrial PLC network is also Siemens based, so I don't see much problems around that because we can make use of the Node-Red Profinet or Modbus library's.
The question is stated in very general terms, so I will have to answer in very general terms.
Overall the answer to your question is yes, but there are a number of details to sort out (some of them might be show stoppers).
Yocto is a system to generate embedded Linux images and also SDKs (cross compiler toolchain + sysroot).
You might be fine to take an existing Yocto Image for the SIMATIC 2040 and just add your own application to it. For this a matching SDK has to exist. This approach works fine as long as your application has not too many dependencies and you don't need to many modifications off the existing image.
If this is not the case you might be better off generating a custom image as well as an SDK (based on the existing SIMATIC 2040 configuration).
Considering your USB device. The linked data sheet states windows support. Your options?
Talk to the vendor? Does he provide a driver, but doesn't advertise it? Is he willing to hand out a detailed datasheet?
Check if there is a community driver in the mainline kernel?
Reverse engineering the existing Windows driver?
Pick an alternative device with an existing Linux driver (preferably in the mainline kernel).
The right solution depends on the time and effort you are willing and able to put into this.

USB-connected external graphics card

Is there any way in any Linux-based OS to access the instructions sent to have it transfer the instructions meant for the GPU to an external device connected via USB3.0 (and, obviously get the pixel output back)?
In Windows there is no native support for this kind of thing. Although many external graphics card exist which connect to a PCi slot, I didn't come across any USB ones.
Is there any way to accomplish this with native support of any of the Linux OSes?
EDIT: I was misunderstood, as far as I can see the comments. I want to program an external graphics card, I'm just looking for a way to get the GPU instructions to get to my device and get back the pixel array.

What data can a HID device receive?

I am designing a USB keyboard with special capabilities. What information can such a HID device receive from the host?
Can I via USB:
Read data from a form on the screen?
Find out what OS the user is on?
Find out if there's been an error message?
Even 'know' what's going on visually on the screen, i.e. what program is selected or whether the program is windowed or fullscreen?
Thank you!
The device can't get any of this information from a standard driver that the operating system supplies because that would be a security issue. It can receive any information that your own driver or application sends it. There are many ways to communicate with it - your device could present multiple interfaces (which will appear as separate devices), multiple endpoints, or use the control channel. You will definitely need to study the spec, and I also found this tutorial helpful.
I have done something similar and used the control channel to exchange feature data with a Windows application (over the standard Windows driver). On Windows, the API calls are HidD_SetFeature() and HidD_GetFeature().
On the device side, my hardware ran embedded Linux and I used the GadgetFS library to create a user-mode driver - much easier to debug than a kernel driver.
As others have said, you'll run into issues if you try this with a normal HID. However, there is a project called the USB Rubber Ducky. From their description:
The USB Rubber Ducky isn't your ordinary HID (Human Interface Device).
Coupled with a powerful 60 MHz 32-bit processor and a simple scripting language
The USB Rubber Ducky looks like a usb-device and is recognized as a HID, but is programmable. You can make a small script that will be typed onto the screen which will allow you to performs the queries you seek.
With the USB Rubber Ducky you can:
Read data from a form on the screen? Yes
Find out what OS the user is on? Yes
Find out if there's been an error message? Yes
Even 'know' what's going on visually on the screen, i.e. what program is selected or whether the program is windowed or fullscreen? Yes
If you aren't hoping to buy this device, at least their firmware is on github so it can provide you a starting point

Resources