Tải bản đầy đủ (.pdf) (24 trang)

Viết driver chuột usb cho Linux

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (786.68 KB, 24 trang )

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ - VIỄN THƠNG

BÁO CÁO BÀI TẬP LỚN
Mơn: Hệ điều hành
Đề tài:

Viết driver chuột usb cho Linux

Giảng viên hướng dẫn:

TS. Phạm Doãn Tĩnh

Họ và tên

MSSV

Nguyễn Hữu Phúc

20167332

Đào Tiến Thành

20163695

Võ Sinh Hiển

20161430

Hoàng Đức Mạnh


20162642

Nguyễn Văn Đường

20150983
Hà Nội, 6/202
1


LỜI MỞ ĐẦU
Trong lĩnh vực lập trình hệ thống nhúng, một trong những công việc quan trọng nhất
với chúng ta đó chính là lập trình ghép nối, điều khiển các module, các thiết bị ngoại vi
ghép nối với hệ trung tâm. Để có thể làm được việc này, ngồi các kỹ năng lập trình chúng
ta cịn cần phải thành thạo về các giao thức ghép nối phổ biến như RS232, SPI, I2C. Đặc
biệt, chuẩn giao tiếp USB đã trở thành chuẩn kết nối cũng như phương thức truyền dữ liệu
thân thuộc với người dùng công nghệ nhờ vào sự thuận tiện, độ bền và giá thành hợp lý của
nó và có thể nói nó là một trong các chuẩn phổ biến nhất hiện nay. Tìm hiểu chuẩn USB sẽ
giúp cho chúng ta có kiến thức để có thể làm được rất nhiều cơng việc như:


Thiết kế, chế tạo thiết bị hoạt động theo chuẩn USB



Viết driver cho thiết bị giao tiếp theo chuẩn USB



Lập trình ghép nối với các thiết bị làm việc theo chuẩn USB


Trong phạm vi bài tập lớn môn hệ điều hành, chúng em quyết định chọn đề tài “Viết
driver chuột theo chuẩn USB HID cho hệ điều hành Linux” với mong muốn biết được cách
xây dựng một driver cho hệ điều hành, tìm hiểu phương thức giao tiếp của hệ điều hành với
thiết bị USB cũng như tìm hiểu hoạt động của giao tiếp USB.
Chúng em xin cảm ơn thầy Phạm Doãn Tĩnh đã cung cấp cho chúng em kiến thức cần
thiết, để chúng em hoàn thành bài tập lớn môn hệ điều hành. Mặc dù driver device viết ra
còn khá đơn sơ nhưng thời gian và kiến thức có hạn nên chúng em chỉ hồn thành được
một số tiêu chí nhất định. Từ lạ khi lần đầu sử dụng hệ điều hành Ubuntu đến khi kết thúc
học phần chúng em đã có những kiến thức cơ bản để biến Linux công cụ hỗ trợ đắc lực
trong quá trình học tập và làm việc.
Chúng em xin cảm ơn!
Nhóm 11

2


MỤC LỤC
1

2

Khái quát về giao thức USB ........................................................................................ 5
1.1

Các thành phần cơ bản của giao thức USB ............................................................ 6

1.2

Mơ hình giao thức USB.......................................................................................... 9


1.2.1

Chuẩn tín hiệu.................................................................................................. 9

1.2.2

Mơ hình mạng................................................................................................ 10

1.2.3

Kịch bản hoạt động ........................................................................................ 11

USB driver ................................................................................................................. 12
2.1

Tìm hiểu USB driver ............................................................................................ 12

2.2

Xây dựng driver cho chuột USB .......................................................................... 15

3

Chạy chương trình và kiểm tra kết quả ...................................................................... 21

4

KẾT LUẬN ............................................................................................................... 24

3



DANH MỤC HÌNH ẢNH
Hình 1.1. Tổng quan về lớp USB device ............................................................................. 5
Hình 1.2. Tổng quan về lớp USB driver .............................................................................. 6
Hình 1.3. Cấu trúc dữ liệu của endpoint .............................................................................. 7
Hình 1.4. Cấu trúc dữ liệu interface..................................................................................... 8
Hình 1.5. Mơ hình cáp USB ................................................................................................ 9
Hình 1.6. Mơ hình host – devices của USB ....................................................................... 10
Hình 2.1. Thơng tin thiết bị ............................................................................................... 14
Hình 2.2. Thư viện linux được dùng trong chương trình................................................... 15
Hình 2.3. Khởi tạo cấu trúc cho driver .............................................................................. 15
Hình 2.4. Khai báo mã thiết bị ........................................................................................... 16
Hình 2.5. Cấu trúc hàm ngắt .............................................................................................. 16
Hình 2.6. Đăng kí driver với kernel ................................................................................... 17
Hình 2.7. Hủy đăng ki driver với kernel ............................................................................ 17
Hình 2.8. Cấu trúc hàm pen_probe .................................................................................... 18
Hình 2.9. Cấu trúc hàm ngắt .............................................................................................. 19
Hình 2.10. Cấu trúc hàm file_operations ........................................................................... 19
Hình 3.1. Thơng tin thiết bị trong kernel ........................................................................... 21
Hình 3.2. Kết quả đăng kí driver ....................................................................................... 22
Hình 3.3. Thơng tin thiết bị sau khi đổi driver .................................................................. 22
Hình 3.4. Kết quả chương trình test ................................................................................... 23
Hình 3.5. Kết quả sau khi gỡ driver ................................................................................... 23

4


Khái quát về giao thức USB
Universal serial bus (USB) là một kết nối giữa 1 máy tính chủ và một vài thiết bị

ngoại vi. Ban đầu nó được tạo ra để thay thế một loạt các loại bus chậm khác-các kết nối
song song nối tiếp, bàn phím-với một kiểu bus duy nhất mà tất cả các thiết bị có thể kết nối
tới.
Một thiết bị giao tiếp bằng chuẩn USB thực ra rất phức tạp. Nhưng may mắn là hệ
điều hành Linux cung cấp cho ta những thư viện hỗ trợ khá đầy đủ, và điều đó đã giúp tiết
kiệm được rất nhiều thời gian, cơng sức cũng như chi phí xây dựng một thiết bị như thế.
Đa phần sự phức tạp của USB được hỗ trợ bởi USB Core của Linux.

Hình 1.1. Tổng quan về lớp USB device

Trình điều khiển USB nằm giữa các hệ thống con kernel khác nhau (khối, mạng, char,
v.v.) và bộ điều khiển phần cứng USB. Lõi USB cung cấp giao diện cho trình điều khiển
USB sử dụng để truy cập và điều khiển phần cứng USB mà không phải lo lắng về các loại
bộ điều khiển phần cứng USB khác nhau có trên hệ thống.

5


Hình 1.2. Tổng quan về lớp USB driver

Từ Hình 1.2 ta có thể thấy được để tìm hiểu và viết usb device driver ta cần tìm hiểu
về các enpoint, interface, các cấu hình API và cách tiến trình điều khiển trong các lớp của
USB device.
Các thành phần cơ bản của giao thức USB
Endpoint: Thành phần cơ bản nhất trong chuẩn giao tiếp USB. USB Endpoint truyền
dữ liệu theo một hướng duy nhất, từ host đến device (gọi là OUT Endpoint) hoặc ngược
lại (In Endpoint). Có 4 loại endpoint:
- Controll: Controll endpoint dùng để truy cập các phần khác nhau trong thiết bị
USB. Chúng thường được dùng để cài đặt thiết bị, lấy thông tin thiết bị, gửi lệnh
đến thiết bị, hoặc lấy báo cáo trạng thái của thiết bị.

- Interupt: Interupt endpoint dùng để truyền dữ liệu dung lượng nhỏ mỗi khi máy
chủ truy vấn dữ liệu từ thiết bị. Loại endpoint này hay được sử dụng với những
thiết bị như chuột hay bàn phím. Chúng cũng hay được dùng để gửi dữ liệu giữa
các thiết bị với nhau, nhưng lượng dữ liệu truyền đi thường không lớn. Giao thức
USB ln đảm bảo có băng thơng dự phịng cho loại endpoint này.
- Bulk: Bulk endpoint dùng để truyền dữ liệu có dung lượng lớn. Loại endpoint này
có kích thước lớn hơn nhiều so với interupt. Chúng được dùng cho loại thiết bị yêu
cầu truyền dẫn dữ liệu kích thước lớn mà không được xảy ra mất mát dữ liệu.
Chúng cũng khơng có băng thơng dự trữ giống như interupt endpoint. Nếu không

6


có đủ băng thơng để truyền cả gói tin đi, dữ liệu sẽ được chia nhỏ. Loại endpoint
này được sử dụng cho các thiết bị như máy in, ổ nhớ flash…
- Isochorous: Isochorous endpoint dùng để truyền dữ liệu kích thước lớn, nhưng
không yêu cầu sự đảm bảo dữ liệu toàn vẹn. Chúng được dùng cho các thiết bị chấp
nhận sự mất mát trong truyền dữ liệu, đổi lại sự đảm bảo quá trình được liên tục,
như các thiết bị truyền dẫn thời gian thực như video và audio…
Cấu trúc dữ liệu của endpoint được định nghĩa trong struct usb_host_endpoint của
Linux kernel. Trong đó thơng tin thực sự của endpoint được chứa trong struct
usb_endpoint_descriptor.

Hình 1.3. Cấu trúc dữ liệu của endpoint

Các trường cần quan tâm trong struct usb_endpoint_descriptor :
- bEndpointAddress: địa chỉ của endpoint, trong đó có 8 bit dùng mã hóa
hướng của endpoint là IN hay OUT.
- bmAttributes: Dùng định nghĩa loại endpoint là kiểu nào trong 4 kiểu
controll, bulk, interupt hay isochorous.

- wMaxPacketSize: Kích thước tối đa gói tin mà endpoint có thể chuyển đi.
Nếu gói tin cần chuyển lớn hơn giá trị này thì nó sẽ bị chia thành các gói có
kích thước tương đương.
- bInterval: Nếu endpoint là loại interupt thì biến này sẽ xác định khoảng thời gian
giữa các lần gửi request từ host đến device (đo bằng mili giây).
Interface: Tập hợp các endpoint gọi là interface. Mỗi interface thể hiện một chức
năng cơ bản duy nhất của thiết bị, ví dụ như ổ flash, hay bàn phím. Một thiết bị có thể có

7


nhiều interface. Một interface có nhiều thiết lập, với thiết lập ban đầu được đánh số 0. Thiết
lập khác nhau có thể dùng điều khuyển endpoint theo các cách khác nhau…
Interface được định nghĩa trong Linux kernel bằng struct usb_interface.

Hình 1.4. Cấu trúc dữ liệu interface

Các thông số cần quan tâm:
- struct usb_host_interface *altsetting: Một mảng chứa các phần tử kiểu interface
tương ứng với mỗi thiết lập khác nhau. Mỗi struct usb_host_interface chứa một tập
hợp các endpoint đã được định nghĩa trong usb_host_endpoint.
- unsigned num_altsetting: số thiết lập khác nhau của interface, được trỏ đến bởi
con trỏ *altsetting.
- struct usb_host_interface *cur_altsetting: con trỏ trỏ đến thiết lập hiện tại của
interface.
- int minor: Thiết bị trong hệ thống được truy cập bằng tên. Tên thiết bị bao gồm 2
phần là major và minor. major dùng xác định driver cho thiết bị, cịn minor dùng
để xác định chính xác thiết bị đang xét.
Configuration: là tập hợp các interface. Một thiết bị có thể có nhiều configuration
và chuyển đổi qua lại giữa chúng. Chỉ có một configuration được phép sử dụng tại mỗi thời


8


điểm. Linux không mạnh trong việc hỗ trợ các thiết bị sử dụng đồng thời nhiều
configuration (tuy nhiên các thiết bị đó rất hiếm).
Tóm lại:
- Một thiết bị có thể có nhiều configuration.
- Một configuration có thể có nhiều interface.
- Một interface có thể có nhiều setting.
- Interface khơng có hoặc có thể có nhiều endpoint.
Mơ hình giao thức USB
Về mặt cấu trúc, một hệ thống con USB không được đặt ra như một bus; nó đúng hơn
là một cái cây được xây dựng từ một số liên kết điểm-điểm. Các liên kết là cáp bốn dây
(nối đất, nguồn và hai dây tín hiệu) kết nối một thiết bị và hub, giống như Ethernet xoắn
đôi. Bộ điều khiển máy chủ USB chịu trách nhiệm yêu cầu mọi thiết bị USB nếu nó có bất
kỳ dữ liệu nào để gửi. Do cấu trúc liên kết này, một thiết bị USB không bao giờ có thể bắt
đầu gửi dữ liệu mà khơng được yêu cầu trước bởi bộ điều khiển máy chủ. Cấu hình này cho
phép loại hệ thống plug-and-play rất dễ dàng, theo đó các thiết bị có thể được cấu hình tự
động bởi máy tính chủ.
1.2.1 Chuẩn tín hiệu

Hình 1.5. Mơ hình cáp USB

Chuẩn USB sử dụng 4 đường tín hiệu trong đó có 2 đường cấp nguồn DC (VBUS-5V
và GND). 2 đườ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 nên có khả năng chống nhiễu tốt.

9



1.2.2 Mơ hình mạng

Hình 1.6. Mơ hình host – devices của USB

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. Trong đồ hình như vậy, các thiết
bị USB được chia làm 3 loại chính:
-

USB Host: thiết bị đóng vai trị điều khiển tồn bộ mạng USB (có thể lên tới tối đa
126 thiết bị). 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ò của thiết bị USB Host:
Trao đổi dữ liệu với các USB Device
Điều khiển USB Bus:
o Quản lý các thiết bị cắm vào hay rút ra khỏi Bus USB qua quá trình điểm
danh (Enumeration).
o Phân xử, 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ị.

10


-

USB Device: là các thiết bị đóng vai trị như các slave giao tiếp với USB Host. Xin
lưu ý một điều hết sức quan trọng đó là các thiết bị này hồn tồn đóng vai trị bị
động, khơng bao giờ được tự ý gửi gói tin lên 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 q trình điều phối của USB Host.

Các bạn sẽ hiểu cơ chế này rõ hơn trong phần truyền thông của chuẩn USB. 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ủa chúng ta. Cấp nguồn
cho các thiết bị USB.

1.2.3 Kịch bản hoạt động
Quá trình hoạt động của chuẩn USB có thể được chia làm hai giai đoạn chính:
• Q trình điểm danh:là quá trình USB Host phát hiện các thiết bị cắm vào và rút
ra khỏi đường USB Bus. Mỗi khi một thiết bị tham gia vào Bus USB, USB Host sẽ
tiến hành đọc các thông tin mô 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.
• Quá trình truyền dữ liệu:Đứng ở góc độ mức hệ thống, các Interface chính là các
dịch vụ khác nhau mà thiết bị đó cung cấp cịn các Endpoint chính là các cổng cần
thiết cho mỗi dịch vụ. Tương ứng với khái niệm trong kiến trúc TCP/IP, ví dụ giao
thức FTP là giao thức sử dụng để truyền file sẽ sử dụng hai cổng 20,21. Trong khi
đó giao thức HTTP lại sử dụng port 80, giao thức Telnet sử dụng port 23. Thực tế
các 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ình truyền thông
được tiến hành song song và cho tốc độ cao hơn, bên cạnh đó giúp cho việc phân
tách các dịch vụ khác nhau. Với chuẩn USB, các thiết bị được thiết kế với tối đa là
16 Endpoint.
11



USB driver
Tìm hiểu USB driver
Mã USB trong nhân Linux giao tiếp với tất cả các thiết bị USB bằng cách sử dụng
cấu trúc gọi là urb (USB request block). Khối yêu cầu này được mô tả với cấu trúc urb
struct và có thể được tìm thấy trong tệp bao gồm / linux / usb.h. Một urb được sử dụng để
gửi hoặc nhận dữ liệu đến hoặc từ một endpoint USB cụ thể trên một thiết bị USB cụ thể
theo cách khơng đồng bộ. Trình điều khiển thiết bị USB có thể phân bổ nhiều urbs cho một
endpoint duy nhất hoặc có thể sử dụng lại một urb duy nhất cho nhiều endpoint khác nhau,
tùy thuộc vào nhu cầu của trình điều khiển. Mỗi endpoint trong một thiết bị có thể xử lý
một hàng các urbs, do đó nhiều urbs có thể được gửi đến cùng một điểm cuối trước khi
hàng đợi trống. Vịng đời điển hình của một urb như sau:
• Được tạo bởi trình điều khiển thiết bị USB.
• Được gán cho một điểm cuối cụ thể của một thiết bị USB cụ thể.
• Gửi đến lõi USB, bởi trình điều khiển thiết bị USB.
• Gửi cho trình điều khiển bộ điều khiển máy chủ USB cụ thể cho thiết bị được chỉ
định bởi lõi USB.
• Được xử lý bởi trình điều khiển bộ điều khiển máy chủ USB thực hiện chuyển USB
sang thiết bị.
• Khi urb hồn thành, trình điều khiển máy chủ USB sẽ thơng báo cho trình điều khiển
thiết bị USB.
Urbs cũng có thể bị hủy bất cứ lúc nào bởi trình điều khiển đã gửi urb hoặc bởi lõi
USB nếu thiết bị bị tháo ra khỏi hệ thống, các urbs được tạo động và chứa số tham chiếu
bên trong cho phép chúng được tự động giải phóng khi người dùng cuối cùng của urb giải
phóng nó.
• Các trường của cấu trúc urb cấu trúc quan trọng đối với trình điều khiển thiết bị USB
là:
struct usb_device *dev

12



• Con trỏ tới cấu trúc usb_device mà urb này được gửi tới. Biến này phải được trình
điều khiển USB khởi tạo trước khi urb có thể được gửi đến lõi USB.
unsigned int pipe
Thông tin endpoint cho cấu trúc usb_device cụ thể mà urb này sẽ được gửi đến. Biến
này phải được trình điều khiển USB khởi tạo trước khi urb có thể được gửi đến lõi USB.
• Tạo và hủy urbs:
Cấu trúc urb được tạo bằng việc gọi hàm struct urb:
*usb_alloc_urb(int iso_packets, int mem_flags);
Tham số đầu tiên, iso_packets, là số lượng gói đồng thời mà urb này chứa. Nếu không
muốn tạo một urb đồng thời, biến này phải được đặt thành 0. Tham số thứ hai, mem_flags,
là cùng loại cờ được truyền cho lệnh gọi hàm kmalloc để cấp phát bộ nhớ từ kernel. Nếu
hàm thành công trong việc phân bổ đủ không gian cho urb, một con trỏ tới urb được trả về
cho người gọi. Nếu giá trị trả về là NULL, một số lỗi đã xảy ra trong lõi USB và trình điều
khiển cần phải dọn sạch đúng cách.
• Để hủy urbs gọi hàm:
void usb_free_urb(struct urb *urb);
Tham số duy nhất truyền vào hàm là địa chỉ urb cần hủy.
• Thốt urb
Để dừng một urb đã được gửi đến lõi USB, sử dụng các hàm usb_kill_urb hoặc
usb_unlink_urb .
int usb_kill_urb(struct urb *urb);
int usb_unlink_urb(struct urb *urb);
Khi hàm là usb_kill_urb, vòng đời của urb bị dừng lại. Chức năng này thường được
sử dụng khi thiết bị bị ngắt kết nối với hệ thống.
Hàm usb_unlink_urb được sử dụng để báo cho lõi USB dừng một urb. Hàm này
khơng chờ cho urb hồn toàn dừng lại trước khi trả về tới hàm gọi.
13



• Cấu trúc cấu trúc usb_device_id cung cấp danh sách các loại thiết bị USB khác nhau
mà trình điều khiển này hỗ trợ. Danh sách này được sử dụng bởi lõi USB để quyết định
trình điều khiển nào sẽ cung cấp cho thiết bị .
Một số trường của usb_device_id
+_u16 idVendor
ID nhà cung cấp USB cho thiết bị. Số này được chỉ định bởi diễn đàn USB cho các
thành viên của nó và khơng thể được tạo bởi bất kỳ ai khác.
+ _u16 idProduct

Hình 2.1. Thông tin thiết bị

ID sản phẩm USB cho thiết bị. Tất cả các nhà cung cấp có ID nhà cung cấp được gán
cho họ có thể quản lý ID sản phẩm của họ theo cách họ chọn.
Sử dụng lệnh command “$ sudo cat /sys/kernel/debug/usb/devices” để quan sát thông
tin chi tiết của thiết bị. Lưu ý rằng thiết bị đang được cấu hình driver mặc định là “usbhid”
và ta cần gỡ nó trước khi cài một driver mới.

14


Xây dựng driver cho chuột USB
Trước hết cần khai báo thư viện được sử dụng trong chương trình

Hình 2.2. Thư viện linux được dùng trong chương trình

Cấu trúc chính mà tất cả các trình điều khiển USB phải tạo là cấu trúc usb_driver:
Để tạo cấu trúc cấu trúc usb_driver, chỉ có năm trường cần được khởi tạo:

Hình 2.3. Khởi tạo cấu trúc cho driver


Cấu trúc này phải được trình điều khiển USB điền vào và bao gồm một số hàm gọi lại
và các biến mơ tả trình điều khiển USB với mã lõi USB:
const char *name
Con trỏ đến tên của trình điều khiển. Nó phải là duy nhất trong số tất cả các trình điều
khiển USB trong kernel và thường được đặt cùng tên với tên mơ-đun của trình điều khiển.
Nó hiển thị trong sysfs dưới / sys / bus / usb / driver / khi trình điều khiển nằm trong kernel.
const struct usb_device_id *id_table

15


Con trỏ tới bảng struct usb_device_id chứa danh sách tất cả các loại thiết bị USB khác
nhau mà trình điều khiển này có thể chấp nhận. Nếu biến này khơng được đặt, hàm probe
trong trình điều khiển USB sẽ khơng bao giờ được gọi.

Hình 2.4. Khai báo mã thiết bị

void (*disconnect) (struct usb_interface *intf)
Con trỏ đến hàm ngắt kết nối trong trình điều khiển USB. Chức năng này được gọi
bởi lõi USB khi cấu trúc usb_interface đã bị xóa khỏi hệ thống hoặc khi trình điều khiển
đang được dỡ khỏi lõi USB.

Hình 2.5. Cấu trúc hàm ngắt

Để đăng ký cấu trúc usb_driver một cuộc gọi đến usb_register_driver được thực hiện
bằng một con trỏ tới cấu trúcusb_driver. Điều này thường được thực hiện trong mã khởi
tạo mơ-đun cho trình điều khiển USB:

16



Hình 2.6. Đăng kí driver với kernel

Khi trình điều khiển USB được hủy , cấu trúc usb_driver cần phải được hủy đăng ký
khỏi kernel. Điều này được thực hiện với một cuộc gọi đến usb_deregister_driver. Khi cuộc
gọi này xảy ra, mọi giao diện USB hiện bị ràng buộc với trình điều khiển này sẽ bị ngắt kết
nối và hàm ngắt kết nối được gọi cho chúng.

Hình 2.7. Hủy đăng ki driver với kernel

int (*probe) (struct usb_interface *intf, const struct usb_device_id *id)
Con trỏ đến chức năng probe trong trình điều khiển USB. Hàm này được gọi bởi lõi
USB khi nó nghĩ rằng nó có cấu trúc usb_interface mà trình điều khiển này có thể xử lý.
Một con trỏ tới struct usb_device_id mà lõi USB được sử dụng để đưa ra quyết định này
cũng được truyền cho hàm này. Nếu trình điều khiển USB xác nhận cấu trúc usb_interface
được truyền cho nó, nó sẽ khởi tạo thiết bị đúng cách và trả về 0. Nếu trình điều khiển
khơng muốn u cầu thiết bị hoặc xảy ra lỗi, nó sẽ trả về giá trị lỗi âm.

17


Hình 2.8. Cấu trúc hàm pen_probe

void (usb_mouse_irq) (struct urb *urb)
18


Hàm ngắt sẽ nhận tín hiệu của chuột khi nó quét tới thiết bị và vận chuyển dữ liệu lên
các tầng usb driver.


Hình 2.9. Cấu trúc hàm ngắt

Trên đây là cấu trúc cơ bản của một chương trình usb device driver với các hàm số cơ
bản. Ngoài ta chúng ta cần cấu trúc của file_operations để điều khiển thiết bị

Hình 2.10. Cấu trúc hàm file_operations

Cũng như các hàm static int my_open(struct inode *i, struct file *f), static int
my_close(struct inode *i, struct file *f), static ssize_t my_read(struct file *f, char __user
19


*buf, size_t len, loff_t *off), static ssize_t my_write(struct file *f, const char __user
*buf,size_t len, loff_t *off). Sau khi xây dựng chương trình device driver ta sẽ viết một
chương trình ứng dựng để test khản năng hoạt động của chương trình.

20


Chạy chương trình và kiểm tra kết quả
Đầu tiên chúng ta cần gỡ chương gỡ bỏ chương trình mặc định device driver bằng lệnh
“$ sudo mknod /dev/myDev c 91 1”
“$ sudo rmmod usbhid”
Lúc này ta không thể sử dụng được chuột nữa do driver của nó đã được gỡ ra.
“$ sudo insmod usb1.ko”
Sau khi chạy các lệnh trên thì ta thu được kết quả như sau:

Hình 3.1. Thông tin thiết bị trong kernel


Để xem được kết quả trên ta sử dụng lệnh “$ dmesg” sau khi đã insert kernel vào thiết
bị. Ta có thể sử dụng chuột bình thường.
Sau đó ta sử dụng lệnh “$ sudo cat /proc/devices” để kiểm tra driver đã đăng kí và
insmod thiết bị.

21


Hình 3.2. Kết quả đăng kí driver

Chúng ta cũng có thể xem kết quả driver được thay thế “usbhid” trên thiết bị bằng lệnh
“$ sudo cat /sys/kernel/debug/usb/devices”

Hình 3.3. Thông tin thiết bị sau khi đổi driver

22


Để thuận tiến cho việc kiểm tra ta có thể sử dụng chương trình ứng dụng để gọi vào
usb driver vừa được code.

Hình 3.4. Kết quả chương trình test

Nếu không muốn sử dụng driver nữa thì ta sử dụng lệnh “$ sudo rmmod usb1” để gỡ
driver ra khỏi thiết bị. Sử dụng lệnh “$ dmesg” để kiểm tra kết quả.

Hình 3.5. Kết quả sau khi gỡ driver

Tất nhiên lúc này chúng ta không thể sử dụng chuột được nữa cho đến khi cài một
driver mới hoặc khôi phục lại driver “usbhid” mặc định của nó.

Để khơi phục driver mặc định của nó ta sử dụng lệnh “sudo modprobe usbhid”. Lúc
này ta sẽ sử dụng chuột ở chế độ mặc định của nó.

23


KẾT LUẬN
Chương trình với mục địch tìm hiểu về kernel , device driver, usb driver trong Linux
khi mà chúng em mới nhập môn và tập tành làm quen với Ubuntu, tuy đã cố gắng học hỏi
nhưng khản năng có hạn chúng em chủ yếu buid lại và xây dựng một chương tình device
driver đơn giản và nó đã bước đầu hoạt động.
Tuy chương trình là chưa hồn thiện nhưng chúng em sẽ hồn thiện nó khi học hỏi
được nhiều hơn về linux kernel.
Trên đây là bài báo cáo bài tập lớn cũng như thu hoạch của chúng em khi thực hành
viết usb mouse device driver. Chúng em xin cảm ơn thầy vì những kiến thức mà mình thức
mà chúng em đã học được.

24



×