USB mouse Device driver simple implementation (i)

Source: Internet
Author: User


one, Linux under the USB driver

Separation and tiering is the most basic form of driver development in Linux, USB drive development in the host side mainly involved in two parts: Host controller driver and device driver.

Host controller driver is mainly related to the specific SOC, it is to identify the USB device, install the corresponding device driver, to provide access to the USB device read and write functions.

The device driver is mainly based on the specific USB device to the USB host driver to provide the data obtained by processing, to achieve this type of USB device-specific functions. The specific hierarchy looks like this:


Basic Development environment:

Operating system: Ubuntu12.04

Kernel: Linux-3.0.86

gui:qtopia2.2.0

Cross-compilation tool GCC version: 4.5.1


implementation of USB mouse device driver

This part mainly completes the function is: realizes a simple USB mouse device driver, reads the mouse to carry on the operation the raw data which produces.

1. Preparation work

The default in the Linux kernel has been configured with USB mouse-related driver, so in order to write their own driver can be loaded into the kernel and use, first to remove the kernel of the USB mouse drive. Go to the kernel directory, execute make menuconfig, and perform the following configuration:

-> Device Drivers
	-> HID Devices
	[]usb Human Interface Device (full HID) support
2. Device driver Writing

A, assign, set up, register a USB_DRIVER structure variable, in order to facilitate the definition of the following structure:

/* Define a structure that describes USB
/struct Yl_usbmouse {
	dma_addr_t Usb_buf_phys;	/* Describes the physical address of the allocated buffer *
	/char *usb_buf_virt;		/* Describes the virtual address of the allocated buffer *
	/int usb_buf_len;		/* Used to describe the size of the buffer * *
	struct URB *urb;		/* Describe the USB request block
/};
Define a USB_DRIVER structure and set it:

/* Define a usb_driver struct variable/
static struct Usb_driver yl_usb_mouse_driver = {
	. Name		= "Yl_usbmouse",
	. Probe		= Yl_usb_mouse_probe,
	. Disconnect	= Yl_usb_mouse_disconnect,
	. id_table	= yl _usb_mouse_id_table,
};

Register this structure in the entry function:

/* Module entry function
/static int __init yl_usb_mouse_init (void)
{/	
	* Register a USB_DRIVER structure variable * *
	usb_register (&yl_usb_mouse_driver);
	return 0;
}
b, assigning, setting, initializing, submitting a urb,urb is used to pass USB host controller-driven data. When the inserted device matches this usb_driver, its probe function will be invoked, and we can implement some of the URB's column operations in the probe function.

Assign a URB:

* 1, assign a USB request block * *
g_yl_usbmouse.urb = usb_alloc_urb (0, Gfp_kernel);
Set, initialize this URB:

/* Get an endpoint of USB device * *
pipe = usb_rcvintpipe (dev, endpoint->bendpointaddress);

/* Get the length of the transmitted data * *
G_yl_usbmouse.usb_buf_len = endpoint->wmaxpacketsize;

/* Allocate a buffer to store the USB mouse data
/g_yl_usbmouse.usb_buf_virt = usb_alloc_coherent (Dev, G_yl_usbmouse.usb_buf_len, gfp_ ATOMIC, &g_yl_usbmouse.usb_buf_phys);

/* 2, initialize this USB request block * *
usb_fill_int_urb (g_yl_usbmouse.urb, Dev, pipe, g_yl_usbmouse.usb_buf_virt, G_YL_USBMOUSE.USB _buf_len, Yl_usbmouse_irq, NULL, endpoint->binterval);
G_YL_USBMOUSE.URB->TRANSFER_DMA = G_yl_usbmouse.usb_buf_phys;
G_yl_usbmouse.urb->transfer_flags |= Urb_no_transfer_dma_map;
Submit this URB:

* 3, submit this USB request block * *
usb_submit_urb (g_yl_usbmouse.urb, Gfp_kernel); 	
c, USB mouse to get data interrupt processing function, this function is in the initialization of the URB pass in the callback function, the mouse occurs when the action will touch the function of the call, the mouse data passed in. Its specific implementation is shown below:

/* USB mouse Interrupt processing function
/static void Yl_usbmouse_irq (struct urb *urb)
{
	int i = 0;

	/* Print out the data in turn * *
	PRINTK ("Yl_usbmouse data:");
	for (i = 0; i < G_yl_usbmouse.usb_buf_len i++)
	{
		printk ("0x%x", G_yl_usbmouse.usb_buf_virt[i]);
	PRINTK ("\ n");

	/* Resubmit URB
	/usb_submit_urb (g_yl_usbmouse.urb, gfp_atomic);
}

This function is simple to implement: the original data produced by the mouse to print to the terminal can be.

3, compile and install the driver, on the Development Board to connect the mouse experiment results are as follows:


The

shows from above that each operation of the mouse produces 7 bytes of data at a time. It can be seen that the data itself is just some ordinary data, no meaning, that how to let the mouse generated these data to play a role, you need to use the USB mouse and input subsystem, in order to really play the role of the USB mouse. See below for concrete implementation.


Appendix: The complete example in this article routines code looks like this:

#include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/ init.h> #include <linux/usb/input.h> #include <linux/hid.h>/* Defines a structure that describes USB/struct Yl_usbmouse {Dma_	addr_t Usb_buf_phys;		/* Describes the physical address of the allocated buffer */char *usb_buf_virt;		/* Describes the virtual address of the allocated buffer */int usb_buf_len;		/* Used to describe the size of the buffer * * struct URB *urb;

/* Describe the USB request block/};

/* Define a variable/static struct Yl_usbmouse g_yl_usbmouse that describes the USB structure;

	/* USB mouse Interrupt processing function/static void Yl_usbmouse_irq (struct urb *urb) {int i = 0;
	/* Print out the data in turn * * PRINTK ("Yl_usbmouse data:");
	for (i = 0; i < G_yl_usbmouse.usb_buf_len i++) {PRINTK ("0x%x", G_yl_usbmouse.usb_buf_virt[i));

	} printk ("\ n");
* * Submit URB * * USB_SUBMIT_URB (G_YL_USBMOUSE.URB, gfp_atomic) again; }/* The probe function invoked when the matching device succeeds */static int yl_usb_mouse_probe (struct usb_interface *intf, const struct usb_device_id *id) {Struc
	T Usb_device *dev = Interface_to_usbdev (intf);
	struct Usb_host_interface *interface; struct USB_ENDPOINT_Descriptor *endpoint;

	int pipe;
	/* Get interface and endpoint information * * interface = intf->cur_altsetting;

	Endpoint = &interface->endpoint[0].desc;

	/* Get an endpoint of USB device * * pipe = usb_rcvintpipe (dev, endpoint->bendpointaddress);

	/* Get the length of the transmitted data * * G_yl_usbmouse.usb_buf_len = endpoint->wmaxpacketsize; /* Allocate a buffer to store the USB mouse data/g_yl_usbmouse.usb_buf_virt = Usb_alloc_coherent (Dev, G_yl_usbmouse.usb_buf_len, gfp_atomic,

	&g_yl_usbmouse.usb_buf_phys);

	* 1, assign a USB request block * * G_yl_usbmouse.urb = usb_alloc_urb (0, Gfp_kernel); /* 2, initialize this USB request block * * USB_FILL_INT_URB (g_yl_usbmouse.urb, Dev, pipe, g_yl_usbmouse.usb_buf_virt, g_yl_usbmouse.usb_buf_
	Len, Yl_usbmouse_irq, NULL, Endpoint->binterval);
	G_YL_USBMOUSE.URB-&GT;TRANSFER_DMA = G_yl_usbmouse.usb_buf_phys;

	G_yl_usbmouse.urb->transfer_flags |= Urb_no_transfer_dma_map; 	

	* 3, submit this USB request block * * USB_SUBMIT_URB (g_yl_usbmouse.urb, Gfp_kernel);
return 0;
}/* The function called when the USB device is pulled out/static void Yl_usb_mouse_disconnect (struct usb_interface *intf) {	struct Usb_device *dev = Interface_to_usbdev (intf);
	Usb_kill_urb (G_YL_USBMOUSE.URB);

	Usb_free_urb (G_YL_USBMOUSE.URB);
Usb_free_coherent (Dev, G_yl_usbmouse.usb_buf_len, G_yl_usbmouse.usb_buf_virt, G_yl_usbmouse.usb_buf_phys); /* Defines an array of id_table to compare and judge when USB devices are plugged in/static struct usb_device_id yl_usb_mouse_id_table [] = {{Usb_interface_info (

Usb_interface_class_hid, Usb_interface_subclass_boot, Usb_interface_protocol_mouse)}, {}/* Terminating entry */}; /* Define a usb_driver struct variable/static struct Usb_driver yl_usb_mouse_driver = {. Name = "Yl_usbmouse",. Probe = Yl_usb_mo

Use_probe,. Disconnect = Yl_usb_mouse_disconnect,. id_table = yl_usb_mouse_id_table,}; /* Module Entry function */static int __init yl_usb_mouse_init (void) {/* Register a USB_DRIVER structure variable/usb_register (&yl_usb_mouse_dri
	ver);
return 0; }/* Module export function/static void __exit yl_usb_mouse_exit (void) {/* unregister a usb_driver struct variable/usb_deregister (&yl_usb_mou
Se_driver);
} module_init (Yl_usb_mouse_init); ModulE_exit (Yl_usb_mouse_exit); Module_license ("GPL");




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.