11/26/2014

USB Driver의 기본구조 및 Linux 관련 Driver

1. USB의 Pin과 종류 

  • USB의 Pin Type 
USB Type A 와 B로 나누어지며,  기본 USB 1.0은 4 Pin이 기본이며, 이 후 OTG가 지원이 되면서,
Micro USB A/B 부터 5Pin으로 변경되어 ID Pin을 필요


  • USB의 기본 4 Pinout
Type-A and -B pinout
PinNameWire color[a]Description
1VBUSRed orOrange+5 V
2D−White orGoldData−
3D+GreenData+
4GNDBlack orBlueGround


  • USB 의 5 Pinout (OTG이후)
Mini/Micro-A and -B pinout
PinNameWire color[a]Description
1VBUSRed+5 V
2D−WhiteData−
3D+GreenData+
4IDNo wireOn-The-Go ID distinguishes cable ends:
  • "A" plug (host): connected to GND
  • "B" plug (device): not connected
5GNDBlackSignal ground


USB는 일반 USB Pin을 제외하고 5 Pin이며, 이때 새로 생긴 것이 OTG (On-The-Go)  Pin이다.
이는 HOST가 될수 있으며, Device가 될수도 있기때문에 이 Pin은 중요한다.


  • 자세한 내용은 Wiki 참조
  https://en.wikipedia.org/wiki/USB
  http://processors.wiki.ti.com/index.php/DM81xx_AM38XX_USB_User_Guide


2. USB Host Driver의 구조 

USB는 아래와 같이 USB Version에 따라 지원되는 기능이 달라지며 자세한 내용은 아래의 링크를 참조하자.

  • USB Host Controller 기본구조 
  1. OHCI (Open Host Controller Interface) 
    1. 처음 만들어진 USB 1.0 / 1.1 표준 USB Host Controller 이며, fireworks device를 위해 사용되어진다고하는데, 최근 Linux Kernel에 존재함 
  2. UHCI(Universal Host Controller Interface)
    1.  USB 1.x 부터 인텔에 의해 만들어져서 로얄티가 있다고 하며, 아직도 Linux에 소스가 존재함

OHCI 와 UHCI 관련내용

  • USB Host Controller 확장구조 ( USB2.0 / USB3.0)
  1. EHCI (Enhanced Host Controller Interface)
    1. USB 2.0 지원을 위한 표준이며 보통 Linux Kernel에 존재한다.  
  2. xHCI (Extensible Host Controller Interface)
    1. USB 3.0 지원을 한다고 하며, OHCI/UHCI/EHCI를 대체를 한다고 아직 사용을 못해봤다. 

Chip Maker마다 다르겠지만, 기본 자사 USB Host Controller Driver(OHCI)EHCI를 조합으로 사용을 하는 것으로 보이며, 
각 Chip Maker의 USB Host Controller가 OHCI or UCHI를 선택해서 사용하는 것 같은데, 로얄티 문제로 주로 OHCI기반으로 구성하는 것 같다.  




USB Device 의 Class Descriptor 와 USB Class Driver 와 연결
  https://ahyuo79.blogspot.com/2014/11/class-descriptor.html


  • USB CDC for LTE 관련 Driver 
  https://wiki.openwrt.org/doc/recipes/3gdongle
  http://tpholic.com/xe/?mid=ibmqna&page=2&document_srl=6593791
  https://www.linuxquestions.org/questions/linux-newbie-8/how-do-i-define-ttyusb0-423976/
  https://www.olimex.com/forum/index.php?topic=558.0
  http://www.makelinux.net/ldd3/chp-13-sect-4
USB File System 의 이용
  http://www.hep.by/gnu/kernel/usb/usbfs.html
  https://stackoverflow.com/questions/25793399/mount-usbfs-on-linux-3-10-kernel


2.1 USB Host Module 동작 

아래와 같이 USB는 Interface Descriptor와 Probe가 가장 중요하므로, 아래와 같이 각 기능을 확인을 해보자.

요즘은 USB Driver를 모듈 만들어 modprobe를 이용하여 vendor, product 정보를 넣고 올린다. (udevd 이용)

USB의 Host의 USB Device Module기본동작은 다음과 같다
  1. Device/Interface Descriptor를 분석하여 맞게 Driver Loading 
  2. Interface driver는 보통 Probe에서 다른 Interface driver로 연결
  3. Endpoint Descriptor를 분석하여 URB를 Host와 Device가 통신할 것인지 분석. 
최종의 Driver는 Endpoint Descriptor 기준으로 URB
URB는 USB Request Block으로 Endpoint Descriptor의 기초로 만들어지면, 이 DATA 구조로 Host와 Device는 통신을 하게된다.


  • Probe의 역할
Probe는 가장 중요한 역할을 하며, 각각의 Interface를 분석하며, 다른 Driver를 호출한다.
물론 최종 Interface Driver가 존재하며, 이곳에서 Endpoint Descriptor와 URB관련 부분이 존재한다.


2.2 USB Host의 Core File의 기능 

  • USB HCD Core Files
Linux Version 마다 다르겠지만, drivers/usb/core 위치한 driver들이 각 명령을 Control 하고 제어를 담당한다 
  1. USB의 기본적인 Control ( GET_DESCRIPTOR ...)
  2. USB의 URB 전송 및 제어 
  3. Hub Class 
  4. 다른 USB Driver Probe 제어 (Device/Interface Descriptor 기준)
  http://elixir.free-electrons.com/linux/v2.6.28.1/source/drivers/usb/core/hcd.c#L428
  http://elixir.free-electrons.com/linux/v2.6.28/source/drivers/usb/core/usb.c#L606


  • USB Device Driver 등록 (Module의 관리)
  1. usb_register_driver는 모든 USB Driver가 등록하고 이를 관리. (Linked List)
  2. usb_register_driver 내에는 usb_probe_interface 가지고 있으며,module내의 probe별도 
  3. usb_probe_interface는 USB match 관련부분 등록된 USB Driver를 호출 전 관리 
  http://elixir.free-electrons.com/linux/v2.6.28/source/drivers/usb/core/driver.c


  • 간혹 open() 에서 사용되는 usb_find_interface로 Interface driver를 찾음
  http://elixir.free-electrons.com/linux/v2.6.28/source/drivers/usb/core/usb.c#L163


2.3 USB Host Module 기본구조

module_init/module_exit 할때 각각의 module을 usb_register_driver 등록 및 해제한다.


  • 기본 USB Module 
  http://elixir.free-electrons.com/linux/v3.13-rc1/source/drivers/usb/usb-skeleton.c


2.4 USB Host 연결된 Module Example 

아래의 Driver를 Probe를 간단히 분석해보면, probe에서 다시 usbnet_probe를 호출하여 결국 usbnet_probe를 사용하여

Endpoint가 결정되고, URB 부분이 완성된다.

  http://elixir.free-electrons.com/linux/v3.13-rc1/source/drivers/net/usb/qmi_wwan.c#L794
  http://elixir.free-electrons.com/linux/v3.13-rc1/source/drivers/net/usb/usbnet.c#L1543

  • 관련 Linux Driver 문서 
  http://www.makelinux.net/ldd3/chp-13-sect-4


USB_DEVICE (Venid, ProductID)
struct usb_device_id
usb_register(&pen_driver);
device_register (&port->dev);



  • Debug는 USB Host에서 Probe시 Interface의 정보기술


 xxxx_probe(struct usb_interface *intf, const struct usb_device_id *prod)
{
 printk("intf No:%d Ty:%d Cl:%d SC:%d Pr:%d\n"
   ,intf->cur_altsetting->desc.bInterfaceNumber
   ,intf->cur_altsetting->desc.bDescriptorType
   ,intf->cur_altsetting->desc.bInterfaceClass
   ,intf->cur_altsetting->desc.bInterfaceSubClass
   ,intf->cur_altsetting->desc.bInterfaceProtocol
 ); //jhlee

}



  • inlclude/linux/usb.h

struct usb_interface {
 /* array of alternate settings for this interface,
  * stored in no particular order */
 struct usb_host_interface *altsetting;

 struct usb_host_interface *cur_altsetting; /* the currently
      * active alternate setting */
 unsigned num_altsetting; /* number of alternate settings */

 int minor;   /* minor number this interface is
      * bound to */
 enum usb_interface_condition condition;  /* state of binding */
 struct device dev;  /* interface specific device info */
 struct class_device *class_dev;
};
...
struct usb_host_interface {
 struct usb_interface_descriptor desc;

 /* array of desc.bNumEndpoint endpoints associated with this
  * interface setting.  these will be in no particular order.
  */
 struct usb_host_endpoint *endpoint;

 char *string;  /* iInterface string, if present */
 unsigned char *extra;   /* Extra descriptors */
 int extralen;
};


  • inlclude/linux/usb_ch9.h

/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
 __u8  bLength;
 __u8  bDescriptorType;

 __u8  bInterfaceNumber;
 __u8  bAlternateSetting;
 __u8  bNumEndpoints;
 __u8  bInterfaceClass;
 __u8  bInterfaceSubClass;
 __u8  bInterfaceProtocol;
 __u8  iInterface;
} __attribute__ ((packed));


  http://elixir.free-electrons.com/linux/v4.3.3/source/include/uapi/linux/usb/cdc.h#L17
  http://elixir.free-electrons.com/linux/v3.17.5/source/drivers/net/usb/qmi_wwan.c#L845


3. USB OTG의 Gadget (Device) 구조 

USB Device의 구조는 설명했듯이 기본적인 USB에서 제공하는 각 Descriptor를 제공을해줘야한다.
그리고 이의 설정에 맟추어 EndPoint 와 URB로 USB HOST와 통신이 가능하도록 해줘야한다.

기존에는 별도의 USB Device Chip을 사용하는 경우도 있으나, 현재 Linux에서는 OTG기반으로 USB Gadget(Device)를 사용가능하다 


USB Gadget의 Function ACM
  http://elixir.free-electrons.com/linux/v3.7.9/source/drivers/usb/gadget/f_acm.c


3.1 USB Gadget Driver  

OTG(On-The-Go) Mode로  사용할 경우, USB는 Device Mode와 Host Mode가 동시 동작이 가능하기 때문에,
Host 이외에 Linux에서는 Gadget이라는 것을 이용하여 USB Device Mode를 지원한다.

아래와 같이 USB Device Mode로 사용할 경우 각 Class Device를 대충 알아보자.
대표적인 것들이 Mass Storage , CDC 등 다양하게 이용이되며, Module 형태로 Kernel에서 기본적으로 제공을 해준다.

반드시 Kernel Version을 확인하자.
  https://www.kernel.org/doc/htmldocs/gadget/index.html

  • 각 개별 모듈의 위치 
      drivers/usb/gadget

  • 주요소스 분석 부분 
  1. Gadget Driver에서의  Descriptor의 정의 및 설정부분 
  2. Endpoint를 어떻게 기본 통신을 하는지 개념 
  3. 이 Endpoint 통신부분과 다른 Interface와 어떻게 연결되는지 관련부분 Driver들   

  • 관련내용 
  http://www.linux-usb.org/gadget/
  http://www.linux-usb.org/gadget/h2-otg.html
  http://www.usb.org/developers/docs/
  https://events.linuxfoundation.org/sites/events/files/slides/LinuxConNA2013-andrzej.pietrasiewicz-usb-gadget-configfs_0.pdf

  • 관련소스
  https://elixir.free-electrons.com/linux/v3.3/source/drivers/usb/gadget
  https://elixir.free-electrons.com/linux/v2.6.29.3/source/drivers/usb/gadget
  https://git.linuxtv.org/pinchartl/uvcvideo.git/tree/drivers/usb/gadget?h=uvcvideo-gadget


  • TI-Sitara Version 예제 
기본동작 방식은 module 형태로 동작하기 때문에, 아래와 같이 lsmod로 자신의 module점검을 해보자.

# lsmod
Module                  Size  Used by
sd_mod                 28383  2
usb_storage            47815  1
scsi_mod              135887  2 usb_storage,sd_mod
bc_example              7250  0
sha512_generic          9903  0
sha512_arm             12079  0
drbg                   13425  1
des_generic            17736  0
cbc                     2324  0
xfrm_user              22606  2
xfrm4_tunnel            2040  0
ipcomp                  2257  0
xfrm_ipcomp             4311  1 ipcomp
esp4                    6466  0
ah4                     5627  0
bluetooth             327425  2
af_key                 26406  0
xfrm_algo               6970  5 ah4,esp4,af_key,xfrm_user,xfrm_ipcomp
usb_f_acm               5404  1
u_serial               11555  3 usb_f_acm
usb_f_ecm               6620  1
g_multi                 6330  0
usb_f_mass_storage     37916  2 g_multi
usb_f_rndis            15406  2 g_multi
u_ether                13577  3 usb_f_ecm,usb_f_rndis,g_multi
libcomposite           44392  5 usb_f_acm,usb_f_ecm,usb_f_rndis,g_multi,usb_f_mass_storage
configfs               26917  6 usb_f_acm,usb_f_ecm,usb_f_rndis,libcomposite,usb_f_mass_storage
rpmsg_pru               4958  0
virtio_rpmsg_bus       12724  1 rpmsg_pru
musb_dsps               8235  0
musb_hdrc              71486  1 musb_dsps
udc_core               12063  2 musb_hdrc,libcomposite
usbcore               195911  2 musb_hdrc,usb_storage
pm33xx                  5577  0
snd_soc_simple_card     7712  0
ecb                     1909  0
pru_rproc              11796  2
pruss_intc              7163  3 pru_rproc
ti_emif_sram            6242  1 pm33xx
wkup_m3_ipc             8278  1 pm33xx
sha256_generic          9503  1
hmac                    2735  1
wkup_m3_rproc           3669  1
md5                     1897  0
pvrsrvkm              406903  5 bc_example
sha1_generic            2621  0
sha1_arm_neon           6261  0
sha1_arm                3862  1 sha1_arm_neon
omap_aes_driver        19488  0
pruss                  10892  1 pru_rproc
remoteproc             26901  4 pruss,wkup_m3_rproc,pru_rproc,wkup_m3_ipc
omap_sham              21513  0
virtio                  7742  2 remoteproc,virtio_rpmsg_bus
virtio_ring            12163  2 remoteproc,virtio_rpmsg_bus
wlcore_sdio             6771  0
omap_rng                4759  0
rng_core                7794  1 omap_rng
snd_soc_tlv320aic3x    48260  1
musb_am335x             1426  0
ti_am335x_tsc           6029  0
rtc_omap                8272  1
omap_wdt                4634  0
ti_am335x_tscadc        6290  1 ti_am335x_tsc
sch_fq_codel            8289  4
cryptodev              38007  2

USB Gadget u_serial는 USB ACM으로  usb_f_acm과 연결되어 동작 (USB to Serial)