임베디드 리눅스 개발보드에서 USB 키보드를 사용하는 방법
마우스 드라이버는 드라이버 로딩 부분, 프로브 부분, 오픈 부분, urb 콜백 함수 처리 부분 등 여러 부분으로 나눌 수 있습니다.
아래 음영 부분은 댓글입니다.
1. 드라이버 로딩 부분
static int __init usb_mouse_init(void)
{
int retval = usb_register(&usb_mouse_driver);/ /마우스 드라이버 등록
if (retval == 0)
info(DRIVER_VERSION ":" DRIVER_DESC);
return retval;
}
usb_mouse_driver의 정의는 다음과 같습니다:
static struct usb_driver usb_mouse_driver = {
.owner = THIS_MODULE,
.name = "usbmouse",
.probe = usb_mouse_probe,
.disconnect = usb_mouse_disconnect,
.id_table = usb_mouse_id_table,
};
등록이 성공하면 usb_mouse_probe가 호출됩니다. 그러면 언제 등록이 성공한 것으로 간주됩니까?
다른 드라이버 등록 프로세스와 유사하게, 해당 "버스"에서 일치하는 "장치"가 발견된 경우에만 프로브가 호출됩니다. 버스 일치 방법은 특정 버스와 관련이 있습니다. 예를 들어 platform_bus_type은 드라이버 이름과 플랫폼 장치 이름이 동일한지 확인합니다. USB 버스 일치 방법을 확인하는 방법은 무엇입니까?
USB 장치는 usb_bus_type 버스에 등록됩니다. usb_bus_type의 일치 방법을 참조하세요.
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.hotplug = usb_hotplug,
static int usb_device_match (struct device *dev, struct device_driver *drv)
{
struct usb_interface *intf;
struct usb_driver *usb_drv;< / p>
const struct usb_device_id *id;
/* 어떤 장치와도 일치하지 않는 일반 드라이버를 확인합니다. */
if (drv == &usb_generic_driver )
0 반환;
intf = to_usb_interface(dev);
usb_drv = to_usb_driver(drv);
id = usb_match_id ( intf , usb_drv->id_table);
if (id)
1을 반환;
0을 반환;
}
USB의 매칭 방식은 usb_match_id(intf, usb_drv->id_table), 즉 "dev의 intf 정보"와 "usb_drv->id_table 정보"를 비교하여 일치하면, 이는 드라이버가 해당 장치에 해당한다는 의미입니다. 장치가 버스에 추가되었으므로 USB 장치 드라이버를 등록하기 위해 drv의 프로브 메서드가 호출됩니다.
usb_mouse_id_table은 다음과 같이 정의됩니다:
static struct usb_device_id usb_mouse_id_table[] = {
{ USB_INTERFACE_INFO(3, 1, 2) },
{ } /* 항목 종료 */
};
#define USB_INTERFACE_INFO(cl,sc,pr) /
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, /
.bInterfaceClass = (cl), /
.bInterfaceSubClass = (sc), /
.bInterfaceProtocol = (pr)
마우스 장치는 USB HID(휴먼 인터페이스 장치)를 준수합니다. 마우스 인터페이스 클래스 코드는 HID 사양에 다음과 같이 지정됩니다.
인터페이스 클래스: 0x03
인터페이스 하위 클래스: 0x01
인터페이스 프로토콜: 0x02
이 분류의 장점은 장치 제조업체가 표준 드라이버를 직접 사용할 수 있다는 것입니다.
HID 클래스 외에도 대용량 저장소, 프린터, 오디오 등도 있습니다.
#define USB_DEVICE_ID_MATCH_INT_INFO /
(USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
일치 프로세스는 다음과 같습니다:
usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_host_interface *intf;
struct usb_device * dev;
/* devio.c의 proc_connectinfo는 id == NULL로 우리를 호출할 수 있습니다. */
if (id == NULL)
return NULL ;
intf = 인터페이스->cur_altsetting;
dev = 인터페이스_to_usbdev(인터페이스);
/* 해당 ID를 확인하는 것이 중요합니다. ->driver_info는 0이 아닙니다.
0이 아닌 항목을 제외하고는 모두 0인 항목이므로
id->driver_info는 다음과 같은 항목을 생성하는 방법입니다.
드라이버가 모든
장치와 인터페이스를 검사하려고 함을 나타냅니다. */
for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
id->driver_info; id++) {
if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
id->idVendor != le16_to_cpu(dev-> descriptor.idVendor))
계속;
if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
id->idProduct != le16_to_cpu(dev-> descriptor.idProduct))
계속;
/* 0은 부호 없는 숫자보다 크지 않으므로 id->bcdDevice_lo != 0을 테스트할 필요가 없습니다. */
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
(id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
계속;
p>if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
(id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
계속;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
(id->bDeviceClass != dev->descriptor.bDeviceClass))
계속;
p>
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
(id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
계속;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
계속;
// 인터페이스 클래스
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
(id->bInterfaceClass != intf->desc.bInterfaceClass))
계속 ;
//인터페이스 하위 클래스
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
(id->bInterfaceSubClass != intf ->desc.bInterfaceSubClass))
continue;
//따라야 할 프로토콜
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
( id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
계속;
return id;
}
return NULL ;
}
장치의 인터페이스 클래스, 인터페이스 하위 클래스 및 인터페이스 프로토콜이 일치하는 경우에만 마우스 드라이버가 프로브 메서드를 호출하는 것을 볼 수 있습니다. 마우스 드라이버.