Linux/Kernel module: Can a driver be used by two user programs? - linux

I'm trying to develop a "virtual" video driver based on ViVi project example. It's virtual since it doesn't interact with any camera. It gets a video stream from a user program (C++) and also it acts as video driver for another user program (Flash) which displays the video stream.
So, if I have a /dev/video0. One program needs write frame to it and another reads one from. Is that possible?
I need this because Flash doesn't recognize this camera, so I use a virtual driver as a bridge from my grabber (which uses the real driver) and Flash.

Yes.
More generally, a device driver can allow as many simultaneous opens as it wants. Take a look at Linux Device Drivers for more info. You can use filp->private_data to store data relevant to the specific open instance.
For even more flexibility, a device driver isn't even limited to having a single device node in /dev.

There used the vloopback driver, which did exactly what you want to do. However, it wasn't part of the standard kernel. Some time ago, I wrote a library (dv4linux that intercepted libc read/writes to /dev/video to achieve something similar. The current version has serious issues with newer firefox's malloc handling, though. berlios.de may fo out of service soon.

Can a driver be used by two program :
It usually can, but it is driver dependant. When it comes to data capture, you often have one process which gets all the data, and other processes have only limited access to the driver functionnality. So in the end, the API is ok with multiple process opening a driver, but in the end it all depends on the driver.
Can the VIVI driver be used as a bridge driver :
No. It is a video capture emulation driver, but there is no "video output" or "video sink" capability in this driver. You will have to understant why flash doesn't work with your real driver, but does work with a virtual driver. strace is your friend.

Related

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.

Is a linux framebuffer driver a video card driver?

I have little background on how these hardware actually works, but now I'm required to learn how to write a Linux frame buffer driver for Android devices.
I'm confused by Linux graphics stack. From what I understand, on a desktop computer the compositing window manager interacts with DRM, which then sends data to specific video card driver. On the other hand there are some kind of controllers retrieving data from GPU's memory through DMA and send it to the monitor, as suggested by the answer here .
Also by diagram at page 29 of this book, I figured that a frame buffer driver is on top of actual graphic devices, so it must need to interact with specific video card driver, for example, an nVidia driver.
But when I google writing a frame buffer driver for an embedded device, the results show that as if the driver is directly responsible for contacting with the LCD, so it looks like it's even below a video card driver.
So is a frame buffer driver actually a video card driver?
A framebuffer driver provides an interface for
Modesetting
Memory access to the video buffer
Basic 2D acceleration operations (e.g. for scrolling)
To provide this interface, the framebuffer driver generally talks to the hardware directly.
For example, the vesafb framebuffer driver will use the VESA standard interface to talk to the video hardware. However, this standard is limited, so there isn't really much hardware acceleration going on and drawing is slow.
Another example is the intelfb framebuffer driver. It talks to some intel hardware using a proprietary interface, that exposes more acceleration facilities, so it is faster.
Nowadays, KMS drivers are used instead for most hardware. They do both expose a framebuffer and also access to other GPU functionality, e.g. OpenGL, through DRM.
Your confusion seems to arise from the fact, that the framebuffer driver and the X11 GPU driver are in fact competing! This is why, if you have a KMS system, the switch between graphical and text consoles is instant, however, with a non-KMS system, it is slow, as both the fb driver and the X11 driver need to re-initialize the video hardware on console switch.
Find more information in the comprehensive talk Linux Graphics Demystified by Martin Fiedler:
http://keyj.emphy.de/files/linuxgraphics_en.pdf

Why using the libusb requires detaching the kernel driver?

Why using the libusb requires detaching the kernel driver? Why isn't it possible to perform some USB IOs along with the kernel driver?
Mainly to avoid confusion about the state of the USB-device. Each interface can only have one "user" at any given time.
Many USB-devices can enter different execution domains, cache-states, DMA transfers etc. These kinds of devices will then have state-machine-trackers in the driver, and it would easily fall out of sync or other types of conflicts. Not all devices are simple HID interfaces (which can be manipulated via other API's btw)
In order to communicate, each USB device have endpoints. These endpoint are like pipes, in these pipes all the data are travalling.
One endpoint have only one direction and can be use just by 1 driver.
So you need to detach the kernel driver in order to make available these endpoints.
If you want you can always detect and desactivate the driver which use the device in order to avoid the use of detach kernel driver.

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

What can be removed from the Linux i2c-dev driver to serve as a base for a new driver meant for only one device?

I'm trying to write a Linux character device driver for a device that just happens to communicate over I2C. The device is an Atmel microcontroller with code that provides an I2C address. It already works using the typical i2c-dev method on the Linux-side.
So now I want to replicate i2c-dev as a new driver that works specifically with this particular device, so that I can add some of my own device-specific abstraction code on top. But I'd like to trim out all the unnecessary code from i2c-dev that currently makes it generic. What can be removed in this situation?
What can be removed in this situation?
You're actually asking an XY question.
You would be better off looking at and adapting an existing I2C device driver that is already similar in required functionality, rather than hacking a special case driver for userspace access.
So now I want to replicate i2c-dev as a new driver that works specifically with this particular device, so that I can add some of my own device-specific abstraction code on top
So then you actually need to write a "Client driver" as described below (from Linux Documentation/i2c/summary):
When we talk about I2C, we use the following terms:
Bus -> Algorithm
Adapter
Device -> Driver
Client
An Algorithm driver contains general code that can be used for a whole class
of I2C adapters. Each specific adapter driver either depends on one algorithm
driver, or includes its own implementation.
A Driver driver (yes, this sounds ridiculous, sorry) contains the general
code to access some type of device. Each detected device gets its own
data in the Client structure. Usually, Driver and Client are more closely
integrated than Algorithm and Adapter.
Details are in Documentation/i2c/writing-clients.
To find a driver of similar functionality, scan the list of I2C client drivers. Note that these I2C drivers are located in the Linux source tree by their functionality (e.g. drivers/rtc/ or drivers/hwmon/) and not their interface (i.e. I2C).

Resources