POLLING & INTERUPTS 44-

Một phần của tài liệu đồ án công nghệ thông tin USB driver trên hệ điều hành Linux Red Hat (Trang 44)

Khi đồng bộ giữa bộ vi xử lý (CPU) và các thiết bị phần cứng, có một số yêu cầu cần thực hiện. Vì bản chất sự truy cập phần cứng thì chậm hơn nhiểu so với tốc độ xử lý của CPU. Vì vậy đã có một số kỹ thuật được áp dụng để kết nối các thiết bị phần cứng tới CPU.

+ Polling mode + Interrupt mode + Interrupt sharing + Bottom halvels + Task queues + DMA mode 4.2.1. Polling mode

Polling mode là cách CPU sẽ truy vấn lần lượt các thiết bi phần cứng đang kết nối với máy tính xem nó co sẵn sàng làm việc không? Nếu thiết bị sẵn sàng thì quá trình trao đổi dữ liệu diễn ra. Cách nay chậm nhưng thích hợp với các thiết bị có vào ra chậm.

4.2.2. Interrupt mode

Khi CPU đang thực hiện tác vụ, ngẫu nhiên, ngoại vi thứ i xin phục vụ bằng cách phát ra tín hiệu IRQ(i) (Interrupt Request) đến CPU.

Nói chung, CPU sẽ ngừng xử lý tác vụ đang thục hiện và cất ngữ cảnh vào Stack Mem, rồi tìm địa chỉ của phục vụ ngắt tng ứng (Interrupt Service Routine - ISR) để thực hiện.

Sau khi thực hiện xong ISR, gặp lệnh iret (reti...), CPU khôi phục lại ngữ cảnh của tác vụ đang thuc hiện dở và tiếp tục thực hiện.

4.2.3. Interrupt sharing

Do số lượng IRQ của một máy tính la có hạn, vì vậy có thể thiết kế chương trình để nhiều thiết bị có thể sử dụng chung một IRQ

4.2.4. Bottom halvels

Nếu thường xuyên xảy ra tình trạng không cần thực hiện ngay hàm sau khi ngắt trong khi chức năng đang thực hiên dở cần thuẹc hiện hơn, trong trường hợp này một bottom halvels được tạo ra.

4.2.5. Task queues

Trong trường hợp bottom halvels được tạo ra thì khó để kiếm soát tác vụ nao quan trọng hơn, vì vậy mỗi tác vụ được gán cho 1 số nguyên trong khoảng 32, task queues được tạo ra và coi như một mở rộng của bottom halvels

Là cách trao đổi dữ liệu trực tiếp giữa device và bộ nhớ không thông qua bộ vi xử lý.

4.3. USB TOPOGY

Mỗi hệ thống bus USB bao gồm một host controller và một root hup, trong đó, root hup được hiểu như là điểm mắc gốc của các device và các hup khác, host controller la thành phần điều khiển, phát hiện các kết nối và xử lý các urb từ các device.

4.4. CÁC KIỂU LUỒNG ĐIỀU KHIỂN

Trên USB có 4 kiểu luồng điều khiển

+ Control Transfers: Được sử dụng để cấu hình thiết bị lúc gắn kết và có thể sử dụng cho các mục đích khác bao gồm cả diều khiển các pipes của thiết bị. Truyền theo phương pháp này thì an toàn, dữ liệu không bị mất. Điều khiển được thực hiện thông qua các lệnh

GET STATUS

CLEAR FEATURE

SET ADDRESS

GET DESCRIPTOR

SET DESCRIPTOR

GET CONFIGURATION

+ Bulk Data Transfers: sử dụng khi truyền dữ liệu không chặt chẽ về rang buộc như máy in, sanner… tuỳ thuọc vào tình trang bus mà việc truyền có hiệu qua không

+ Interrupt Data Transfers:được sử dụng cho các mục đích của người sử dụng hoặc có thông tin phản hồi

+ Isochronous Data Transfers: gọi là truyền luồng theo thời gian ( streaming real time transfers) như âm thanh, hình ảnh

4.5. CẤU HÌNH THIÊT BỊ

Mỗi khi thiết bị (device) được gắn vào hệ thống thì nó được đánh số và các thông tin description được đọc. Description là các thông tin mô tả về thiết bị và các thuộc tính của nó

+ Device Descriptor chứa thông tin về device. Một device thì có một Descriptor

+ Configuration Descriptor xác định các thông tin cấu hình, môt device thì có một hay nhiều configuration descriptors.

+ Interface Descriptor mô tả giao diện đối với một configuration descriptor + Endpoint Descriptor chứa các thông tin được yêu cầu bởi host để lấy được băng thông của mỗi điểm truy cập cuối.

+ String Descriptors cung cấp thêm các thồn tin có thê đọc được dưới ở Unicode format.

Một USB device được đăng ký và gỡ bỏ khỏi host như một hệ thống con. Mỗi USB device driver cần đăng ký một file, một số chính (đối với USB luôn luôn la 180) và một số phụ từ 0 đến 15.

+ Cấu trúc dữ liệu lưu các thông tin về USB driver

struct usb_driver { const char *name;

void * (*probe)(struct usb_device *, unsigned int, const struct usb_device_id *id_table);

void (*disconnect)(struct usb_device *, void *); struct list_head driver_list;

struct file_operations *fops; int minor;

struct semaphore serialize;

int (*ioctl) (struct usb_device *dev, unsigned int code, void *buf);

const struct usb_device_id *id_table; };

Trong đó

- name: thường là tên module

- probe: điểm truy cập của probe function.

- disconnect: điểm truy cập của disconnect function.

- driver list: cho sử dụng bên trong driver - khởi tạo là NULL,NULL - fops: các thao tác đối với a driver

- minor: so phụ được gán cho device này device - serialize:

- ioctl: - id table:

+ 2 điểm truy cập các hàm chức năng

probe được gọi khi một device được kết gắn vào hệ thống disconnect được gọi khi một device được tháo ra khỏi hệ thống

void *probe(struct usb_device *dev, unsigned int interface, const struct usb_device_id *id_table)

{

struct driver_context *context;

if (dev->descriptor.idVendor == 0x0547 && dev->descriptor.idProduct == 0x2131 && interface == 1 ) { context=allocate_driver_resources(); return context; } return NULL;

}

static void dabusb_disconnect (struct usb_device *usbdev, void *drv_context)

{

struct driver_context *s = drv_context; s->remove_pending = 1; wake_up (&s->wait); sleep_on (&s->remove_ok); free_driver_resources(s); } + Các hàm hỗ trợ từ host

- int usb register(struct usb driver *drv);

dùng để dăng ký một USB device driver mới như một hệ thống con của host

- void usb deregister(struct usb driver *drv);

dùng để gỡ bỏ một USB device driver ra khỏi host host

- void usb driver claim interface(struct usb driver *driver, struct usb interface *iface, void *drv context);

dùng để đăng ky USB sử dụng nhiều giao diện khác nhau - int usb interface claimed(struct usb interface *iface);

dung để kiểm tra xem device driver khác đã sử dụng giao dien này chưa

- void usb driver release interface(struct usb driver *driver, struct usb interface *iface);

giải phóng tất cả các giao diện đã được đăng ký trong hàm probe

- const struct usb device id *usb match id( struct usb device *dev, struct usb interface *interface, const struct usb device id *id);

+ Cấu hình Descriptor cho device:

Mỗi device có một cấu trúc phân cấp các thông tin về device và thuộc tính của nó

struct usb_device{ ...

struct usb_config_descriptor *actconfig;/* the active configuration */

...

struct usb_device_descriptor descriptor;/* Descriptor */ struct usb_config_descriptor *config; /* All of the configs */ }

usb_device là gốc truy cập của tất cả các descriptor

+ Truy cập tất cả các descriptor

for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { struct usb_config_descriptor *cfg = &dev->config[i]; ...

}

+ Truy cập tất cả các interface của một Configuration

for (j = 0; j < cfg->bNumInterfaces; j++) {

struct usb_interface *ifp = &cfg->interface[j]; ...

}

+ Truy cập tất cả các interface thay thế của một Configuration

for (k = 0; k < ifp->num_altsetting; k++) {

struct usb_interface_descriptor *as = &ifp->altsetting[k]; ...

}

+ Truy cập tất cả các endpoint descriptors của một interface

for(l = 0; l < as->bNumEndpoints; l++) {

struct usb_endpoint_descriptor *ep=&as->endpoint[k]; ...

}

+ Các hàm thiết lập, gỡ bỏ Desctiptor, Interface, Configuration

- int usb set_configuration(struct usb device *dev, int configuration); thiết lập một configuration

- int usb set_interface(struct usb device *dev, int interface, int alternate);

thiết lập một interface thay thế

- int usb_ get_ device descriptor(struct usb device *dev); lấy các thông tin về usb device

- int usb get descriptor(struct usb device *dev, unsigned char desctype, unsigned char descindex, void *buf, int size);

lấy các thông tin về descriptors

- int usb get string(struct usb device *dev, unsigned short langid, unsigned char index,

void *buf, int size);

lấy các string đã được đánh chỉ mục cho một device, configuration hay interface

- int usb string(struct usb device *dev, int index, char *buf, size t size);

lấy các string đã được đánh chỉ mục cho một device,

configuration hay interface nhưng chuyển đổi từ Unicode sang ASCII

- int usb get status(struct usb device *dev, int type, int target, void *data)

lấy trạng thái của device

+Một số hàm khác

- int usb clear halt(struct usb device *dev, int pipe); - int usb get protocol(struct usb device *dev, int ifnum); - int usb set protocol(struct usb device *dev, int protocol, - int usb get report(struct usb device *dev, unsigned char type, unsigned char id,

int ifnum, void *buf, int size);

- int usb set idle(struct usb device *dev, int ifnum, int duration, int report id);

USB device sử dụng một cấu trúc URB để chuyển tải các yêu cầu tới host: cấu trúc URB

struct urb {

spinlock_t lock; void *hcpriv;

struct list_head urb_list; struct urb *next;

struct usb_device *dev; unsigned int pipe; int status;

unsigned int transfer_flags; void *transfer_buffer; dma_addr_t transfer_dma; int transfer_buffer_length; int actual_length; int bandwidth;

unsigned char *setup_packet; dma_addr_t setup_dma; int start_frame; int number_of_packets; int interval; int error_count; int timeout;

void *context;

usb_complete_t complete;

struct iso_packet_descriptor iso_frame_desc[0]; };

Các hàm hỗ trợ chuyển URB tới host là - urb t usb_alloc_urb(int iso packets); - void usb free urb (purb t purb); - int usb submit urb(purb t purb); - int usb unlink urb(purb t purb);

USB DRIVER CHO FLASH MEMMORY

5.1. GIỚI THIỆU VỀ FLASH MEMMORY

Flash Memmory là loại thiết bị lưu trữ dùng công nghệ EEPROM, được thiết kế theo chuẩn bus vào ra USB. Do tính tiện dụng và khả năng cơ động của nó, Flash Memmory ngày càng được sủ dụng và ứng dụng rộng rãi. Trong phần đồ án tốt nghiệp này, em xin được trình bày về cách thức xây dựng một driver cho flash memmory từ 64 Mb đến 256 Mb.

Việc xây dựng USB driver cho flash memmory cũng như các USB driver khác, vì vậy em chỉ nêu ra các khác biệt

5.2. CÁC SƠ ĐỒ THỰC HIỆN CHOTRÊN USB DRIVER CHO FLASH MEMMORY

Sơ đồ khối quan trọng nhất là sơ đồ thực hiện trong hàm probe

Khoá con trỏ tới device

Xác định lại các tham số

Khởi toạ lại thiết bị

Mỏ khoá tới device

Xác định bộ nhớ và khởi tạo

Xác định URB

Xác định các tham số

Tạo số thứ tự cho device

Xác định các hàm xử lý prôtl

Đăng ký

Xác định các hàm xử lý prôtl

Kiêm tra xem device đã tồn tại chưa

Lấy các Interface

Kiểm tra xem hệ thống có hỗ trọ không Lấy các tham số về device

5.3. CÁC CẤU TRÚC DỮ LIỆU DÙNG TRÊN USB DRIVER CHO FLASH MEMMORY

Để xây dựng driver, cấu trúc quan trọng nhất luu toàn bộ thông tin về driver trong quá trình làm việc la cấu trúc us_data bao gồm các thành phần sau

Struct us_data * next;

Struct semaphore dev_semaphore; Struct usb_device * pusb_dev;

unsigned int flags;

char vendor[32]; char product[32]; char serial[32]; char * transport_name; char * protocol_name; u8 subclass; u8 protocol; u8 max_lun; u8 ifnum; u8 ep_in; u8 ep_out; Struct usb_endpoint_descriptor * ep_int;

Trans_cmnd transport; Trans_reset transport_reset; proto_cmnd proto_handler; GUID(guid);

Struct Scsi_Host * host; Scsi_Host_Template htmplt;

int host_number; int host_no; Scsi_Cmnd * srb;

atomic_t abortcnt; Scsi_Cmnd * queue_srb; int action;

pid_t pid; Struct semaphore ip_waitq; atomic_t ip_wanted[1]; Struct semaphore irq_urb_sem; Struct urb * irq_urb; unsigned char irqbuf[2]; unsigned char irqdata[2]; Struct semaphore current_urb_sem; Struct urb * current_urb; Struct completion current_done; unsigned int tag;

Struct semaphore sema; struct completion notify;

spinlock_t queue_exclusion; Struct us_unusual_dev * unusual_dev; Void * extra;

Cấu trúc lưu giữ toàn bộ các thông tin về device đang làm việc. Trong đó next: là device tiếp theo

dev_semaphore: để bảo vệ pusb_dev pusb_dev: là device hiện tại

flags: cờ khởi động

vendor: là tên nhà cung cấp product:

serial:

transport_name tên của hàm vận chuyển protocol_name: tên của giao thức

subclass: protocol: max_lun:

ifnum: số lượng giao thức ep_in: bulk in endpoint ep_out: bulk out endpoint

struct usb_endpoint_descriptor *ep_int; /* interrupt endpoint */

transport: hàm vận chuyển

transport_reset: hàm reset vận chuyển proto_handler: hàm xử lý giao thức GUID(guid): số được gán cho device Host: bộ đệm của host

Htmplt:mẫu hình của host host_number: để tìm host

host_no: dịa chỉ host xác định bởi scsi srb:

abortcnt: queue_srb:

action: hành động pid: mã tác vụ

ip_waitq: ip_wanted[1]:

irq_urb_sem: để bảo vệ irq_urb irq_urb: USB request

irqbuf[2]: bộ đệm cho irq_urb irqdata[2:; dữ liệu từ irq_urb

current_urb_sem: để bảo vệ current_urb current_urb: current_done: cờ hoàn thành tag: sema: tác vuh nghỉ notify: cờ của tác vụ queue_exclusion:

unusual_dev: nếu là thiết bị không thông thường extra:extra_destructor:

CHƯƠNG 6 TỔNG KẾT

6.1. PHÁT TRIỂN DRIVER TRÊN HỆ ĐIỀU HÀNH MÃ NGUỒN ĐÓNG VÀ HỆ ĐIỀU HÀNH MÃ NGUỒN MỞ

Driver cũng như các sản phẩm phần mềm khác, trong khi trên hệ điều hành mã nguồn đóng như Window, chúng ta hoàn toàn không biết kernel của Windows lmà việc như thê nào với các driver và với các thiết bị phần cứng thì trái lại driver trên Linux la một thành phần của kernel và được cung cấp mở cả mã nguồn về các giao diện, các hàm hỗ trợ và cách thức lam việc. Một điều đáng kể là do tính mở của kernel nên khi người dùng phát hiện lỗi và thông báo lên cộng đồng nguồn mở thì lập tức sẽ có nhũng thành viên của cộng đồng sửa lỗi này và cập nhật vào kernel. Vì vậy có thể nói chất lượng của các driver viết trên hệ điều hành mã nguồn mở cao hơn va đòi hỏi ít thời gian để phát triển hơn.

Tuy nhiên, driver trên Linux lại nghèo nàn về tài liệu hướng dẫn cài đặt và sử dụng. Điều này đòi hỏi người sử dụng phải có kinh nghiệm và kiến thức nhất định.

6.2. TỔNG KẾT

Phát triển driver là một công việc khó khăn và đòi hỏi nhiều kiến thức sâu về hệ điều hành, về thiết bị cần xây dựng. Việc phát triển một driver và kiểm tra hoàn chỉnh để có thể dưa tới người sử dụng cuối theo các chuyên gia đánh giá mất khoảng từ 5-6 tháng. Trong phạm vi đồ án tốt nghiệp do hạn chế về thời gian và kiến thức chuyên môn sâu nên kết quả thu được chưa thật nhiều. Tuy vậy em cũngng xin nêu ra một số kết quả đã đạt được:

+ hiểu về kiến trúc bus USB

+ xây dựng driver cho flash memmory + sử dụng được các thư viện kernel cho USB

+ các bước tạo và xây dựng các file cần thiết cho việc phát triển USB driver trên linux dựa trên các giao diện va hàm mà kernel cung cấp.

PHỤ LỤC A. CÁC THUẬT NGỮ VIẾT TẮT

- CPU: Bộ vi xử lý - Device: thiết bị - Interface: Giao diện

- Host: Chỉ hệ thống có cài đặt Host Controller

- Host Controller: Driver điều khiển trung tâm của BUS USB - Process: tiến trình, tác vụ

- Protocol: giao thức

PHỤ LỤC B. MỘT SỐ HÀM CUNG CẤP BỞI KERNEL CHO USB FLASH MEMMORY DRIVER

1)

int usb_register(struct usb_driver *new_driver)

2)

void usb_scan_devices(void)

3)

static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev)

4)

void usb_deregister(struct usb_driver *driver)

int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum)

6)

struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)

7)

struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)

8)

long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)

9)

int usb_check_bandwidth (struct usb_device *dev, struct urb *urb)

10)

void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc)

11)

void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc)

12)

static void usb_bus_get(struct usb_bus *bus)

13)

14)

struct usb_bus *usb_alloc_bus(struct usb_operations *op)

15)

void usb_free_bus(struct usb_bus *bus)

16)

void usb_register_bus(struct usb_bus *bus)

17)

void usb_deregister_bus(struct usb_bus *bus)

18)

static void usb_check_support(struct usb_device *dev)

19)

void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv)

20)

int usb_interface_claimed(struct usb_interface *iface)

21)

void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface)

22)

const struct usb_device_id *

const struct usb_device_id *id)

23)

static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum)

24)

int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned ifnum)

25)

static void call_policy_interface (char *verb, struct usb_device *dev, int interface)

26)

static void call_policy (char *verb, struct usb_device *dev)

27)

static inline void

call_policy (char *verb, struct usb_device *dev)

28)

static void usb_find_drivers(struct usb_device *dev)

29)

struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)

30)

void usb_free_dev(struct usb_device *dev)

void usb_inc_dev_use(struct usb_device *dev)

32)

struct urb *usb_alloc_urb(int iso_packets)

33)

void usb_free_urb(struct urb* urb)

34)

int usb_submit_urb(struct urb *urb)

35)

int usb_unlink_urb(struct urb *urb)

36)

static void usb_api_blocking_completion(struct urb *urb)

37)

static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)

38)

int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,

struct usb_ctrlrequest *cmd, void *data, int len, int timeout)

39)

int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout)

40)

int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout)

41)

int usb_get_current_frame_number(struct usb_device *usb_dev)

42)

static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size)

43)

static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)

44)

int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer)

45)

void usb_destroy_configuration(struct usb_device *dev)

46)

static int ascii2utf (char *ascii, __u8 *utf, int utfmax)

47)

48)

int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr)

49)

void usb_disconnect(struct usb_device **pdev)

50)

void usb_connect(struct usb_device *dev)

51)

#define GET_TIMEOUT 5 #define SET_TIMEOUT 5

int usb_set_address(struct usb_device *dev)

52)

int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)

53)

int usb_get_class_descriptor(struct usb_device *dev, int ifnum,

unsigned char type, unsigned char id, void *buf, int size)

54)

int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)

55)

int usb_get_device_descriptor(struct usb_device *dev)

56)

int usb_get_status(struct usb_device *dev, int type, int target, void *data)

Một phần của tài liệu đồ án công nghệ thông tin USB driver trên hệ điều hành Linux Red Hat (Trang 44)

Tải bản đầy đủ (DOC)

(78 trang)
w