lOMoARcPSD| 59256994
Ngô Thị Vinh và Đtg Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
QUY TRÌNH VIẾT DRIVER CHO CÁC THIẾT BỊ THEO CHUẨN USB
TRONG HỆ THỐNG NHÚNG LINUX
*
Ngô Thị Vinh, Đoàn Ngọc Phƣơng , Ngô Hữu Huy
Trường Đại học Công nghệ Thông tin và Truyền thông – ĐH Thái Nguyên
TÓM TẮT
Để điều khiển đƣợc các thiết bị ngoại vi, các module mở rộng của các hệ thống nhúng, ngƣời lập
trình thƣờng phải tự viết các chƣơng trình điều khiển Driver cho c cổng giao tiếp thay sử
dụng các Driver sẵn của nhà cung cấp thiết bị tính riêng biệt của các hệ nhúng. Việc viết Driver
cho các cổng giao tiếp luôn đƣợc coi là một công việc hết sức quan trọng và tốn nhiều công sức của
ngƣời lập trình, do đó cần có các quy trình rõ ràng để cụ thể hóa và đơn giản hóa công việc này. Bài
báo trình bày về quy trình viết Driver cho một thiết bị USB – một chuẩn giao tiếp hết sức phổ biến
hiện nay, Driver đƣợc xây dựng cho các hệ thống sử dụng hệ điều hành Linux nhân ARM
những nền tảng phổ biến trên các hệ thống nhúng hiện đại.
Từ khóa: Linux, Tiny 6410, vi điều khiển ARM11, hệ điều hành nhúng, USB Driver
GIỚI THIỆU
1
Khi xây dựng ứng dụng cho các hệ nhúng thì
một trong những công việc quan trọng nhất của
ngƣời lập trình đó 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ệ vi điều khiển trung tâm. Nếu
các module các thiết bị đƣợc ghép nối với
các hệ thống tƣơng thích với nhau về chuẩn
giao tiếp giao thức truyền thông thì chúng
thể hoạt động trao đổi dữ liệu cho nhau.
Các hệ nhúng thƣờng sdụng các giao thức
truyền thông phổ biến nhƣ Ethernet, RS232,
SPI, I2C đặc biệt ngày nay là giao thức USB.
Sử dụng giao thức USB nhiều ƣu điểm [1]
nhƣ dễ sử dụng, tốc độ truyền cao chỉ sau
chuẩn Ethernet [1], đtin cậy cao, chi phí thấp,
yêu cầu điện áp nguồn nuôi nhỏ (+5V).
đƣợc những hiểu biết sâu sắc về chuẩn USB sẽ
giúp ngƣời lập trình thể thực hiện đƣợ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ị hoạt động theo chuẩn USB.
Bài báo sẽ trình bày c bƣớc viết một driver
cho một thiết bị USB trên hệ điều hành nhúng
1
Tel: 0979 479940
Linux đƣợc cài đặt trên kít ARM Tiny6410 [8].
Linux một trong những hệ điều hành đƣợc
phát triển rộng rãi cho các hệ nhúng với phần
nhân có kích thức rất nhỏ gọn và miễn phí [4].
Ngoài ra, Linux hỗ trợ trình biên dịch cho các
ứng dụng đƣợc viết bằng C/C++ java [4].
Đây là hai trong ba ngôn ngữ lập trình đƣợc sử
dụng nhiều nhất thế giới bởi tốc độ chạy nhanh
không phụ thuộc vào nền phần cứng của
chúng.
CHUẨN USB
Tín hiệu: Chuẩn USB sử dụng 4 đƣờng tín
hiệu trong đó 2 đƣờng cấp nguồn DC
VBUS-5V và đƣờng GND. 2 đƣờng còn lại là
một cặp tín hiệu vi sai D+ D- cho phép
truyền dữ liệu [1].
Thiết bị USB: c thiết bị USB có thể đƣợc
chia làm 3 loại chính [1] dựa theo vài trò của
chúng: (1) USB Host thiết bị đóng vai trò
điều khiển toàn bộ mạng USB. Để giao tiếp và
điều khiển các USB device, Bộ điều khiển USB
Host controller cần đƣợc thiết kế tích hợp với
một USB RootHub. USB Host chức năng
trao đổi dữ liệu với các USB Device, điều khiển
bus USB, quản lý các thiết bị cắm vào hay rút
ra khỏi Bus USB qua quá trình định danh, phân
lOMoARcPSD|59 256994
Ngô Thị Vinh và Đtg Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
xử, quản 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ị. (2) USB Device
c thiết bị đóng vai trò nhƣ các slave giao
tiếp với USB Host. c USB Device là các
thiết bị bị 9
động, quá trình trao đổi dữ liệu của chúng đều
phải thông qua quá trình điều phối của USB
Host. (3) USB Hub đóng vai tnhƣ các Hub
trong mạng Ethernet để cấp nguồn cho các thiết
bị USB.
Hoạt động của chuẩn USB: đƣợc chia làm hai
giai đoạn chính gồm quá trình định danh quá
trình truyền dữ liệu. Qtrình định danh là q
trình USB Host phát hiện các thiết bị cắm vào
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
tả của USB Device rồi thiết lập địa chỉ
NodeID chế độ hoạt động tƣơng ứng cho
thiết bị USB Device. Các địa chỉ sẽ đƣợc đánh
một số nguyên từ 1 đến 126. 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 liên quan đến hai
khái niệm là Interface Endpoint. Một thiết
bị USB thể nhiều Interface và một
Interface có thể sử dụng nhiều Endpoint khác
nhau. Các Endpoint đó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 các quá trình truyền thông
đƣợc tiến hành song song cho tốc độ cao
hơn, đồng thời giúp cho việc phân tách c dịch
vụ khác nhau dễ dàng. Với chuẩn USB, c
thiết bị đƣợc thiết kế với tối đa là 16 Endpoint.
Các Endpoint đƣợc phân loại theo hƣớng
truyền dữ liệu nhìn từ phía USB Host theo
cách: Các Endpoint truyền dữ liệu từ USB
Device tới USB Host gọi endpoint IN, còn
các Endoint truyền dữ liệu t USB Host tới
USB Device là endpoint OUT [1]. Chuẩn USB
cung cấp bốn chế độ truyền [1] dùng cho c
mục đích khác nhau. Chế độ truyền điều khiển
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. Chế độ truyền theo ngắt
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 nhƣ
chuột, bàn phím. Chế độ truyền theo khối sử
dụng cho các thiết bị cần truyền một lƣợng dữ
liệu lớn, u cầu độ chính c tuyệt đối
không ng buộc quá chặt chẽ về thời gian
thực nhƣ các thẻ
10
nhớ USB, y in. Chế đtruyền đẳng thời 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 nhƣng chấp nhận với
một độ 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.
QUY TRÌNH VIẾT DRIVER CHO THIẾT BỊ
USB TRÊN HỆ ĐIỀU HÀNH LINUX
Hệ thống USB trong Linux đƣợc phân làm
nhiều tầng [2], [5]. Tầng Driver của các USB
nằm giữa hai tầng tầng lõi hệ thống c
tầng con khác nhau.
Tầng lõi của USB do hệ điều hành Linux cung
cấp, một tập các hàm API [5] nhằm trừu
tƣợng hóa các nền phần cứng khác nhau và các
thành phần phụ thuộc. Tầng Driver tập các
API dẫn xuất cho các tầng con lớp trên. Tùy
thuộc vào mục đích sử dụng ngƣời lập trình
cần sử dụng các API phù hợp với các thiết bị.
Để viết Driver cho một thiết bị USB trên Linux
ngƣời lập trình cần thực hiện các bƣớc nhƣ
sau:
Bƣớc 1: Tìm hiều thông tin về thiết bị USB.
Ngƣời lập trình cần biết thông tin cần thiết về
Firmware của thiết bị bao gồm [2]: định danh
nhà sản xuất (idvendor), định danh về sản
phẩm (idproduct), số lƣợng các cấu hình
Configuration, số lƣợng các Interface trong
từng cấu hình, số lƣợng và loại Endpoint trong
lOMoARcPSD| 59256994
Ngô Thị Vinh và Đtg Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
từng Interface. Trên hệ điều nh Linux ta chỉ
việc kết nối thiết bị tới máy nh lệnh
lsusb [5] trên terminal để xem danh sách các
thiết bị USB cấu hình của chúng. Bƣớc 2:
Khai báo danh sách c thiết bị thể đƣợc
điều khiển bởi Driver. Ngƣời lập trình cần phải
chỉ định Driver 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ị,
thể là một thiết bị cụ thể cũng có thể là một lớp
thiết bị. Một số macro có thể đƣợc sử dụng để
khởi tạo cấu trúc này [2], [5] n sử dụng
macro USB_DEVICE (vendor, product) để tạo
ra một cấu trúc usb_device_id với IDvendor
IDproduct. Sau khi đã tạo ra một cấu trúc
usb_device_id ngƣời lập trình cần phải khai
báo cấu trúc này với tầng lõi sử dụng macro
MODULE_DEVICE_TABLE [5].
Bƣớc 3: Khai báo cấu trúc dữ liệu liên quan tới
thiết bị. Trong quá trình thăm dò thiết bị ngƣời
lập trình cần lƣu lại các thông tin cần thiết nhƣ:
định danh nhà sản xuất, định danh thiết bị,
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ể để ta định nghĩa ra một
cấu trúc dữ liệu phợp. Cấu trúc dữ liệu
dạng: struct usb_mydevice {
struct sb_device *udev;(1)
struct usb_inter *inter;(2)
unsigned char *in_buffer;(3)
size_t in_size;(4)
__u8 in_endpointAddr;(5)
__u8 out_endpointAddr;(6) };
Trong đó: (1) (2) con trỏ cấu trúc mô tả
thiết bị, (3) bộ đệm dữ liệu vào, (4) kích
thƣớc bộ đệm dữ liệu vào, (5) (6) là địa chỉ của
hai Endpoint IN và OUT.
Hình 1. Quy trình viết USB Driver Bƣớc
4. Đăng hủy đăng Driver cho thiết bị
USB Device. Để tầng USB Core có thể nhận ra
Driver, ngƣời lập trình cần phải đăng kí Driver
sử dụng hàm sau: usb_register(struct
usb_driver &);
Hàm này thƣờng đƣợc gọi trong hàm khởi tạo
Driver. Tham số cần truyền cho hàm này một
con trtới cấu trúc usb_driver [2]. Cấu trúc này
chứa các thông tin về Driver đang viết bao
gồm: (1) tên của Driver, (2) con trỏ tới bảng
chứa các thiết bị sẽ đƣợc điều khiển bởi Driver
đã đƣợc khai báo
MODULE_DEVICE_TABLE(), (3) một con
trỏ tới một 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 để xác
định các Endpoint, cấp phát bộ nhớ…(4) Một
con trỏ tới một 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.
Bƣớc 5. Thực hiện thăm dò thiết bị với hàm
probe(). Khi thiết bị đƣợc kết nối tới hệ thống,
hàm thăm [2]của Driver sẽ đƣợc gọi với một
con trỏ trỏ tới cấu trúc usb_interface tả
Interface đƣợc chọn trên thiết bị do tầng lõi
USB truyền tới. Hàm thăm dò sẽ thực hiện các
công việc nhƣ lấy ra địa chỉ các Endpoint cần
dùng kích thƣớc các bộ đệm cho thiết bị, cấp
lOMoARcPSD|59 256994
Ngô Thị Vinh và Đtg Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
phát bộ đệm, lƣu lại các thông tin nhƣ địa chỉ
Endpoint, kích thƣớc bộ đệm, địa chỉ bộ
đệm…, đăng kí lớp thiết bị cho Driver.
Bƣớc 6: Thực hiện đọc/ghi dữ liệu từ thiết bị.
Để đọc ghi dữ liệu từ thiết bUSB ta phải lấy
các thông tin từ thiết bị s dụng hàm
usb_get_intfdata() thiết lập dữ liệu cho cấu
trúc file nhƣ sau: dev =
usb_get_intfdata(interface); file->private_data
= dev;
Cấu trúc file đƣợc định nghĩa trong
<linux/fs.h>[5] một cấu trúc quan trọng
trong không gian nhân của Linux rất cần thiết
cho việc viết Driver của USB. Sau đó, ngƣời
lập trình sẽ thực hiện đọc, ghi dữ liệu tthiết bị
sử dụng các hàm read() và write() [5]. Bƣớc 7:
Hủy kết nối tới thiết bị bằng hàm disconnect().
Khi thiết bị đƣợc gỡ bỏ ra khỏi hệ thống, hàm
ngắt kết nối đƣợc gọi. Hàm disconnect sẽ thực
hiện hai công việc chính hủy các dữ liệu về
thiết bị đã u trữ từ hàm thăm bằng cách
thiết lập giá trị NULL cho 11
interface hủy đăng lớp thiết bị qua hàm
usb_deregister_dev().
KẾT QUẢ THỰC NGHIỆM
Chúng tôi đã tiến hành viết Driver cho một
Camera USB đƣợc kết nối tới kít Tiny6410 cài
hệ điều hành nhúng Linux. Kết quả cho thấy hệ
điều hành cài trên kít đã nhận đƣợc USB
Camera của hãng Tako, với 100 lần thử kết nối
tỉ lệ thành công là 100%, thời gian nhận thiết bị
trung bình 25 giây, chƣơng trình Driver
không y tranh chấp về cổng khi cắm đồng
thời 2 thiết bị trên 2 cổng USB của kit. Ảnh thu
đƣợc từ Camera đƣợc hiển thị trên màn hình
của kít.
Hình 2. Kết quả thu ảnh từ camera USB của hãng
Tako trên kít Tiny6410 cài Linux
KẾT LUẬN
Bài báo đã trình bày quy trình viết một Driver
cho một thiết bị USB trên hệ điều hành nhúng
Linux. Đây cũng là các bƣớc chung mà ngƣời
SUMMARY
lập trình thể tham khảo khi viết Driver cho
một thiết bị USB trên nền của hầu hết các hệ
điều hành nhúng khác. Bài báo đã thực hiện
viết Driver cho một USB Camera của hãng
Tako kiểm chứng kết quả trên kít ARM11
Tiny6410.
TÀI LIỆU THAM KHẢO
1. Jan Axelson (2009), USB Complete: The
Developers Guide, Fourth Edition, Lakeview
Research LLC, 5310 Chinook Ln., Madison WI
53704.
2. Jonathan Corbet, Alessandro Rubini, and Greg
Kroah-Hartman (2013), Linux Device Drivers,
O'Reilly.
3. Greg Kroah-Hartman (2001), How to Write a
Linux USB Device Driver,
http://www.linuxjournal.com/article/4786. 4.
Graham Glass, King Ables, (2006), Linux for
Programmers and Users, Prentice Hall,
5. Michael Opdenacker (2012) , Linux USB
device drivers, Free Electrons.
6. Rajaram Regupathy, Bootstrap Yourself
with Linux-USB Stack: Design, Develop, Debug,
and Validate Embedded USB, Course Technology
PTR, March 16, 2011
7.http://www.linux-drivers.org/usb_webcams.html
8. http://api.haiku-os.org/usb_modules.html.
lOMoARcPSD|59 256994
Ngô Thị Vinh và Đtg Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
9. www.minidevs.com, Tiny6410 Development Kit, 2013
THE PROCESS OF WRITING DRIVER FOR USB DEVICES
ON LINUX EMBEDDED SYSTEM
Ngo Thi Vinh, Doan Ngoc Phuong
2
, Ngo Huu Huy
College of Information and Communication Technology - TNU
To control the peripherals, expansion modules of embedded systems, programmers often have to
write the driver - Driver for the interface instead of using the available Driver suppliers equipment
because of the peculiarities of embedded systems. Writing Driver for the interface are always
considered to be a very important job and spend a lot of programming effort, so there should be clear
procedures to concretize and simplify this task. This paper presents the process of writing a device
driver for USB - a communication standard that is extremely popular today, Driver was developed
for systems using the Linux operating system and ARM is the common platform on modern
embedded systems.
Key words: Linux Embedded, Tiny 6410, ARM11 microprocessor, Embedded Operating System,
USB Driver
Ngày nhận bài:25/01/2014; Ngày phản biện:10/02/2014; Ngày duyệt đăng: 26/02/2014
Phản biện khoa học: TS. Phùng Trung Nghĩa – Trường ĐH Công nghệ Thông tin & Truyền thông -
ĐHTN
12
2
Tel: 0979 479940

Preview text:

lOMoARcP SD| 59256994 Ngô Thị Vinh và Đtg
Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
QUY TRÌNH VIẾT DRIVER CHO CÁC THIẾT BỊ THEO CHUẨN USB
TRONG HỆ THỐNG NHÚNG LINUX *
Ngô Thị Vinh, Đoàn Ngọc Phƣơng , Ngô Hữu Huy
Trường Đại học Công nghệ Thông tin và Truyền thông – ĐH Thái Nguyên TÓM TẮT
Để điều khiển đƣợc các thiết bị ngoại vi, các module mở rộng của các hệ thống nhúng, ngƣời lập
trình thƣờng phải tự viết các chƣơng trình điều khiển – Driver cho các cổng giao tiếp thay vì sử
dụng các Driver có sẵn của nhà cung cấp thiết bị vì tính riêng biệt của các hệ nhúng. Việc viết Driver
cho các cổng giao tiếp luôn đƣợc coi là một công việc hết sức quan trọng và tốn nhiều công sức của
ngƣời lập trình, do đó cần có các quy trình rõ ràng để cụ thể hóa và đơn giản hóa công việc này. Bài
báo trình bày về quy trình viết Driver cho một thiết bị USB – một chuẩn giao tiếp hết sức phổ biến
hiện nay, Driver đƣợc xây dựng cho các hệ thống sử dụng hệ điều hành Linux và nhân ARM là
những nền tảng phổ biến trên các hệ thống nhúng hiện đại.
Từ khóa: Linux, Tiny 6410, vi điều khiển ARM11, hệ điều hành nhúng, USB Driver
Linux đƣợc cài đặt trên kít ARM Tiny6410 [8]. GIỚI THIỆU1
Linux là một trong những hệ điều hành đƣợc
Khi xây dựng ứng dụng cho các hệ nhúng thì
phát triển rộng rãi cho các hệ nhúng với phần
một trong những công việc quan trọng nhất của
nhân có kích thức rất nhỏ gọn và miễn phí [4].
ngƣời lập trình đó chính là lập trình ghép nối
Ngoài ra, Linux hỗ trợ trình biên dịch cho các
để điều khiển các module, các thiết bị ngoại vi
ứng dụng đƣợc viết bằng C/C++ và java [4].
ghép nối với hệ vi điều khiển trung tâm. Nếu
Đây là hai trong ba ngôn ngữ lập trình đƣợc sử
các module và các thiết bị đƣợc ghép nối với
dụng nhiều nhất thế giới bởi tốc độ chạy nhanh
các hệ thống tƣơng thích với nhau về chuẩn
và không phụ thuộc vào nền phần cứng của
giao tiếp và giao thức truyền thông thì chúng chúng.
có thể hoạt động và trao đổi dữ liệu cho nhau. CHUẨN USB
Các hệ nhúng thƣờng sử dụng các giao thức
Tín hiệu: Chuẩn USB sử dụng 4 đƣờng tín
truyền thông phổ biến nhƣ Ethernet, RS232,
hiệu trong đó có 2 đƣờng cấp nguồn DC là
SPI, I2C và đặc biệt ngày nay là giao thức USB.
VBUS-5V và đƣờng GND. 2 đƣờng còn lại là
Sử dụng giao thức USB có nhiều ƣu điểm [1]
một cặp tín hiệu vi sai D+ và D- cho phép
nhƣ dễ sử dụng, tốc độ truyền cao chỉ sau truyền dữ liệu [1].
chuẩn Ethernet [1], độ tin cậy cao, chi phí thấp,
Thiết bị USB: Các thiết bị USB có thể đƣợc
yêu cầu điện áp nguồn nuôi nhỏ (+5V). Có
chia làm 3 loại chính [1] dựa theo vài trò của
đƣợc những hiểu biết sâu sắc về chuẩn USB sẽ
chúng: (1) USB Host là thiết bị đóng vai trò
giúp ngƣời lập trình có thể thực hiện đƣợc rất
điều khiển toàn bộ mạng USB. Để giao tiếp và
nhiều công việc nhƣ: thiết kế, chế tạo thiết bị
điều khiển các USB device, Bộ điều khiển USB
hoạt động theo chuẩn USB, viết driver cho thiết
Host controller cần đƣợc thiết kế tích hợp với
bị giao tiếp theo chuẩn USB, lập trình ghép nối
một USB RootHub. USB Host có chức năng
với các thiết bị hoạt động theo chuẩn USB.
trao đổi dữ liệu với các USB Device, điều khiển
Bài báo sẽ trình bày các bƣớc viết một driver
bus USB, quản lý các thiết bị cắm vào hay rút
cho một thiết bị USB trên hệ điều hành nhúng
ra khỏi Bus USB qua quá trình định danh, phân 1 Tel: 0979 479940 lOMoAR cP SD| 59 256 994 Ngô Thị Vinh và Đtg
Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
xử, quản lý luồng dữ liệu trên Bus, đảm bảo các
là chế độ truyền đƣợc tất cả các thiết bị USB
thiết bị đều có cơ hội trao đổi dữ liệu tùy thuộc
hỗ trợ để truyền các thông tin điều khiển với
vào cấu hình của mỗi thiết bị. (2) USB Device
tốc độ tƣơng đối chậm. Chế độ truyền theo ngắt
là các thiết bị đóng vai trò nhƣ các slave giao
sử dụng cho các thiết bị cần truyền một lƣợng
tiếp với USB Host. Các USB Device là các
dữ liệu nhỏ, tuần hoàn theo thời gian nhƣ thiết bị bị 9
chuột, bàn phím. Chế độ truyền theo khối sử
động, quá trình trao đổi dữ liệu của chúng đều
dụng cho các thiết bị cần truyền một lƣợng dữ
phải thông qua quá trình điều phối của USB
liệu lớn, yêu cầu độ chính xác tuyệt đối và
Host. (3) USB Hub đóng vai trò nhƣ các Hub
không có ràng buộc quá chặt chẽ về thời gian
trong mạng Ethernet để cấp nguồn cho các thiết thực nhƣ các thẻ bị USB. 10
Hoạt động của chuẩn USB: đƣợc chia làm hai
nhớ USB, máy in. Chế độ truyền đẳng thời sử
giai đoạn chính gồm quá trình định danh và quá
dụng cho các thiết bị cần truyền một lƣợng dữ
trình truyền dữ liệu. Quá trình định danh là quá
liệu lớn với tốc độ rất nhanh, đảm bảo ràng
trình USB Host phát hiện các thiết bị cắm vào
buộc về thời gian thực nhƣng chấp nhận với
và rút ra khỏi đƣờng USB Bus. Mỗi khi một
một độ chính xác ở một mức nhất định nhƣ các
thiết bị tham gia vào Bus
thiết bị nghe nhạc, xem phim kết nối theo chuẩn
USB, USB Host sẽ tiến hành đọc các thông tin USB.
mô tả của USB Device rồi thiết lập địa chỉ
QUY TRÌNH VIẾT DRIVER CHO THIẾT BỊ
NodeID và chế độ hoạt động tƣơng ứng cho
USB TRÊN HỆ ĐIỀU HÀNH LINUX
thiết bị USB Device. Các địa chỉ sẽ đƣợc đánh
một số nguyên từ 1 đến 126. Khi thiết bị rút ra
Hệ thống USB trong Linux đƣợc phân làm
khỏi đƣờng Bus, địa chỉ này sẽ đƣợc thu hồi.
nhiều tầng [2], [5]. Tầng Driver của các USB
Quá trình truyền dữ liệu liên quan đến hai
nằm giữa hai tầng là tầng lõi và hệ thống các
khái niệm là Interface và Endpoint. Một thiết tầng con khác nhau.
bị USB có thể có nhiều Interface và một
Tầng lõi của USB do hệ điều hành Linux cung
Interface có thể sử dụng nhiều Endpoint khác
cấp, nó là một tập các hàm API [5] nhằm trừu
nhau. Các Endpoint đóng vai trò nhƣ các bộ
tƣợng hóa các nền phần cứng khác nhau và các
đệm truyền/nhận dữ liệu. Nhờ việc sử dụng
thành phần phụ thuộc. Tầng Driver là tập các
nhiều bộ đệm mà các quá trình truyền thông
API dẫn xuất cho các tầng con ở lớp trên. Tùy
đƣợc tiến hành song song và cho tốc độ cao
thuộc vào mục đích sử dụng mà ngƣời lập trình
hơn, đồng thời giúp cho việc phân tách các dịch
cần sử dụng các API phù hợp với các thiết bị.
vụ khác nhau dễ dàng. Với chuẩn USB, các
Để viết Driver cho một thiết bị USB trên Linux
thiết bị đƣợc thiết kế với tối đa là 16 Endpoint.
ngƣời lập trình cần thực hiện các bƣớc nhƣ
Các Endpoint đƣợc phân loại theo hƣớng sau:
truyền dữ liệu nhìn từ phía USB Host theo
Bƣớc 1: Tìm hiều thông tin về thiết bị USB.
cách: Các Endpoint truyền dữ liệu từ USB
Ngƣời lập trình cần biết thông tin cần thiết về
Device tới USB Host gọi là endpoint IN, còn
Firmware của thiết bị bao gồm [2]: định danh
các Endoint truyền dữ liệu từ USB Host tới
nhà sản xuất (idvendor), định danh về sản
USB Device là endpoint OUT [1]. Chuẩn USB
phẩm (idproduct), số lƣợng các cấu hình
cung cấp bốn chế độ truyền [1] dùng cho các
Configuration, số lƣợng các Interface trong
mục đích khác nhau. Chế độ truyền điều khiển
từng cấu hình, số lƣợng và loại Endpoint trong lOMoAR cPSD| 59 256 99 4 Ngô Thị Vinh và Đtg
Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
từng Interface. Trên hệ điều hành Linux ta chỉ
việc kết nối thiết bị tới máy tính và gõ lệnh
lsusb [5] trên terminal để xem danh sách các
thiết bị USB và cấu hình của chúng. Bƣớc 2:
Khai báo danh sách các thiết bị có thể đƣợc
điều khiển bởi Driver. Ngƣời lập trình cần phải
chỉ định Driver 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ị. Một số macro có thể đƣợc sử dụng để
khởi tạo cấu trúc này [2], [5] nhƣ 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
Hình 1. Quy trình viết USB Driver Bƣớc
usb_device_id ngƣời lập trình cần phải khai
4. Đăng kí và hủy đăng kí Driver cho thiết bị
báo cấu trúc này với tầng lõi sử dụng macro
USB Device. Để tầng USB Core có thể nhận ra MODULE_DEVICE_TABLE [5].
Driver, ngƣời lập trình cần phải đăng kí Driver
sử dụng hàm sau: usb_register(struct
Bƣớc 3: Khai báo cấu trúc dữ liệu liên quan tới usb_driver &);
thiết bị. Trong quá trình thăm dò thiết bị ngƣời
Hàm này thƣờng đƣợc gọi trong hàm khởi tạo
lập trình cần lƣu lại các thông tin cần thiết nhƣ:
Driver. Tham số cần truyền cho hàm này là một
định danh nhà sản xuất, định danh thiết bị,
con trỏ tới cấu trúc usb_driver [2]. Cấu trúc này
thông tin các Configuration, Interface,
chứa các thông tin về Driver đang viết bao
Endpoint của thiết bị. Tùy theo đặc điểm của
gồm: (1) tên của Driver, (2) con trỏ tới bảng
từng phần cứng cụ thể để ta định nghĩa ra một
chứa các thiết bị sẽ đƣợc điều khiển bởi Driver
cấu trúc dữ liệu phù hợp. Cấu trúc dữ liệu có đã đƣợc khai báo dạng: struct usb_mydevice {
MODULE_DEVICE_TABLE(), (3) một con struct sb_device *udev;(1)
trỏ tới một hàm thăm dò, hàm này sẽ đƣợc gọi struct usb_inter *inter;(2)
khi thiết bị đƣợc kết nối tới hệ thống để xác unsigned char *in_buffer;(3)
định các Endpoint, cấp phát bộ nhớ…(4) Một size_t in_size;(4)
con trỏ tới một hàm ngắt kết nối, hàm này sẽ __u8 in_endpointAddr;(5)
đƣợc gọi khi thiết bị đƣợc gỡ bỏ ra khỏi hệ thống. __u8 out_endpointAddr;(6) };
Bƣớc 5. Thực hiện thăm dò thiết bị với hàm
Trong đó: (1) và (2) là con trỏ cấu trúc mô tả
probe(). Khi thiết bị đƣợc kết nối tới hệ thống,
thiết bị, (3) là bộ đệm dữ liệu vào, (4) là kích
hàm thăm dò [2]của Driver sẽ đƣợc gọi với một
thƣớc bộ đệm dữ liệu vào, (5) (6) là địa chỉ của
con trỏ trỏ tới cấu trúc usb_interface mô tả hai Endpoint IN và OUT.
Interface đƣợc chọn trên thiết bị do tầng lõi
USB truyền tới. Hàm thăm dò sẽ thực hiện các
công việc nhƣ lấy ra địa chỉ các Endpoint cần
dùng và kích thƣớc các bộ đệm cho thiết bị, cấp lOMoAR cP SD| 59 256 994 Ngô Thị Vinh và Đtg
Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
phát bộ đệm, lƣu lại các thông tin nhƣ địa chỉ
Endpoint, kích thƣớc bộ đệm, địa chỉ bộ
đệm…, đăng kí lớp thiết bị cho Driver.
Bƣớc 6: Thực hiện đọc/ghi dữ liệu từ thiết bị.
Để đọc ghi dữ liệu từ thiết bị USB ta phải lấy
các thông tin từ thiết bị sử dụng hàm
usb_get_intfdata() và thiết lập dữ liệu cho cấu trúc file nhƣ sau: dev =
usb_get_intfdata(interface); file->private_data = dev;
Hình 2. Kết quả thu ảnh từ camera USB của hãng
Tako trên kít Tiny6410 cài Linux
Cấu trúc file đƣợc định nghĩa trong
[5] là một cấu trúc quan trọng KẾT LUẬN
trong không gian nhân của Linux rất cần thiết
Bài báo đã trình bày quy trình viết một Driver
cho việc viết Driver của USB. Sau đó, ngƣời
cho một thiết bị USB trên hệ điều hành nhúng
lập trình sẽ thực hiện đọc, ghi dữ liệu từ thiết bị
Linux. Đây cũng là các bƣớc chung mà ngƣời
sử dụng các hàm read() và write() [5]. Bƣớc 7:
Hủy kết nối tới thiết bị bằng hàm disconnect(). SUMMARY
Khi thiết bị đƣợc gỡ bỏ ra khỏi hệ thống, hàm
lập trình có thể tham khảo khi viết Driver cho
ngắt kết nối đƣợc gọi. Hàm disconnect sẽ thực
một thiết bị USB trên nền của hầu hết các hệ
hiện hai công việc chính là hủy các dữ liệu về
điều hành nhúng khác. Bài báo đã thực hiện
thiết bị đã lƣu trữ từ hàm thăm dò bằng cách
viết Driver cho một USB Camera của hãng
thiết lập giá trị NULL cho 11
Tako và kiểm chứng kết quả trên kít ARM11
interface và hủy đăng kí lớp thiết bị qua hàm Tiny6410. usb_deregister_dev(). TÀI LIỆU THAM KHẢO KẾT QUẢ THỰC NGHIỆM
1. Jan Axelson (2009), USB Complete: The
Chúng tôi đã tiến hành viết Driver cho một
Developer’s Guide, Fourth Edition, Lakeview
Camera USB đƣợc kết nối tới kít Tiny6410 cài
Research LLC, 5310 Chinook Ln., Madison WI
hệ điều hành nhúng Linux. Kết quả cho thấy hệ 53704.
điều hành cài trên kít đã nhận đƣợc USB
2. Jonathan Corbet, Alessandro Rubini, and Greg
Camera của hãng Tako, với 100 lần thử kết nối
Kroah-Hartman (2013), Linux Device Drivers, O'Reilly.
tỉ lệ thành công là 100%, thời gian nhận thiết bị
3. Greg Kroah-Hartman (2001), How to Write a
trung bình là 25 giây, chƣơng trình Driver Linux USB Device Driver,
không gây tranh chấp về cổng khi cắm đồng
http://www.linuxjournal.com/article/4786. 4.
thời 2 thiết bị trên 2 cổng USB của kit. Ảnh thu
Graham Glass, King Ables, (2006), Linux for
đƣợc từ Camera đƣợc hiển thị trên màn hình
Programmers and Users, Prentice Hall, của kít. 5.
Michael Opdenacker (2012) , Linux USB
device drivers, Free Electrons. 6.
Rajaram Regupathy, Bootstrap Yourself
with Linux-USB Stack: Design, Develop, Debug,
and Validate Embedded USB, Course Technology PTR, March 16, 2011
7.http://www.linux-drivers.org/usb_webcams.html
8. http://api.haiku-os.org/usb_modules.html. lOMoAR cP SD| 59 256 994 Ngô Thị Vinh và Đtg
Tạp chí KHOA HỌC & CÔNG NGHỆ 116 (02): 9 - 12
9. www.minidevs.com, Tiny6410 Development Kit, 2013
THE PROCESS OF WRITING DRIVER FOR USB DEVICES ON LINUX EMBEDDED SYSTEM
Ngo Thi Vinh, Doan Ngoc Phuong2, Ngo Huu Huy
College of Information and Communication Technology - TNU
To control the peripherals, expansion modules of embedded systems, programmers often have to
write the driver - Driver for the interface instead of using the available Driver suppliers equipment
because of the peculiarities of embedded systems. Writing Driver for the interface are always
considered to be a very important job and spend a lot of programming effort, so there should be clear
procedures to concretize and simplify this task. This paper presents the process of writing a device
driver for USB - a communication standard that is extremely popular today, Driver was developed
for systems using the Linux operating system and ARM is the common platform on modern embedded systems.
Key words: Linux Embedded, Tiny 6410, ARM11 microprocessor, Embedded Operating System, USB Driver
Ngày nhận bài:25/01/2014; Ngày phản biện:10/02/2014; Ngày duyệt đăng: 26/02/2014
Phản biện khoa học: TS. Phùng Trung Nghĩa – Trường ĐH Công nghệ Thông tin & Truyền thông - ĐHTN 12 2 Tel: 0979 479940