1. Trang chủ
  2. » Luận Văn - Báo Cáo

Đề tài viết driver cho thiết bị USB mouse

21 1,1K 11

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 21
Dung lượng 917,94 KB

Nội dung

Ví dụ: thẻ nhớ USB, máy in. Truyền đẳng thời Isochronous transfer: sử dụng cho các thiết bị cần truyền một lượng dữ liệu lớn với tốc độ rất nhanh, đảm bảo ràng buộc về thời gian thực tu

Trang 1

BÁO CÁO

BÀI TẬP LỚN HỆ ĐIỀU HÀNH

Đề tài: Viết driver cho thiết bị USB mouse.

Nhóm sinh viên thực hiện: Nhóm 04 – K55 Thành viên: Nguyễn Trí Đức 20102634 Nguyễn Xuân Sỹ 20102115

Lý Đức Vượng 20102591

Hà Nội ngày 02 tháng 05 năm 2014

Trang 2

Mục lục

Viết driver cho thiết bị USB mouse

1. Tổng quan về Chuẩn USB

1.1 Chuẩn tín hiệu

Chuẩn USB sử dụng 4 đường tín hiệu trong đó có hai đường cấp nguồn DC (VBUS-5V và GND), hai đường còn lại là một cặp tín hiệu vi sai (D+ và D)cho phép truyền dữ liệu Cặp dây tín hiệu này được nối xoắn ở bên trong,

có khả năng chống nhiễu tốt

Hình 1 Sơ đồ usb

1.2 Mô hình phân cấp

Trang 3

Hình 2.Mô hình phân cấp

Các thiết bị hoạt động theo chuẩn USB được kết nối với nhau theo đồ hình mạng hình sao phân cấp Trung tâm của mỗi hình sao này là các Hub

USB Host: thiết bị đóng vai trò điều khiển toàn bộ mạng USB.

Ví dụ như trên máy tính, USB Host được gắn trên mainboard Để giao tiếp

và điều khiển các USB device, USB Host controller cần được thiết kế tích hợp với USB RootHub (Hub mức cao nhất)

Vai trò:

Trao đổi dữ liệu với các USB Device

Điều khiển USB Bus

- Quản lý các thiết bị cắm vào hay rút ra khỏi Bus USB qua quá trình liệt kê (Enumeration)

- Quản lý luồng dữ liệu trên Bus, đảm bảo các thiết bị đều có cơ hội trao đổi dữ liệu tùy thuộc vào cấu hình của mỗi thiết bị

USB Device: là các thiết bị đóng vai trò như các slave giao tiếp với USB

Host Các thiết bị này đóng vai trò bị động, không được tự ý gửi gói tin lên

Trang 4

USB Host hay gửi gói tin giữa các USB Device với nhau, tất cả đều phải thông qua quá trình điều phối của USB Host.

Chức năng của thiết bị USB Device:

• Trao đổi dữ liệu với USB Host

• Phát hiện gói tin hay yêu cầu từ USB Host theo giao thức USB

USB Hub: đóng vai trò như các Hub trong mạng Ethernet Cấp nguồn cho các

tả (Description) của USB Device, từ đó thiết lập địa chỉ (NodeID) và chế độ hoạt động tương ứng cho thiết bị USB Device Các địa chỉ sẽ được đánh từ 1->126 nên về lý thuyết, chuẩn USB cho phép kết nối

126 thiết bị vào đường Bus Khi thiết bị rút ra khỏi đường Bus, địa chỉ này sẽ được thu hồi

Trang 5

Hình 3 quá trình liệt kê

Quá trình truyền dữ liệu: để hiểu quá trình truyền dữ liệu này, ta

phải hiểu được hai khái niệm quan trọng nhất trong chuẩn USB, đó

là khái niệm Interface và Endpoint (chỉ USB device có Endpoint,USB Host không có) Một thiết bị USB sẽ có thể có nhiều Interface,một Interface có thể sử dụng nhiều Endpoint

Ví dụ:

 Thẻ nhớ USB chỉ sử dụng 1 Interface theo chuẩn USB Mass storage,interface này sử dụng 3 Endpoint

Trang 6

 Bộ USB 3G sử dụng các Interface khác nhau như: CD Room, Massstorage và Communication, mỗi interface lại sử dụng nhiều Endpointkhác nhau.

-Endpoint cũng như các Port trong chuẩn TCP/IP đóng vai trò như các bộđệm truyền/nhận dữ liệu Nhờ việc sử dụng nhiều bộ đệm mà các quá trìnhtruyền thông được tiến hành song song và cho tốc độ cao hơn, bên cạnh đó giúpcho việc phân tách các dịch vụ khác nhau Với chuẩn USB, các thiết bị đượcthiết kế với tối đa là 16 Enppoint Các Endpoint được phân loại theo hướngtruyền dữ liệu nhìn từ phía USB Host Cụ thể:

• Các Endpoint truyền dữ liệu từ USB Device tới USB Host làendpoint IN

• Các Endoint truyền dữ liệu từ USB Host tới USB Device là endpointOUT

-Các thông tin cấu hình của một thiết bị USB hoạt động với 1 Interface,Interface này sử dụng hai Endpoint (0x01 và 0x82), 1 Endpoint In và mộtEndpoint Out, cả hai Endpoint hoạt động ở chế độ Bulk Transfer Trên Linux,

ta có thể dùng lệnh lsusb để xem các thông tin này với bất cứ thiết bị USB nàocắm vào Bus

Trang 7

1.4 Chế độ truyền

Chuẩn USB cung cấp 4 chế độ truyền:

Truyền điều khiển (Control transfer): là chế độ truyền được tất cả các

thiết bị USB hỗ trợ để truyền các thông tin điều khiển với tốc độ tươngđối chậm

Truyền ngắt (Interrupt transfer): sử dụng cho các thiết bị cần truyền

một lượng dữ liệu nhỏ, tuần hoàn theo thời gian ví dụ như chuột, bàn phím Khi đó, ví dụ cứ 10s một lần USB Host sẽ gửi request xuống và USB Device sẽ trả dữ liệu về cho USB Host (với trường hợp Interrupt

In Endpoint)

Truyền theo khối (Bulk transfer): sử dụng cho các thiết bị cần truyền

một lượng dữ liệu lớn, yêu cầu độ chính xác tuyệt đối, không có ràng

Trang 8

buộc quá chặt chẽ về thời gian thực (tương tự giao thức TCP/IP trong mạng Ethernet) Ví dụ: thẻ nhớ USB, máy in.

Truyền đẳng thời (Isochronous transfer): sử dụng cho các thiết bị cần

truyền một lượng dữ liệu lớn với tốc độ rất nhanh, đảm bảo ràng buộc

về thời gian thực tuy nhiên chấp nhận hy sinh độ chính xác ở một mức nhất định như các thiết bị nghe nhạc, xem phim kết nối theo chuẩn USB (tương tự giao thức UDP trong mạng Ethernet)

2. Quy trình viết device driver trên Linux

2.1 Mô hình phân lớp hệ thống usb trên linux

Tầng USB Device Drivers nằm giữa 2 tầng: USB Core và các hệ thống con khác nhau của nhân (Kernel Subsystems) như: hệ thống con thiết bị kiểu khối (Block), hệ thống con thiết bị kiểu kí tự (Char), hệ thống con thiết bị đầu vào (Input)

USB Core do nhân hệ điều hành Linux cung cấp, với các API (Application Programming Interface) nhằm hỗ trợ các thiết bị USB và USB Host Controller.Vai trò: USB Core là trừu tượng hóa tất cả các phần cứng và các thành phầnphụ thuộc thiết bị

Trang 9

Các USB Device Driver sử dụng các tham số của tầng USB Core, không cần quan tâm tới các nền tảng phần cứng khác nhau.

USB Device Driver xuất ra các API lên tầng trên Tùy theo thiết bị có thể được xếp vào các lớp con như lớp vào dữ liệu (Input), lớp âm thanh (Sound), lớp bộ nhớ (memory) mà Driver có thể xuất ra các API khác nhau

Các ứng dụng người dùng khi muốn giao tiếp với thiết bị phần cứng sẽ sử dụng các API này để yêu cầu USB Device Driver thực hiện:

USB core tham số hóa thiết bị để USB device dirver có thể làm việc được với mọi thiết bị có chuẩn USB USB device driver lái luồng dữ liệu, luồngđiều khiển để hardware và application bên trên có thể liên lạc với nhau một cách chính xác

2.2 Danh sách thiết bị điều khiển bởi usb

Khi viết một USB Driver người lập trình viên cần chỉ định xem Driver này

sẽ được sử dụng cho các thiết bị hoặc các lớp thiết bị nào Cấu trúc

usb_device_id cung cấp một kiểu thiết bị, nó có thể là một thiết bị cụ thể cũng

có thể là một lớp thiết bị Có một số macro để khởi tạo cấu trúc này

Ví dụ: Sử dụng macro USB_DEVICE (vendor, product) để tạo ra một cấu trúc usb_device_id với IDvendor và IDproduct

Sau khi đã tạo ra một cấu trúc usb_device_id ta cần phải khai báo cấu trúc này với USB Core, để làm việc này ta sử dụng macro

Trang 10

2.3 Khai báo cấu trúc dữ liệu thiết bị

Trong quá trình thăm dò thiết bị, có rất nhiều thông tin về thiết bị ta truy nhập được và cần phải lưu lại để sử dụng về sau Các thông tin cần thiết bao gồm: thiết bị cụ thể (được xác định bởi cấu trúc usb_device), thông tin các Configuration, Interface, Endpoint của thiết bị Tùy theo đặc điểm của từng phần cứng cụ thể mà ta định nghĩa một cấu trúc dữ liệu phù hợp

2.4 Đăng ký và hủy đăng ký usb Device Driver

Để tầng USB Core có thể nhận ra Driver, lập trình viên cần phải đăng kí Driver đó Sử dụng hàm sau để làm việc này:

usb_register(struct usb_driver &);

Hàm này thường được gọi trong hàm khởi tạo mô-đun Driver đang

viết.Tham số cần truyền cho hàm này là một con trỏ tới cấu trúc usb_driver Cấu trúc này bao gồm các thông tin về Driver đang viết Cấu trúc này được định nghĩa như sau:

struct usb_driver {

const char * name;

int (* probe) (struct usb_interface *intf, const struct usb_device_id *id); void (* disconnect) (struct usb_interface *intf);

int (* ioctl) (struct usb_interface *intf, unsigned int code, void *buf); int (* suspend) (struct usb_interface *intf, pm_message_t message); int (* resume) (struct usb_interface *intf);

int (* reset_resume) (struct usb_interface *intf);

int (* pre_reset) (struct usb_interface *intf);

int (* post_reset) (struct usb_interface *intf);

const struct usb_device_id * id_table;

struct usb_dynids dynids;

Trang 11

struct usbdrv_wrap drvwrap;

unsigned int no_dynamic_id:1;

unsigned int supports_autosuspend:1;

};

Các thông tin quan trọng gồm:

 Const char* name : tên của Driver

 Const struct usb_device_id* id_table : con trỏ tới bảng chứa các thiết

bị sẽ được điều khiển bởi Driver này và đã được khai báo bằng macroMODULE_DEVICE_TABLE()

 int (*probe) (struct usb_interface *intf, const struct usb_device_id* id) : đây là một tham số rất quan trọng Tham số này là một con trỏ tới một hàm (hàm thăm dò), hàm này sẽ được gọi khi thiết bị được kết nối tới hệ thống Trong hàm này ta sẽ thực hiện các công việc quan trọng như xác định các Endpoint, cấp phát bộ nhớ

 void (*disconnect) (struct usb_interface* intf) : Một con trỏ tới một hàm (hàm ngắt kết nối), hàm này sẽ được gọi khi thiết bị được gỡ bỏ

ra khỏi hệ thống Trong hàm này lập trình viên cần phải thực hiện công tác dọn dẹp hệ thống như giải phóng bộ nhớ, hủy các công việc đang dở dang…

Để hủy đăng kí một USB Device Driver ra khỏi hệ thống, ta sử dụng hàm sau:

usb_deregister(struct usb_driver &);

Hàm này thường được gọi trong hàm kết thúc mô-đun Driver đang viết

2.5 Thăm dò thiết bị

Khi thiết bị mới được kết nối tới hệ thống, nếu Driver được chỉ định cho điều khiển thiết bị đó thì hàm thăm dò của Driver sẽ được gọi USB Core truyền tới hàm thăm dò một con trỏ tới cấu trúc usb_interface mô tả Interface được chọn trên thiết bị

Trong hàm thăm dò, Driver cần thực hiện một số công việc sau:

Trang 12

 Lấy ra địa chỉ các Endpoint cần dùng, lấy ra kích thước các bộ đệm cho thiết bị.

 Cấp phát bộ đệm

 Lưu lại các thông tin (địa chỉ Endpoint, kích thước bộ đệm, địa chỉ

bộ đệm…)

 Đăng kí lớp thiết bị cho Driver

 Truy cập các thông tin Endpoint

 Lưu lại các thông tin đã truy cập và cấp phát

Để lưu trữ các dữ liệu liên quan tới thiết bị nhằm mục đích sử dụng sau, ta sử dụng hàm sau:

usb_set_intfdata(intf, dev);

Trong đó dev là con trỏ tới cấu trúc dữ liệu ta cần lưu trữ

 Đăng ký lớp thiết bị

Như ta đã thấy trong mô hình phân lớp của hệ thống USB trên

Linux, phía trên lớp USB Device Driver là lớp Các hệ thống con nhân Linux (hay Các lớp thiết bị), bao gồm: Char, Block, TTY, Mem… Các thiết bị USB có thể được đối xử theo một trong các hệ thống con đó, chẳng hạn như chuột, bàn phím có thể coi như thuộc lớp Input Tức là các ứng dụng người dùng sẽ sử dụng các API lớp Input để thực hiện giao tiếp với chuột, bàn phím Do đó Driver cũng cần đăng kí thực hiện đăng kí lớp thiết bị mà nó quản lý Tùy theo từng lớp có các hàm đăng

kí khác nhau:

2.6 Hàm ngắt kết nối thiết bị

Khi thiết bị được gỡ bỏ ra khỏi hệ thống, hàm ngắt kết nối được gọi

Nguyên mẫu hàm như sau:

void (*disconnect) (struct usb_interface* intf);

2.7 Hàm mở, đọc, ghi thiết bị

 Mở thanh ghi

Mã code: static int mydevice_open(struct inode *inode, struct file *file);Hành động này có tác dụng chuẩn bị cho các hành động đọc, ghi sau đó Trong hàm này ta sử dụng hàm usb_get_intfdata() để lấy ra các thông tin

Trang 13

liên quan tới thiết bị đã lưu trữ từ hàm probe() (bằng hàm usb_set_intfdata), thiết lập dữ liệu này cho cấu trúc file.

 Đọc thanh ghi

Mã code: static ssize_t mydevice_read(struct file *file, char user

*buffer, size_t count, loff_t *ppos);

Hàm này có hai việc chính, đầu tiên là tạo ra các URB (USB request block) yêu cầu dữ liệu và xác nhận nó tới tầng USB Core, thứ hai là chuyển

dữ liệu nhận được từ các URB sang không gian người dùng bằng hàm:unsigned long copy_to_user(void user * to, const void * from,

unsigned long size);

 Ghi thanh ghi

Mã code :static ssize_t my_device write(struct file *file, const char user *buffer, size_t count, loff_t *ppos);

Hàm này sẽ thực hiện hai công việc ngược lại với hàm đọc Đầu tiên nó phải chuyển dữ liệu từ không gian người dùng sang không gian nhân hệ điều hành, sau đó nó cần đóng gói dữ liệu này trong các URB và xác nhận các URB này tới tầng USB Core

Để copy dữ liệu người dùng vào không gian nhân, ta sử dụng hàm:

unsigned long copy_from_user(void * to, const void user * from, unsigned long size);

2.8 Đăng ký drive cho usb

Việc xây dựng driver này cũng giống như bất kỳ một driver thiết bị nào khác trên Linux, cần sử dụng một khuôn mẫu chung (có hàm tạo, hàm hủy).USB device driver cần thực hiện công việc tương ứng với lớp giao thức USB core; và thay vì cung cấp giao diện lên tầng người dùng (user space)

giống như file thiết bị thì ở đây, usb driver cần thực hiện kết nối đến thiết bị thật trong tầng phần cứng (hardware-space)

Các hàm API của tầng USB core để thực hiện đăng ký và hủy đăng ký thiết

bị như sau (nằm trong tệp tiêu đề <linux/usb.h>):

Trang 14

int usb_register(struct usb_driver *driver);

void usb_deregister(struct usb_driver *);

Cấu trúc usb_driver chứa các trường cung cấp tên driver, bảng ID để dò thiết bị tự động, và 2 hàm callback được gọi bởi USB core trong quá trình kết nối thiết bị (hot plugging) và ngắt kết nối thiết bị (hot removal)

3. Quá trình build trên linux (ubuntu 12.04)

Mục đích build ra file file ko để cài đặt driver mouse

Quá trình buil file ko(kenal object)

Thư mục build file ko

Cài đặt file ko

4. Code driver mouse

Code : driver_mouse.c

Trang 15

#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"

#define DRIVER_DESC "USB HID Boot Protocol mouse driver"

struct usb_device *usbdev;

struct input_dev *dev;

struct urb *irq;

signed char *data;

struct usb_mouse *mouse = urb->context;

signed char *data = mouse->data;

struct input_dev *dev = mouse->dev;

input_report_key(dev, BTN_LEFT, data[0] & 0x01);

input_report_key(dev, BTN_RIGHT, data[0] & 0x02);

input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);

input_report_key(dev, BTN_SIDE, data[0] & 0x08);

input_report_key(dev, BTN_EXTRA, data[0] & 0x10);

input_report_rel(dev, REL_X, data[1]);

input_report_rel(dev, REL_Y, data[2]);

input_report_rel(dev, REL_WHEEL, data[3]);

Trang 16

struct usb_mouse *mouse = input_get_drvdata(dev);

printk(KERN_INFO "Something important happened here 14 \n");

struct usb_device *dev = interface_to_usbdev(intf);

struct usb_host_interface *interface;

struct usb_endpoint_descriptor *endpoint;

struct usb_mouse *mouse;

struct input_dev *input_dev;

int pipe, maxp;

int error = -ENOMEM;

pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);

Trang 17

strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));

usb_make_path(dev, mouse->phys, sizeof(mouse->phys));

strlcat(mouse->phys, "/input0", sizeof(mouse->phys));

input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);

struct usb_mouse *mouse = usb_get_intfdata (intf);

printk(KERN_INFO "Something important happened here 17 \n"); usb_set_intfdata(intf, NULL);

if (mouse) {

usb_kill_urb(mouse->irq);

input_unregister_device(mouse->dev);

usb_free_urb(mouse->irq);

Trang 18

usb_buffer_free(interface_to_usbdev(intf), 8, >data,

MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);

static struct usb_driver usb_mouse_driver = {

Ngày đăng: 25/04/2015, 07:54

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w