Writing USB Device Driver in Linux - linux-device-driver

ALSA or libusb api are two choices; both are new to me; its been years since I wrote a device driver and it was for Unix back in the 80's, but I do know I can figure out how, once I know what tools to use, which I'm guessing both use C still; I have looked at the libusb api; very nice; but I have no idea about ALSA project; seems they are geared into getting modules into the kernel to achieve this.
This is a generic question, but the Device I'm interested in is the Roland GR-55; it has MIDI and Audio from the same USB connection; it has Windows and MAC Drivers but no Linux.
Which libraries or tools do you prefer to use?
Do I write a Device Driver or Loadable Kernel Modules (LKM)?

libusb is useful and easy to get up and running. I would suggest that you start there, especially if you haven't written Linux drivers in a while. Use libusb to understand what the signalling protocol is for the Roland GR-55 and do some experiments.
USB supports several types of logical connections over the same physical wire. There will likely be DATA and CONTROL pipes available from the device and you will need to map that out before starting on a proper driver.
As I said, libusb is easy to get going and you could have something useful in a few days if you just want to write a control interface and store raw data from the device. However, ALSA is the way to go if you want to use the device with existing music software. Also, by updating ALSA you would be supporting the larger community because you could merge your work in to the ALSA project.
Writing a kernel module from scratch could be fun, but USB is a bit of a beast and would probably not be an ideal one to start with. With ALSA you will have a framework to guide you and won't need to worry so much about defining your own APIs.

As commented above, check out Linux Device Drivers http://lwn.net/Kernel/LDD3/ chapter 13 talks specifically about USB drivers. For development it's easier to write your driver as a kernel module because then you don't need to recompile the kernel when you make a change.

No need for writing a new driver - ALSA already has support for that since a while. See commit https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0ef283247a0cf0fd2e8370ee467030292eb3129e

Since you probably want to hear sound on your sound card, you should opt for ALSA. That way after you are done you are done. If you write libusb driver, then you would have to write your own user space tools for feeding that sound card sound for playing.

Related

Implementation of USB device driver on my own OS based in Linux

I’m on process of developing my own Operating System based in Linux.
This week we’re aiming to implement very simple USB device driver , which is quite hard to get basic algorithm .
However commonly it’s hard to find out some sources aside from commercial linux system.
And I want to get some advice about this .
Plus, I do all these stuffs on Ubuntu , using QEMU emulator.
I’ve done simple file system and hard disk device driver so far.
Help me out how to implement USB device driver with very sime ideas.
Thank you !! :)
Implementing USB is quite the task. First you must have a working PCI(e) enumerator or other form of finding the USB controller. You then must find out which of the four most common controller types it happens to be. Each controller type is completely different from the previous and must contain its own driver. You also need a standard USB interface that is independent of the controller type.
Taking on the USB is quite the task, but in my opinion a very interesting and enjoyable task. Enjoyable enough, that I even wrote a book about how to do it. It explains how to find the controller(s) via the PCI(e) bus, how to setup this bus, how to detect the type of USB controller--UHCI, OHCI, EHCI, or xHCI--and how to send and receive data packets to/from attached devices. This book was written exactly for the purpose of those of us creating our own operating systems and adding USB support to them. The fact that you are basing your OS on Linux should not matter since the book does not rely upon any existing OS to accomplish this task, other than the example programs relying on memory allocation, which is easily modified for your developing platform.
Might I say that if you do take on this task, it will be a difficult task, but it will be an enjoyable task. In my opinion, the USB is the most enjoyable part of this hobby of ours.

There is no STM32 chip through the USB driver WIFI module program?

I want to make a network camera, stm32 through the camera to collect images, and then sent to the server through the WIFI module. As 1 second need to transfer a lot of data, so I would like to use the USB interface wifi module program to achieve. Or what better solution to achieve.
Thank you!
I think that you have no idea how the USB works.
You have a couple solutions.
Use a wifi module with SPI interface.
Use a SOC like CC3200.L
Use ESPxxxx module or similar (RTL8710)
You can of course try to use STM with host usb interface, but you will have to implement the USB host stack + driver for USB wifi module + network stack (eg TCP/IP stack). But it is quite complicated as the STM ones are not very good, there are some better paid ones - but expensive. USB host is not easy to implement.
If you want to go along the "networking over USB" path on STM32 (and I'm assuming you're not planning to buy any commercial drivers) it's going to be rough for you.
When it comes to USB, vast majority of the WiFi dongle drivers are proprietary and unless you're on an operating system such as Windows or Linux you're out of luck, unless you want to for the reverse engineering or porting at least parts of the drivers from Linux. With the USB you can think of using the USB-ECM (ethernet over USB) class, but two things here. One - ST doesn't provide any free implementations of this class so you're down do searching for it or implementing it yourself. After a bit of googling I've found one instance of this on githbu, although I havent tested it myself. Second thing - this is no longer wireless as you'll need to be connected to some kind of host providing internet connection, at which point it's probably better to not use USB-ECM and networking at all and just send data using a class that can be implemented easily (USB-CDC or USB-HID). I'm a bit worried about the throughput here.
You can also try to find WiFi modules that are connected over other interface. Generally those modules are connected over UART, some over SPI. This way, integrating it with the TCP/IP stack will also be up to you, at least when it comes to implementing the WiFi module protocol (most likely AT-commands) and implementing network interface so that the stack can "talk" to it. In this approach, I'm almost sure that you'll lack the throughput required for your application.
Personally I'd strongly suggest trying Ethernet if that's an option for you. It's going to be highest bandwidth (which you're going to need), plus it's most "out of the box". There's multiple projects implementing various applications using a free LWIP stack over this interface, including examples generated by ST's CubeMX.

Beginner looking to write linux device driver (usb, pci). Suggestion on device?

I have been reading on linux kernel development and device drivers for a while. I feel ready to give it a go on a real piece of hardware. I would like to write a driver for a, preferably usb (otherwise pci), device for a desktop computer. But every device I seem to think of is already supported (including everything I own atm). So, would welcome any suggestions.
P.S. Willing to buy it, provided it's under £100 (150$).
Anything really practical has already been done out of necessity. My vote would be for something like http://www.amazon.com/Cheeky-Computer-Controlled-Missile-Launcher/dp/B004AIZV48/ref=pd_sim_t_1. It's fun, inexpensive, and currently Windows only.
The protocol should be pretty simple, but will give you good experience on debugging the USB channel in order to figure it out. And when you are done, you'll have a cool toy :)
USB-based devices are generally well supported at the kernel level. What this means is that u rarely have to write a device driver for each and every USB devices at the kernel. THis is because applications can easily use libusb (and several other userspace USB libraries) to talk to the device.
If you look into the USB code in the kernel, you can see that it is among the most complex implementation of all the hardware protocol, but it is also generic across different USB devices. I have done porting work for USB devices before, and trust me, libusb is good enough.
Check it out (for example):
http://libusb.sourceforge.net/doc/examples.html
You could port the Enttec Open DMX USB Interface driver to latest 3.x kernels.
git clone http://git.hbels.com/public/dmx_usb_module
libusb way sounds more appropriate to me too though.

How do I send Midi events to Software Synth in C++

Hi looking for some advice. I am writing some music composition software. I have cobbled together tools to read write and send midi data, they work fine. However I stumped on the following: I'm trying to send midi events to a SW synthesizer on the computer.
So I can control the sw synth from an external keyboard. I can control the keyboard from my own sw in the computer. But how do I get my sw to send midi to the sw synth in the same computer.
Also I'm trying to do this in a platform independent way if possible.
Thanks!
VMan
My question wasn't clear.
So I'm currently running on Win7. Cross platform is a priority but not for the first prototype.
Specifically my problem is with accessing kontakt player (v2) it works within it's own environment and with midi IO. But I can't access it from within my own software.
midiOutGetNumDevs returns just one device and it's the Microsoft GS Wavetable Synth.
I'm confused that I can send midi to the kontakt player via a midi/usb cable but that it doesn't show up as a midi device.
What am I missing?
Thx
Which API/OS are you using? Which SoftSynth?
Short answer: you might try "PortMidi".
http://portmedia.sourceforge.net/
Long(er) answer:
I haven't found any cross-platform MIDI lib able to speak to any kind of MIDI sink. In fact it depends on what the softsynth use for receiving MIDI events.
1) On Linux, you can use ALSA to speak to the ALSA synths. A softsynth can register itself as an ALSA sink. You can either:
* use the ALSA lib to connect to send MIDI events to this sink ;
* or you can register your application as a ALSA MIDI source and use another program (aconnectgui, qjackctl, patchage) to connect it to any sink.
http://www.alsa-project.org/alsa-doc/alsa-lib/rawmidi.html
http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html
Downside: Linux specific
2) You can use JACK for MIDI. As in ALSA MIDI, an application can register MIDI sources and sinks. Yhe softsynth can register as a JACK MIDI sink. Then you need to make you app a JACK MIDI source and connect them with another program (qjackctl, patchage).
http://jackaudio.org/files/docs/html/index.html
Downside: need installation, configuration, launching of JACK
You have two solutions to move the ALSA sink/sources as JACK sink/sources :
either use the built-in functionality of JACK (commandline -Xseq) ;
or using "a2jmidi"
4) On MacOS you can do MIDI with CoreAudio. I don't know anything about it though.
5) On windows, I guess you use the midi* functions in
6) Use OSS on some other OSes
7) Communicate with the synth using socket/protocols
You could make your software send MIDI events using MIDI/RTP or MIDI/UDP so you don't care about the driver/OS. Most softsynth don't speak any of those directly so you need a program to do the bridging (qmidinet or others).
8) PortMidi is a cross platform lib for MIDI. However it doesn't seem to be able to use JACK as a backend directly (you can however make the ALSA devices available in JACK as explained above).
http://portmedia.sourceforge.net/
For example, on Linux, Fluidsynth can use ALSA, OSS and JACK for MIDI input. Timidity++ can use ALSA and the Windows API.
OK the answer to this problem is to use a virtual midi driver. I found a free one here:
http://nerds.de/en/loopbe1.html
This creates a midi output device that shows up with midiOutGetNumDevs that I can stream my midi notes too and other Midi software on the same computer can use it as a midi input device.
Works on Win7 and apprently also has mac support. My problem is solved.
"LoopBe1 is an internal MIDI device for transferring MIDI data between computer programs. Basically LoopBe1 is an "invisible cable" to connect a MIDI outport of an application to any other application´s MIDI inport."
Agreed that a Virtual MIDI Driver is the easiest solution.
Another one that used to be very popular (not sure how it performs on Win7 though) is MIDI Yoke. http://www.midiox.com/
If you are looking to do something commercial, you may consider writing your own virtual MIDI driver to make your software controller(sender) a virtual MIDI source. Only on Windows will this be a lot of work.
On Mac and Linux your job is much easier. As #ysdx said, Mac using CoreMIDI and Linux using ALSA/Jack, this is very easy to do in your application by creating a Virtual MIDI port and connecting to destinations.

Wireless communication: AVR based embedded system and iPhone

What is the best way to realize wireless communication between an embedded system (based on an AVR controller) and the iPhone? I think there are only two options: either WiFi or BlueTooth. The range is not really a problem, since both devices should stay in the same room.
I have no idea, if there are any useful WiFi boards that can be connected to an AVR based microcontroller system (or any small microcontroller), any hints would be highly welcome.
I guess the better solution would be BlueTooth, but there is also the problem: which BlueTooth board is best suited for attachment to an AVR system, and is it possible to use the iPhone BlueTooth stack for (serial) communication over BlueTooth with the AVR device.
I hope that somebody already realized such a system and can give some helpful tips...
You can get modules for both WiFi and Bluetooth that will connect to an embedded system through a UART interface, however a WiFi module will have far more processing power than your AVR microcontroller, often with spare capacity and I/O to execute additional user code, so connecting one to an AVR maybe somewhat redundant in many cases.
Bluetooth modules are simpler, less expensive, and the data-rate is better matched to the AVR's capabilities. For example these Parani modules. I have used them between an embedded system and a Laptop PC's Bluetooth, so given appropriate communications software, there is no technical reason why it could not be used with an iPhone I think. However this may be the flaw, on the PC the device was recognised as a virtual serial port, I don't know whether iPhone supports 'legacy' communications in quite the same way.
For comparison, a WiFi solution
From what I know, BlueTooth is very limited on the iPhone: There is only very few BlueTooth-Profiles implemented, and - even if they can be extended with a jailbroken iPhone - I doubt this is easy to use from the application layer.
On the other side, transferring via WiFi requires a lot of processing power and memory since much more things have to be implemented before you can even start transferring data: 802.11, cdma/ca, arp, tcp. That's a big task.
Is it an option to build a hardware extension to the iPhone ? You might be able to get the serial connection and power out of the dock connector. Then even ZigBee could be very helpful.
Here's an article you might find helpful. I would lean toward a WiFi solution just because of the added flexibility available.
http://www.embedded.com/design/networking/215801088
-t
Some of the other people at the office have done AVR <- Bluetooth -> Symbian and AVR <- Bluetooth -> PC solutions without trouble. There is lots of info, reference designs and source available. I have no idea of how hard it would be to use Bluetooth on Iphone.
The exact module is probability also not important as long as it got some type of serial interface (I2C,SPI) to interface to the AVR and some source code show how to use the module.
Is it an 8-bit or 32-bit AVR? For the AVR32 processors there's support
for WiFi in the Atmel 1.5.0 Software Framework using SD-card-mounted
WiFi modules from HD Wireless (http://www.hd-wireless.se), including
an IP stack (lwIP). Be aware that you need Ad-Hoc (IBSS) support to
connect directly to the iPhone.
There is WiSnap kit. It can connect directly to a standard RS232 interface or through the TTL UART interface to embedded processors. We are planning to use it in our project. It also has Ad-Hoc support.
There are some usage examples and an iPhone application for connection setup.
http://serialio.com/products/mobile/wifi/WiSnapKit1.php
What are you trying to communicate between your AVR and the Iphone? The Iphone is made for the web along with everything apple (which AVR's are decidedly not). So what works well is an embedded device that exposes a web-interface. Like the Transmission bittorrent client on Linux. Also nowadays many low-power small form-factor linux platforms exist that will allow you to do this.
For instance Gumstix has an ARM based platform that runs linux and includes WiFi (Overo Fire).