linux cdc_ecm driver vs rndis driver - linux-kernel

How is linux cdc_ecm driver related to rndis protocol? Is cdc_ecm based on rndis specification from microsoft in any way?
From this wiki page https://en.wikipedia.org/wiki/RNDIS
The USB Implementers Forum (USB-IF) defines at least three non-proprietary USB communications device class (USB CDC) protocols with comparable "virtual Ethernet" functionality; one of them (CDC-ECM) predates RNDIS and is widely used for interoperability with non-Microsoft operating systems, but does not work with Windows.
seems cdc_ecm to be based on microsoft rndis.

CDC-ECM is a standard that was created by USB-IF. It's not related to RNDIS at all. As your quote says, it predates RNDIS. This means it was created before RNDIS existed, so it couldn't be based on RNDIS unless a time machine enters the picture. And if you look at the protocol, it's clearly different.
CDC-ECM works out of the box on Linux hosts, MacOS, ChromeOS, and certain (mainly Samsung) Android phones.
Microsoft decided to create a new Ethernet on USB protocol instead of using the standard that already existed (CDC-ECM). That's just how Microsoft is. So they created RNDIS which isn't a standard and wasn't published. It's a hack based on NDIS, which is an old DOS and Windows 3.11 era network protocol from Microsoft. That's also just how Microsoft is. They like to base stuff on top of older MS software, which is based on even older MS software, going all the way back to DOS. That makes it really complex and hard for anyone else to be compatible with.
Microsoft doesn't include CDC-ECM drivers in Windows, but does have RNDIS drivers.
One can't get Windows to load the included RNDIS drivers, without a INF file, using just the vendor and product ID, device class, etc. There is a non-standard USB device identification descriptor that Microsoft created (see the pattern here) that must be used to identify a RNDIS device to Windows so it will load the generic driver.
Linux has a CDC-ECM / RNDIS combo gadget that is useful for wider compatibility. This appears as a two function USB device. One function is RNDIS and Windows will use this. The other function is CDC-ECM and everyone else will use that. It's not "ECM with RNDIS support". It's two different functions, only one of which can be used at once, that are both created by the same gadget.

Related

Writing a UMDF virtual device driver (or software device) like Virtual DVD

I have an "off the shelf" commercial software using an ANT USB dongle to communicate with a cycling trainer.
My trainer is not compatible with the software because the protocol is slightly different (not a lot).
My goal is to write a protocol translator. The only thing I can think of is to write a UMDF virtual device driver (like Magic ISO Virtual DVD) looking like an ANT USB Device in the device manager (same PID\VID) while connecting itself to the physical ANT device. The virtual device driver will perform the protocol translation.
I looked at several examples from Microsoft here https://github.com/Microsoft/Windows-driver-samples but I was unable to find anything relevant. I thought this example would be a good start https://github.com/Microsoft/Windows-driver-samples-master/Sensors/CustomSensors but it is impossible to load the driver using the given procedure from the inf file.
BTW I am familiar with the content of INF files and the basics of KMDF & UMDF device drivers programming. My problem is to write something that will load in the device manager and present itself as a real USB device even if it is not enumerated by the USB bus subsystem.
Can anybody with driver development experience point me to some relevant code sample or documentation?
Best regards !
I am currently developing a UMDF CCID (smartcard reader) driver. This project helped me at the beginning because it compiles out of the box and creates virtual device nodes (smartcard readers) visible in the device manager.

Windows drivers - communicate with user process

I have written a application in Qt and what is the best way to communicate with a custom USB device (does not belong to any class - need to write custom drivers for it) under Windows. In Linux I could just share the data with user space from the /dev or /sys filesystems. What are the equivalent alternative in Windows ?
There are a couple of user-space USB libraries for Windows. While Microsoft do provide WinUSB directly, I'd recommend using either libusbx or libusb and installing the driver for your device with zadig.
Using libusbx rather than the Microsoft driver directly has the advantage of being easier to port to other operating systems, which might be a consideration for you as you are using Qt.

How can I make a custom USB device show up in Windows as a COM Port?

I have developed a USB device that communicates with linux over a simple but proprietary interface and some custom Linux drivers. My goal is to port this to Windows without writing windows drivers. What I would like to do is find an open source or inbuilt class driver for windows that would look like a COM port in Windows. Then I would tailor the embedded software to match what ever protocol and descriptors the virtual COM port expects to see.
The idea would be that I could plug my device in to a Windows machine and a relatively high speed COM port would appear with out me having to develop Windows drivers for it.
I have been looking at the USB CDC (Communications Device Class) documentation and it looks promising, but I don't know which sub interface would be best to use so that it would show up as a COM port.
Has anyone here done any work like this before or could provide some insight?
Specifically:
Are there virtual COM drivers "built in" to windows or would I need a 3rd party driver.
Which CDC sub class should I use for simple RS232 emulation (No need for modem AT commands, etc)
Is there a better option to do what I am trying to do.
Thanks
There is a USB-to-serial driver built in to Windows that will do what you want. It is called usbser.sys:
http://support.microsoft.com/kb/837637
You will have to write an INF file and distribute that to your users, but that will not be too hard because it is only a few kilobytes of text and you can find examples online.
I'm not aware of any great documentation for this driver by Microsoft, so my advice would be to find some other device that uses it, such as Pololu Wixel, and copy what they did.
Here are the device descriptors we used and the special control tranfers we had to implement:
https://github.com/pololu/wixel-sdk/blob/master/libraries/src/usb_cdc_acm/usb_cdc_acm.c
You can see our INF file, wixel_serial.inf, by downloading the software and looking in the drivers folder:
http://www.pololu.com/docs/0J46/3.a
(There are other files in there that are not necessary for you.)
You can also look at the Arduino Uno because they use the same driver.
Whatever you do, please don't use our USB Vendor ID in your product! You need to get your own.
Update: In Windows 10, you don't need an INF file anymore because of the new usbser.inf driver that comes with Windows.
If you are using a UART you can easily interface it to a FTDI USB chip like http://www.ftdichip.com/Products/ICs/FT232R.htm or a Prolific like http://www.prolific.com.tw/eng/products.asp?id=59
For development, prototype and testing I have half dozen of these laying around http://www.pololu.com/catalog/product/391
I connect it directly to the UART pins on AVR and 8051 micros.

Faking an RS232 Serial Port

I'm developing a project that has a number of hardware sensors connecting to the deployment machine through RS232 serial ports.
But ... I'm developing on a machine without an physical RS232 serial ports, but I would like to make fake serial ports that I can connect to and output data from with the aim of faking input from hardware sensors.
Does anyone know of a way to create a fake serial port and control it on Windows XP?
If you are developing for Windows, the com0com project might be, what you are looking for.
It provides pairs of virtual COM ports that are linked via a nullmodem connetion. You can then use your favorite terminal application or whatever you like to send data to one COM port and recieve from the other one.
EDIT:
As Thomas pointed out the project lacks of a signed driver, which is especially problematic on certain Windows version (e.g. Windows 7 x64).
There are a couple of unofficial com0com versions around that do contain a signed driver. One recent verion (3.0.0.0) can be downloaded e.g. from here.
I know this is an old post, but in case someone else happens upon this question, one good option is Virtual Serial Port Emulator (VSPE) from Eterlogic
It provides an API for creating kernel mode virtual comport devices, i.e. connectors, mappers, splitters etc.
However, some of the advertised capabilities were really not capabilities at all.
EDIT
A much better choice, Eltima. This product is fully baked. Good developer tech support. The product did all it claimed to do. Product options include both desktop applications, as well as software development kits with APIs.
Neither of these products are open source, or free. However, as other posts here have pointed out, there are other options. Here is a list of various serial utilities:
com0com (current)
com0com - With Signed Driver (old version)
Yet another place for com0com with Signed Driver (Pete's Blog)
Tactical Software
Termite
COM Port Serial Emulator
Kermit (obsolete, but still downloadable)
HWVSP3
HHD Software (free edition)
I use com0com - With Signed Driver, on windows 7 x64 to emulate COM3 AND COM4 as a pair.
Then i use COM Dataport Emulator to recieve from COM4.
Then i open COM3 with the app im developping (c#) and send data to COM3.
The data sent thru COM3 is received by COM4 and shown by 'COM Dataport Emulator' who can also send back a response (not automated).
So with this 2 great programs i managed to emulate Serial RS-232 comunication.
Hope it helps.
Both programs are free!!!!!
There's always the hardware route. Purchase two USB to serial converters, and connect them via a NULL modem.
Pro tips:
1) Windows may assign new COM ports to the adapters after every device sleep or reboot.
2) The market leaders in chips for USB to serial are Prolific and FTDI. Both companies are battling knockoffs, and may be blocked in future official Windows drivers. The Linux drivers however work fine with the clones.
Another alternative, even though the OP did not ask for it:
There exist usb-to-serial adapters.
Depending on the type of adapter, you may also need a nullmodem cable, too.
They are extremely easy to use under linux, work under windows, too, if you have got working drivers installed.
That way you can work directly with the sensors, and you do not have to try and emulate data.
That way you are maybe even save from building an anemic system.
(Due to your emulated data inputs not covering all cases, leading you to a brittle system.)
Its often better to work with the real stuff.
i used eltima make virtual serial port for my modbus application debug work. it is really very good application at development stage to check serial port program without connecting hardware.

Do I need to write my own host side USB driver for a CDC device

This may not be considered to be directly programming related but I am at a loss to know where else to ask. I have tried looking at a variety of websites but so far Google has not been my friend.
I am having trouble finding out whether I need to write my own device driver for the various windows/linux/mac platforms that the device I am developing may be connected to, or whether the functionality is provided by the standard drivers.
My device is a USB CDC (communications device) that appears as a COM: port. It also includes a battery charger that will, once the device has been enumerated require the full 5 unit load (500mA) supply current that can be drawn from the USB connector. My problem is that if the USB driver in the host decides that it cannot deliver the full supply current then it should fail to enumerate the device.
If, as a fallback, I provide a second configuration set that only allows the device to draw 1 unit load from the interface connector will the standard drivers enumerate the device using this configuration.
You need to write a .inf file for Windows that ties up your device VID and PID with the system usbser.sys. Mine looks like this (Replace YourCompany as necessary, put in your VID and PID (in hex), and change the DriverVer line to whatever date and version you want):
; -----------------------------------------------------------------------------
; XP/2000 USB Comms Port Setup
; -----------------------------------------------------------------------------
[Version]
DriverVer=12/03/2008,1.0.0000.0000
Signature="$Windows NT$"
Class=Ports
ClassGUID={4d36e978-e325-11ce-bfc1-08002be10318}
Provider=%YourCompany%
[DestinationDirs]
DefaultDestDir=10,system32\drivers
DriverCopyFiles=12
[ControlFlags]
ExcludeFromSelect = *
[Manufacturer]
%YourCOmpany%=YourCompanySerialPort
[YourCompanySerialPort]
%YourCompanyUSBSerialPort%=YOURCOMPANYUSB,USB\VID_1234&PID_ABCD
;
; Win 2000/XP
;
[YOURCOMPANYUSB]
Include=mdmcpq.inf
CopyFiles=FakeModemCopyFileSection
[YOURCOMPANYUSB.HW]
AddReg=YOURCOMPANYUSBAddReg.HW
[YOURCOMPANYUSBAddReg.HW]
HKR,,DevLoader,0,*ntkern
HKR,,NTMPDriver,,"usbser.sys"
[YOURCOMPANYUSB.Services]
AddService=usbser, 0x00000002, FuncDrv_Service_Inst
[FuncDrv_Service_Inst]
DisplayName=%USBFilterString%
ServiceType= 1
StartType = 3
ErrorControl = 0
ServiceBinary = %12%\usbser.sys
[Strings]
YourCompany="YourCompany"
YourCompanySerialPort="Your Company USB Serial Port"
USBFilterString = "USB Serial Service"
Note this works with 32 bit OSs only. It also works with Vista although the file header doesn't say so!
Be aware that some versions of usbser.sys have significant problems, including bluescreening, for example when transferring packets that are exact multiples of 64 bytes. If you're using XP SP2 or previous then install hotfix KB943198. XP SP3 and Vista are fine.
For the Mac you simply need to report your device class correctly and the driver scan picks up the correct drivers. (Windows ignores the device class which is why you need to supply the .inf file).
EDIT: Sorry, I should have been clearer. This will not fail to enumerate if it can't draw the full load - I'm not sure that's possible.
You are correct on the driver question. When the device is plugged in and goes through the enumeration process it is required to stay < 100mA. The host will interrogate and determine the configuration(s). If there are more than one which support different power levels, then the driver will need to decide to select the appropriate configuration. If there is only high-power and it is not available, then it will not enumerate the device. In general, the standard driver doing CDC wouldn't be aware of the different device level configurations that would possible and so would require some degree of customization to handle them.
I am not sure about power question but ther is pleanty CDC drivers (or I think there is) so you could use one. For the power question, the solution with many configuration is probably good one, I have never encountered this in work (I have USB analyzer) but at home sometimes when I have 3 or more different devices that requires power from USB I got failed enumeration. I supose this is operating system choice if it can't supply power to new device it cut's it off (sensible choice as it can't power it). This is my gues rather checking USB standart.
If your device reports a device ID that the host OS already supports,
then they won't need a driver.
You may need to impersonate an existing USB uart. Data sheets are readily available.
(But I figure you already knew that.)
I'm not sure that the host OS will honour your multi-configuration idea.
But give it a punt so we all know!
If your device is connecting as USB CDC-ACM device to the windows desktop host, the windows desktop already provides the driver usbser.sys. But there are some some issues in windows Vista. You just need the inf to install the usbser.sys on desktop. For WinCE you do not have the driver and for you need to write or get one from any third party vendor. Here is one
http://www.em.avant-garde-lab.com/Products.html
If your device specifies itself as self powered in its device descriptor then the host would rely on the devices self power capability. You can check at usb.org for details.
Thanks.

Resources