world leader in high performance signal processing
Trace: » serial

Serial over USB

This exposes a tty style serial line interface, usable with Minicom and similar tools. (There's no serial console support at this time.) Most Linux hosts can talk to this using the generic usb-serial driver. The latest versions of this driver implement the CDC ACM class, as might be implemented by a cell phone or other modem. This driver works with the MS-Windows usbser.sys driver, the Linux cdc-acm driver, and many other USB Host systems. The 2.6.10 kernel has a detailed Documentation/usb/gadget_serial.txt file with information on how to set up this driver with both Windows and Linux systems.

Source file drivers/usb/gadget/serial.c

Overview

The gadget serial driver is a Linux USB gadget driver, a USB device side driver. It runs on a Linux system that has USB device side hardware; for example, a PDA, an embedded Linux system, or a PC with a USB development card.

The gadget serial driver talks over USB to either a CDC ACM driver or a generic USB serial driver running on a host PC.

 Host
 --------------------------------------
| Host-Side   CDC ACM       USB Host   |
| Operating |   or        | Controller |   USB
| System    | Generic USB | Driver     |--------
| (Linux or | Serial      | and        |        |
| Windows)    Driver        USB Stack  |        |
 --------------------------------------         |
                                                |
                                                |
                                                |
 Gadget                                         |
 --------------------------------------         |
| Gadget                   USB Periph. |        |
| Device-Side |  Gadget  | Controller  |        |
| Linux       |  Serial  | Driver      |--------
| Operating   |  Driver  | and         |
| System                   USB Stack   |
 --------------------------------------

On the device-side Linux system, the gadget serial driver looks like a serial device.

On the host-side system, the gadget serial device looks like a CDC ACM compliant class device or a simple vendor specific device with bulk in and bulk out endpoints, and it is treated similarly to other serial devices.

The host side driver can potentially be any ACM compliant driver or any driver that can talk to a device with a simple bulk in/out interface. Gadget serial has been tested with the Linux ACM driver, the Windows usbser.sys ACM driver, and the Linux USB generic serial driver.

With the gadget serial driver and the host side ACM or generic serial driver running, you should be able to communicate between the host and the gadget side systems as if they were connected by a serial cable.

The gadget serial driver only provides simple unreliable data communication. It does not yet handle flow control or many other features of normal serial devices.

Installing the Gadget Serial Driver

Kernel config for Gadget Serial Driver

[Linux Kernel Configuration] -→ [Device Drivers] -→ [USB support] -→ [USB Gadget Support]

<M> Support for USB Gadgets
<M>   Serial Gadget (with CDC ACM support)

You must load the gadget serial driver. To load it as an ACM device, do this:

modprobe g_serial use_acm=1

To load it as a vendor specific bulk in/out device, do this:

modprobe g_serial

This will also automatically load the underlying gadget peripheral controller driver. This must be done each time you reboot the gadget side Linux system. You can add this to the start up scripts, if desired.

The gadget serial driver uses major number 252. Its device inode ttyGS0 will be created after the module is loaded into kernel.

root:/> ls -l dev/ttyGS0
crw-rw----    1 root     root     252,   0 Jan 15 06:03 dev/ttyGS0

If gadget serial is loaded as an ACM device you will want to use either the Windows or Linux ACM driver on the host side. If gadget serial is loaded as a bulk in/out device, you will want to use the Linux generic serial driver on the host side. Follow the appropriate instructions below to install the host side driver.

Installing the Windows Host ACM Driver

To use the Windows ACM driver you must have the files “gserial.inf” and “usbser.sys” together in a folder on the Windows machine.

The “gserial.inf” file is given here.

-------------------- CUT HERE --------------------
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%LINUX%
DriverVer=08/17/2004,0.0.2.0
; Copyright (C) 2004 Al Borchers (alborchers@steinerpoint.com)

[Manufacturer]
%LINUX%=GSerialDeviceList

[GSerialDeviceList]
%GSERIAL%=GSerialInstall, USB\VID_0525&PID_A4A7

[DestinationDirs]
DefaultDestDir=10,System32\Drivers

[GSerialInstall]
CopyFiles=GSerialCopyFiles
AddReg=GSerialAddReg

[GSerialCopyFiles]
usbser.sys

[GSerialAddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[GSerialInstall.Services]
AddService = usbser,0x0002,GSerialService

[GSerialService]
DisplayName = %GSERIAL_DISPLAY_NAME%
ServiceType = 1                  ; SERVICE_KERNEL_DRIVER
StartType = 3                    ; SERVICE_DEMAND_START
ErrorControl = 1                 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\usbser.sys
LoadOrderGroup = Base

[Strings]
LINUX = "Linux"
GSERIAL = "Gadget Serial"
GSERIAL_DISPLAY_NAME = "USB Gadget Serial Driver"
-------------------- CUT HERE --------------------

The “usbser.sys” file comes with various versions of Windows. For example, it can be found on Windows XP typically in

C:\WINDOWS\Driver Cache\i386\sp2.cab

Or it can be found on the Windows 98SE CD in the “win98” folder in the “DRIVER11.CAB” through “DRIVER20.CAB” cab files. You will need the DOS “expand” program, the Cygwin “cabextract” program, or a similar program to unpack these cab files and extract “usbser.sys”.

For example, to extract “usbser.sys” into the current directory on Windows XP, open a DOS window and run a command like

C:\g_serial>expand "C:\WINDOWS\Driver Cache\i386\sp2.cab" -F:usbser.sys .
Microsoft (R) File Expansion Utility  Version 5.1.2600.0
Copyright (C) Microsoft Corp 1990-1999.  All rights reserved.

Expanding c:\windows\driver cache\i386\sp2.cab to .\usbser.sys.

(Thanks to Nishant Kamat for pointing out this DOS command.)

When the gadget serial driver is loaded and the USB device connected to the Windows host with a USB cable, Windows should recognize the gadget serial device and ask for a driver. Tell Windows to find the driver in the folder that contains “gserial.inf” and “usbser.sys”.

For example, on Windows XP, when the gadget serial device is first plugged in, the “Found New Hardware Wizard” starts up. Select “Install from a list or specific location (Advanced)”, then on the next screen select “Include this location in the search” and enter the path or browse to the folder containing “gserial.inf” and “usbser.sys”. Windows will complain that the Gadget Serial driver has not passed Windows Logo testing, but select “Continue anyway” and finish the driver installation.

On Windows XP, in the “Device Manager” (under “Control Panel”, “System”, “Hardware”) expand the “Ports (COM & LPT)” entry and you should see “Gadget Serial” listed as the driver for one of the COM ports.

To uninstall the Windows XP driver for “Gadget Serial”, right click on the “Gadget Serial” entry in the “Device Manager” and select “Uninstall”.

Windows 7 64 Bit

To add support for the USB serial gadget to the INF file for use with Windows Vista/7 64bit, a few changes are needed. Please visit USB Communications Device Class on 64-bit Windows By Josh Perry for details. The following INF file has been modified from the sample that Josh provides so that it will work with the Blackfin driver. The most important part is that the VID and PID were modified to match the INF from above. You will not need usbser.sys on Windows 7 64 bit using this INF.

[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%ProviderName%
DriverVer=10/15/2009,1.0.0.0

[MANUFACTURER]
%ProviderName%=DeviceList, NTx86, NTamd64

[DeviceList.NTx86]
%BfinCDC%=DriverInstall,USB\VID_0525&PID_A4A7

[DeviceList.NTamd64]
%BfinCDC%=DriverInstall,USB\VID_0525&PID_A4A7

[DriverInstall]
include=mdmcpq.inf
CopyFiles=FakeModemCopyFileSection
AddReg=LowerFilterAddReg,SerialPropPageAddReg

[DriverInstall.Services]
include = mdmcpq.inf
AddService = usbser, 0x00000002, LowerFilter_Service_Inst

; This adds the serial port property tab to the device properties dialog
[SerialPropPageAddReg]
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[Strings]
ProviderName = "CDC Driver"
BfinCDC= "Blackfin Com Port"

Installing the Linux Host ACM Driver

To use the Linux ACM driver you must configure the Linux host side kernel for “Support for Host-side USB” and for “USB Modem (CDC ACM) support”.

Once the gadget serial driver is loaded and the USB device connected to the Linux host with a USB cable, the host system should recognize the gadget serial device. For example, the command

mount -t usbfs none /proc/bus/usb/
cat /proc/bus/usb/devices

should show something like this:

T:  Bus=05 Lev=01 Prnt=01 Port=06 Cnt=01 Dev#= 11 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=0525 ProdID=a4a7 Rev= 2.16
S:  Manufacturer=Linux 2.6.22.14-ADI-2007R2-pre-svn3935 with musb_
S:  Product=Gadget Serial
S:  SerialNumber=0
C:* #Ifs= 2 Cfg#= 2 Atr=c0 MxPwr=  2mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=cdc_acm
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

If the host side Linux system is configured properly, the ACM driver should be loaded automatically. The command “lsmod” should show the “acm” module is loaded.

Installing the Linux Host Generic USB Serial Driver

To use the Linux generic USB serial driver you must configure the Linux host side kernel for “Support for Host-side USB”, for “USB Serial Converter support”, and for the “USB Generic Serial Driver”.

Once the gadget serial driver is loaded and the USB device connected to the Linux host with a USB cable, the host system should recognize the gadget serial device. For example, the command

mount -t usbfs none /proc/bus/usb/
cat /proc/bus/usb/devices

should show something like this:

T:  Bus=05 Lev=01 Prnt=01 Port=06 Cnt=01 Dev#= 28 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=0525 ProdID=a4a7 Rev= 2.16
S:  Manufacturer=Linux 2.6.22.14-ADI-2007R2-pre-svn3935 with musb_
S:  Product=Gadget Serial
S:  SerialNumber=0
C:* #Ifs= 2 Cfg#= 2 Atr=c0 MxPwr=  2mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=(none)
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=(none)
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

You must explicitly load the usbserial driver with parameters to configure it to recognize the gadget serial device, like this:

modprobe usbserial vendor=0x0525 product=0xA4A6

If everything is working, usbserial will print a message in the system log saying something like “Gadget Serial converter now attached to ttyUSB0”.

Testing with Minicom or HyperTerminal

Once the gadget serial driver and the host driver are both installed, and a USB cable connects the gadget device to the host, you should be able to communicate over USB between the gadget and host systems. You can use minicom or HyperTerminal to try this out.

On the gadget side run “minicom -s” to configure a new minicom session. Under “Serial port setup” set ”/dev/ttyGS0” as the “Serial Device”. Set baud rate, data bits, parity, and stop bits, to 9600, 8, none, and 1--these settings mostly do not matter. Under “Modem and dialing” erase all the modem and dialing strings.

On a Linux host running the ACM driver, configure minicom similarly but use ”/dev/ttyACM0” as the “Serial Device”. (If you have other ACM devices connected, change the device name appropriately.)

On a Linux host running the USB generic serial driver, configure minicom similarly, but use ”/dev/ttyUSB0” as the “Serial Device”. (If you have other USB serial devices connected, change the device name appropriately.)

On a Windows host configure a new HyperTerminal session to use the COM port assigned to Gadget Serial. The “Port Settings” will be set automatically when HyperTerminal connects to the gadget serial device, so you can leave them set to the default values--these settings mostly do not matter.

With minicom configured and running on the gadget side and with minicom or HyperTerminal configured and running on the host side, you should be able to send data back and forth between the gadget side and host side systems. Anything you type on the terminal window on the gadget side should appear in the terminal window on the host side and vice versa.