Universal Serial Bus (USB) là một trong những giao thức phổ biến nhất được sử dụng trong sản phẩm điện tử tiêu dùng hiện nay, bao gồm máy tính, máy ảnh, thiết bị GPS, máy MP3, modem, máy in, máy scan,.... Các chuẩn USB ban đầu được phát triển bởi Compaq, Microsoft, Intel, và NEC, và sau đó bởi Hewlett-Packard, Lucent và Philips. Các công ty này cuối cùng hình thành tổ chức phi lợi nhuận USB Implementers Forum Inc. tổ chức này phát triển và công bố các thông số kỹ thuật của USB.
Chương này mô tả các nguyên tắc cơ bản của bus USB và đi tìm hiểu các ứng dụng dựa trên USB với vi điều khiển PIC. Các bus USB là một giao thức phức tạp. Một cuộc thảo luận đầy đủ về thiết kế và sử dụng của nó là vượt ra ngoài phạm vi bài nay. Trong bài này chỉ đề cập những nguyên tắc cơ bản của USB và cách kết nối giao tiếp với vi điều khiển PIC 18f4550
USB là một giao thức nối tiếp tốc độ cao, nó có thể cung cấp điện cho các thiết bị kết nối với nó. Một bus USB hỗ trợ kết nối lên đến 127 thiết bị (giới hạn bởi các trường địa chỉ 7-bit, lưu ý rằng địa chỉ 0 không được sử dụng vì nó có một mục đích đặc biệt) được kết nối thông qua dây cáp với chiều dài lên đến ba hoặc thậm chí năm mét. Nhiều thiết bị USB có thể được kết nối với bus thông qua Hub, Hub này có thể có 4, 8, hoặc thậm chí 16 cổng. Một thiết bị có thể được cắm vào một Hub mà Hub này kết nối đến các Hub khác, và như vậy. Số lượng tối đa cho phép là sáu tầng. Theo các đặc điểm kỹ thuật, khoảng cách tối đa của một thiết bị đến máy chủ của nó là khoảng ba mươi mét, thực hiện bằng cách sử dụng 5 hub. Đây là khoảng cách dài nhất. Nếu cho khoảng cách dài hơn ta có thể dùng chuẩn truyền Ethernet.
Hình hub usb
Các đặc điểm kỹ thuật bus USB có hai phiên bản: phiên bản trước đó là USB1.1, hỗ trợ tốc độ 11Mbps, trong khi phiên bản mới là USB 2.0, hỗ trợ tốc độ lên đến 480Mbps. Các đặc điểm kỹ thuật USB định nghĩa ba tốc độ dữ liệu:
Low speed—1.5Mb/sec (Tốc độ thấp)
Full speed—12Mb/sec (Tốc độ đầy đủ)
High speed—480Mb/sec (Tốc độ cao)
Full speed—12Mb/sec (Tốc độ đầy đủ)
High speed—480Mb/sec (Tốc độ cao)
Nguồn tối đa cho một thiết bị bên ngoài kết nối sử dụng điện áp cấp bởi cổng USB được giới hạn trong khoảng 100mA tại điện áp 5.0V.
Có hai loại đầu kết nối được sử dụng đó là kiểu A và kiểu B:
Có hai loại đầu kết nối được sử dụng đó là kiểu A và kiểu B:
Đầu nối kiểu A Đầu nối kiểu B
Chân số | Tên | Màu sắc |
1 | + 5.0 V | Đỏ |
2 | - Data | Trắng |
3 | + Data | Xanh lá cây |
4 | Ground (đất) | Đen |
Bảng 8.2 Quy định chân của đầu kết nối USB
Thông số kỹ thuật còn đề cập loại đầu cắm mini kiểu B, sử dụng cho các thiết bị điện sách tay chẳng hạn như camera và các thiết bị cầm tay khác. Loại đầu cắm này có thêm chân thứ 5 gọi là chân ID, mặt dù chân này không được sử dụng.
Hai dây Data + và Data -, tạo thành 1 cặp xoắn và mang tín hiệu vi sai và trạm dữ liệu kết thúc đơn
Chân số | Tên | Màu sắc |
1 | + 5.0 V | Đỏ |
2 | - Data | Trắng |
3 | + Data | Xanh lá cây |
4 | Không sử dụng | - |
5 | Ground (đất) | Đen |
Bảng 8.2 Quy định chân của đầu kết nối USB mini
Tín hiệu USB là lưỡng pha, và tín hiệu được gửi từ máy chủ bằng cách sử dụng kỹ thuật mã hóa dữ liệuNRZI (non-return to zero inverted). Trong kỹ thuật này, hai logic 0 kế tiếp nhau sẽ bị đảo ngược mức tín hiệu. Mức tín hiệu cho mức logic 1 là không thay đổi. Một bit 0 được "nhồi" sau mỗi sáu bit 1 liên tiếp trong dòng dữ liệu để làm dữ liệu động ( được gọi là bit nhồi vì kéo dài dòng dữ liệu thêm một chút). Hình 8.3 cho thấy cách thức thực hiện NRZI .
Hình 8.3 Dữ liệu NRZI
Một gói dữ liệu truyền bởi máy chủ gửi đến mỗi thiết bị kết nối đến bus, truyền xuống thông qua chuỗi các Hub. Tất cả các thiết bị đều nhận được tín hiệu, nhưng chỉ có một thiết bị , 1 địa chỉ chấp nhận dữ liệu. Ngược lại, tại bất cứ thời gian nào chỉ có một thiết bị có thể truyền đến máy chủ.
Thiết bị USB kết nối đến bus có thể là thiết bị được tùy chỉnh đầy đủ, yêu cầu một trình điều khiển (driver) tùy chỉnh đầy đủ. Phân Lớp thiết bị cho phép cùng một trình điều khiển thiết bị được sử dụng cho nhiều thiết bị có chức năng tương tự.. Ví dụ , thiết bị máy in có phân lớp thiết bị là 0x07, và hầu hết máy in sử dụng kiểu driver này
Hầu hết phân lớp thiết bị thông dụng được trình bày ở bẳng 8.3. Lớp USB human interface device (HID) tạm dịch là lớp thiết bị giao diện con người là lớp được quan tâm đặc biệt, nó được sử dụng trong ví dụ ở bài này.
Một vài thuật ngữ USB thông dụng:
Endpoint (Điểm cuối): một điểm cuối là một bộ nhận hoặc truyền dữ liệu. Endpoint của thiết bị là một bộ nhớ đệm (buffer) để lưu trữ dữ liệu nhận hoặc là dữ liệu để truyền. Thiết bị phải hỗ trợ một endpoint 0, endpoint này có thể nhận và truyền dữ liệu.Một thiết bị USB giới hạn mười sáu enpoint IN (bộ đệm nhận) và mười sáu enpoint out (bộ đệm truyền).
Transaction: một transaction là truyền dữ liệu trên bus.
Pipe (Đường Ống): Một đường ống là kết nối dữ liệu logic giữa máy chủ và một điểm cuối (Enpoint).
Logical pipes: đường ống lôgic
Endpoints in the device: các endpoint trong thiết bị
Phân lớp thiết bị | Miêu tả | Thiết bị ví dụ |
0x00 | Để dành | - |
0x01 | USB audio device (USB thiết bị âm thanh ) | Sound card (card âm thanh) |
0x02 | USB communications device ( USB Thiết bị truyền thông ) | Modem, fax |
0x03 | USB human interface device ( USB Thiết bị giao diện con người) | Keyboard, mouse (Bàn phím, chuột) |
0x07 | USB printer device (USB Thiết bị in) | Printer (Máy in) |
0x08 | USB mass storage device (USB Thiết bị lưu trữ ) | Memory card, flash drive |
0x09 | USB hub device ( USB Thiết bị hub) | Hubs |
0x0B | USB smart card reader device ( USB Thiết bị đọc thẻ thông minh) | Card reader (bộ đọc thẻ nhớ) |
0x0E | USB video device ( USB Thiết bị Video) | Webcam, scanner |
0xE0 | USB wireless device ( USB Thiết bị wireless) | Bluetooth |
8.1 Định danh tốc độ trên bus:
Tại thiết bị , chân dữ liệu D+ hoặc D- được kéo lên nguồn 3.3 V thông qua điện trở 1.5K. Khi thiết bị chạy ở tốc độ full-speed, chân D+ được kéo lên nguồn 3.3V, Khi thiết bị chạy ở tốc độ low speed chân D- được kéo lên nguồn 3.3V. Khi cả hai đường dữ liệu ở mức thấp, báo cho host rằng không có thiết bị nào được kết nối. Khi có thiết bị kết nối, khi đó đường dữ liệu D+ hoặc D- sẽ được kéo lên mức cao, nhờ đó mà host biết được có thiết bị đang được kết nối. Phụ thuộc đường dữ liệu nào được kéo lên mức cao host xác định được tốc độ truyền của thiết bị.
Thiết bị chạy ở tốc độ Full speed
Thiết bị chạy ở tốc độ Low speed
Trạng thái USB :
Một số trạng thái bus USB là:
Idle (trạng thái rỗi): bus ở trạng thái rỗi khi một đường dữ liệu kéo lên cao và đường dữ liệu còn lại ở mức thấp. Đây là trạng thái của đường truyền trước và sau khi truyền gói dữ liệu.
Detached (Tháo rời): Khi không có thiết bị kết nối đến bus, cả hai đường dữ liệu đều ở mức thấp
Detached (Tháo rời): Khi không có thiết bị kết nối đến bus, cả hai đường dữ liệu đều ở mức thấp
Attached (Gắn): Khi một thiết bị được kết nối đến bus, đường dữ liệu D+ hoặc D- sẽ kéo lên cao, có nghĩa là thiết bị đã được gắn.
J state (Trạng thái J): Giống như trạng thái rỗi.
K state (Trạng thái K): Ngược với trạng thái J.
SE0 (The single ended zero state): Trạng thái 0 kết thúc đơn, khi cả hai đường dữ liệu ở mức thấp.
SE1 (The single ended one state) : Trạng thái một kết thúc đơn, khi cả hai đường dữ liệu ở mức cao. SE1 là điều kiện không được phép xảy ra trên bus, nó phải không bao giờ ở trạng thái này.
Reset: Khi host muốn truyền thông với thiết bị trên bus, đầu tiên nó phải gửi một điều kiện "reset" bởi kéo cả hai đường dữ liệu xuống mức thấp ít nhất 10 ms (Trạng thái SE0).
EOP: Sự kết thúc của trạng thái gói, mà về cơ bản là một trạng thái SE0 cho 2 bit thời gian, theo sau là một trạng thái J cho 1 bit thời gian.
Keep alive: Trạng thái này đạt được bằng cách sử dụng EOP. Keep alive được gửi ít nhất mỗi một mili giây để giữ thiết bị khỏi bị tạm ngưng.
Suspend (Tạm ngưng): Được sử dụng để tiết kiệm năng lượng, tạm ngưng được thực hiện bằng cách không gửi bất cứ gì đến thiết bị trong 3 ms. Thiết bị tạm ngưng sử dụng dòng ít hơn 0.5 mA và phải nhận ra tín hiệu reset và tín hiệu resume (phục hồi).
Resume (Phục hồi): Một thiết bị tạm ngưng được đánh thức bởi bởi đảo ngược cực của tín hiệu trên đường truyền dữ liệu ít nhất 20 ms, theo sau bởi một tín hiệu EOP tốc độ thấp
Truyền thông bus USB:
USB là một hệ thống kết nối với Host đóng vai trò ở vị trí trung tâm (Ví dụ như máy tính là host và bàn phím, chuột, máy in... là salve (tớ)), nơi host dò tìm phát hiện thiết bị gắn vào hoặc tháo ra, quản lý điều khiển dòng dữ liệu giữa host và thiết bị, có thể cung cấp nguồn cho thiết bị và nhiều hơn nữa. Mỗi thiết bị trên bus được gán một địa chỉ USB duy nhất, và thiết bị tớ không thể đưa tín hiệu trên bus cho đến khi host yêu cầu nó.
Khi một thiết bị USB mới được cắm vào bus, host USB sử dụng địa chỉ từ 0 để hỏi thông tin cơ bản từ các thiết bị. Sau đó, host gán cho nó một địa chỉ USB duy nhất.
Sau khi host yêu cầu và nhận được thêm các thông tin về các thiết bị, chẳng hạn như tên của thiết bị, khả năng của thiết bị , và ID thiết bị, truyền thông hai chiều trên bus khi đó có thể bắt đầu.
Packets (Gói tin)
Dữ liệu được truyền trên bus USB bên trong một gói tin. Một gói tin bắt đầu với một mô hình đồng bộ để cho phép đồng hồ thu được đồng bộ hóa với dữ liệu. Tiếp theo là dữ byte dữ liệu của gói, kết thúc với tín hiệu kết thúc gói tin.
Một byte định danh gói tin (PID) theo sau trường đồng bộ của mỗi gói tin USB. Một PID có chiều dài 4 bit, và 4 bit tiếp theo được lặp lại theo hình thức lấy bù. Có 14 giá trị PID khác nhau, nó được thể hiện trong bảng 8.4. Trong đó bao gồm một giá trị để dành và một giá trị khác được sử dụng hai lần, với ý nghĩa khác nhau.
Kiểu PID | Tên PID | Bits | Miêu tả |
Token | OUT IN SOF SETUP | 1110 0001 0110 1001 1010 0101 0010 1101 | Host to device transaction Device to host transaction Start of frame Setup command |
Data (Dữ liệu) | DATA0 DATA1 DATA2 MDATA | 1100 0011 0100 1011 1000 0111 0000 1111 | Data packet PID even Data packet PID odd Data packet PID high speed Data packet PID high speed |
Handshake (Bắt tay) | ACK NAK STALL NYET | 1101 0010 0101 1010 0001 1110 1001 0110 | Receiver accepts packet Receiver does not accept packet Stalled No response from receiver |
Special (Đặc biệt) | PRE ERR SPLIT PING Reserved | 0011 1100 0011 1100 0111 1000 1011 0100 1111 0000 | Host preample Split transaction error High-speed split transaction High-speed flow control Reserved |
Bảng 8.4
Có bốn định dạng gói tin, dựa trên PID nào bắt đầu gói tin: gói tin token, gói tin dữ liệu, gói tin bắt tay, và gói tin đặc biệt.
Hình 8.4 cho thấy định dạng của một gói tin token, được sử dụng cho OUT, IN, SOF (bắt đầu của khung), và SETUP. Các gói tin có chứa một địa chỉ 7-bit, 4-bit ENDP (endpoint số), một checksum CRC có độ dài 5-bit, và một EOP (kết thúc gói).
Hình 8.4 : Gói tin token
Một gói tin dữ liệu sử dụng cho giao dịch dữ liệu DATA0, DATA1, DATA2 và MDATA . Định dạng gói tin như hình 8.5 bao gồm một PID, 0-1024 byte dữ liệu, 2 byte kiểm tra CRC, và một EOP
Hình 8.5 : Gói tin dữ liệu
Hình 8.6 cho thấy định dạng của một gói tin bắt tay, được sử dụng cho ACK, NAK, STALL, và NYET. ACK được sử dụng để báo bên nhận đã nhận được một gói tin không bị lỗi. NAK được sử dụng khi thiết bị nhận không thể chấp nhận gói tin. STALL cho thấy khi endpoint bị dừng lại, và NYET được sử dụng khi không có phản hồi từ bên nhận.
Hình 8.6 : Gói tin bắt tay
8.3.2 Kiểu luồng dữ liệu
Dữ liệu có thể truyền trên bus USB theo bốn cách: truyền số lượng lớn (bulk transfer), Truyền ngắt quản (interrupt transfer), Truyền đẳng thời (isochronous transfer) và truyền kiểm soát (control transfer)
Bulks transfers được thiết kế để truyền số lượng lớn dữ liệu với đảm bảo dữ liệu truyền không có lỗi và không đảm bảo băng thông. Nếu một enpoint Out được xác định sử dụng Bulks transfers khi đó host sẽ truyền dữ liệu đến nó sử dụng OUT transaction. Tương tự, nếu một In endpoint được xác định sử dụng bulk transfers, khi đó host sẽ truyền dữ liệu sử dụng IN transaction. Nói chung, bulk transfers được sử dụng nơi mà truyền tốc độ chậm không là vấn đề lớn. Kích thước gói tin tối đa trong một bulk transfer là 8 đến 64 gói tin tại tốc độ full speed, và 512 gói tin tại tốc độ truyền high speed (bulk transfer không cho phép tại low speed)
Interrupt transfers được sử dụng để truyền số lượng nhỏ dữ liệu với băng thông cao nơi dữ liệu phải truyền nhanh nhất có thể và không được trễ. lưu ý rằng interrupt tranfers không ảnh hưởng đến interrupts (ngắt) của hệ thống máy tính. Gói tin interrupts có kích thước từ 1 đến 8 byte tại tốc độ truyền low speed, từ 1 đến 64 byte tại full speed và lên đến 1024 byte tại high speed.
Isochronous transfers (Truyền đẳng thời) đảm bảo được băng thông, nhưng không đảm bảo lỗi của dữ liệu truyền. Đây là thể loại truyền sử dụng trong các ứng dụng chẳng hạn như truyền dữ liệu âm thanh nơi tốc độ là quan trọng nhưng có thể sai sót một vài dữ liệu. Một gói tin isochronous có thể chứa đựng 1023 bytes tại tốc độ full speed hoặc lên đến 1024 byte tại high speed (isochronous tranfer không được hỗ trợ tại low speed).
Control transfer là loại truyền dữu liệu hai chiều, sử dụng cả hai IN endpoint và out endpoint. control tranfers thường được sử dụng cho cấu hình khởi tạo thiết bị bởi host . Kích thước gói tin tối đa là 8 byte tại tốc độ thấp, 8 đến 64 byte tại tốc độ full speed , và 64 byte tại tốc độ high speed. Một control tranfer được thực thi theo ba giai đoạn SETUP (thiết lập), DATA (dữ liệu), và STATUS (trạng thái).
8.3.3 Qúa trình liệt kê (Enumeration):
Khi một thiết bị kết nối đến bus USB, nó được nhận biết bởi host thông qua một quá trình gọi là enumeration. Các bước của enumeration là:
- Khi một thiết bị được kết nối đến bus USB, host nhận thức được thiết bị bởi một trong các đường dữ liệu (D+ hoặc D-) được kéo lên mức cao.
- Host gửi đến thiết bị một tín hiệu reset để đặt thiết bị vào trạng thái biết đến (known state) . Thiết bị reset phản hồi với địa chỉ 0.
- Host gửi một yêu cầu đến đến thiết bị tại địa chỉ 0 để tìm kích thước gói tin tối đa bởi sử dụng lệnh Get Descriptor.
- Thiết bị hồi đáp bởi gửi một phần bộ miêu tả thiết bị.
- Host gửi tín hiệu reset lần nữa.
- Host gán cho thiết bị một địa chỉ duy nhất và gửi một yêu cầu thiết lập địa chỉ đến thiết bị. Sau khi yêu cầu đã hoàn tất, thiết bị thừa nhận địa chỉ mới này. Tại thời điểm này host được giải phóng để reset các thiết bị khác mới gắn lên bus .
- Host gửi một yêu cầu Get Device Descriptor để nhận bộ miêu tả thiết bị đầy đủ, thu thập thông tin như nhà sản xuất, loại thiết bị, và kích thước gói tin control tối đa
- Host gửi một yêu cầu Get Configuration Descriptors để nhận dữ liệu cấu hình thiết bị chẳng hạn như nguồn yêu cầu và thể loại và số giao diện hỗ trợ
- Host có thể yêu cầu bất kỳ mô tả thêm từ thiết bị .
Các giao tiếp ban đầu giữa host và thiết bị được thực hiện bằng cách sử dụng kiểu luồng dữ liệu Control transfer.
Ban đầu, thiết bị được cấp địa chỉ nhưng ở trạng thái chưa cấu hình. Sau khi host thu thập đủ thông tin về thiết bị, nó nạp trình điều khiển thiết bị (driver) phù hợp với cấu hình thiết bị bởi gửi đến thiết bị một yêu cầu Set Configuration. tại điểm này thiết bị đã được cấu hình và giao dịch gửi nhận dữ liệu có thể bắt đầu
8.4 Mô tả (Descriptor):
Tất cả các thiết bị USB có một hệ thống phân cấp các mô tả mô tả tính năng khác nhau của thiết bị: ID nhà sản xuất, phiên bản của thiết bị, phiên bản của USB nó hỗ trợ, thiết bị là gì, yêu cầu nguồn của thiết bị, số lượng và loại enpoints , và vân vân.
Các mô tả USB phổ biến nhất là:
Device descriptors (Mô tả thiết bị )
Configuration descriptors (mô tả cấu hình)
Interface descriptors ( Mô tả giao diện)
HID descriptors (mô tả HID)
Endpoint descriptors ( mô tả Endpoint)
Configuration descriptors (mô tả cấu hình)
Interface descriptors ( Mô tả giao diện)
HID descriptors (mô tả HID)
Endpoint descriptors ( mô tả Endpoint)
Các mô tả là một cấu trúc phân cấp như trong hình 8.7. Ở phía trên của hệ thống phân cấp, chúng ta có các mô tả thiết bị, sau đó mô tả các cấu hình, tiếp theo là các mô tả giao diện, và cuối cùng là mô tả Endpoint. Bộ mô tả HID luôn đi theo các mô tả giao diện khi giao diện thuộc về lớp HID.
Tất cả các mô tả có một định dạng phổ biến. Các byte đầu tiên (bLength) quy định rõ chiều dài của mô tả, trong khi các byte thứ hai (bDescriptorType) chỉ ra các loại mô tả.
Tất cả các mô tả có một định dạng phổ biến. Các byte đầu tiên (bLength) quy định rõ chiều dài của mô tả, trong khi các byte thứ hai (bDescriptorType) chỉ ra các loại mô tả.
Hình 8.7: Phân cấp các mô tả USB
8.4.1 Mô tả thiết bị (device descriptor)
Miêu tả thiết bị là thông tin thiết lập mức cao nhất đọc từ thiết bị và đây là bộ mô tả đầu tiên mà host đọc từ thiết bị.
Thiết bị USB chỉ có một mô tả thiết bị, khi đó mô tả thiết bị đại diện cho toàn bộ thiết bị. Nó cung cấp những thông tin cơ bản nhất chẳng hạn như nhà sản xuất, số serial, số sản phẩm , phân lớp thiết bị, và số của cấu hình. Bảng 8.5 mô tả định dạng của mô tả thiết bị với ý nghĩa của các trường .
bLength là độ dài của mô tả thiết bị.
bDescriptorType là kiểu của mô tả., và là hằng số 0x01
bcdUSB là phiên bảng cao nhất của USB mà thiết bị hỗ trợ được biễu diễn theo định dạng BCD. Theo dạng 0JJMM với JJ là số phiên bảng chính, M là số phiên bảng thứ và N là số phiên bảng thứ lẻ. Ví dụ , USB 1.1 được biểu diễn là 00110.
bDeviceClass, bDeviceSubClass, and bDeviceProtocol được chỉ định bởi tổ chức USB và được sử dụng bởi hệ thống để tìm một phân lớp trình điều khiển cho các thiết bị.
bMaxPacketSize0 là kích thước gói lớn nhất nhận và truyền của endpoint 0.
idVendor được chỉ định bởi tổ chức USB và là ID của nhà cung cấp.
idProduct được chỉ định bởi nhà sản xuất và là ID của sản phẩm.
bcdDevice là số phát hành thiết bị và có định dạng giống như bcdUSB. Các nhà sản xuất sẽ gán giá trị này. Host có thể sử dụng giá trị này để quyết định nạp trình điều khiển .
iManufacturer, iProduct, và iSerialNumber là chi tiết về nhà sản xuất, sản phẩm và số serial của sản phẩm. Những trường này không bắt buộc và có thể set đến zero.
bNumConfigurations là số cấu hình thiết bị hỗ trợ.
bMaxPacketSize0. Kích thước gói tin tối đa của endpoint 0. Host sử dụng thông tin này trong các yêu cầu tiếp theo. Với thiết bị low speed , giá trị này là 8. Thiết bị full speed , giá trị có thể là 8, 16, 32 hoặc 64. High speed giá trị này là 64
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột. Chiều dài của mô tả là 18 byte (bLength = 18), và kiểu mô tả là 001 (bDescriptorType= 0 01). thiết bị hỗ trợ USB 1.1 (bcdUSB = 0 0110). bDeviceClass, bDeviceSubClass, và bDeviceProtocol được thiết lập bằng 0 để chỉ rằng thông tin lớp ở trong bộ miêu tả giao diện (interface descriptor). bMaxPacketSize0 được thiết lập bằng 8 để chỉ rằng kích thươc gói tin tối đa mà enpoint0 nhận và truyền là 8 byte, ba byte tiếp theo xác định ID nhà cung cấp , ID sản phẩm và số phiên bảng thiết bị. Ba byte tiếp theo chỉ mục trỏ đến chuổi thông tin về nhà sản xuất, sản phẩm, và số serial. Cuối cùng, chúng tôi tôi nhận thấy rằng thiết bị chuột chỉ có một cấu hình (bNumConfigurations = 1).
Offset | Các Trường | Giá trị | Miêu tả |
0 | bLength | 18 | Kích thước là 18 |
1 | bDescriptorType | 0x01 | Kiểu mô tả |
2 | bcdUSB | 0x0110 | Hỗ trợ USB 1.1 |
4 | bDeviceClass | 0x00 | Thông tin lớp trong mô tả giao diện |
5 | bDeviceSubClass | 0x00 | Thông tin lớp trong mô tả giao diện |
6 | bDeviceProtocol | 0x00 | Thông tin lớp trong mô tả giao diện |
7 | bMaxPacketSize0 | 8 | Kích thước gói tin tối đa |
8 | idVendor | 0x02A | XYZ Co Ltd. |
10 | idProduct | 0x1001 | chuột |
12 | bcdDevice | 0x0011 | Số phát hành thiết bị |
14 | iManufacturer | 0x20 | Chỉ mục trỏ đến chuổi thông tin về nhà sản xuất |
15 | iProduct | 0x21 | Chỉ mục trỏ đến chuổi thông tin về sản phẩm |
16 | iSerialNumber | 0x22 | Chỉ mục trỏ đến chuổi serial |
17 | bNumConfigurations | 1 | Số cấu hình có thể có |
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột
Packets (Gói tin)
Dữ liệu được truyền trên bus USB bên trong một gói tin. Một gói tin bắt đầu với một mô hình đồng bộ để cho phép đồng hồ thu được đồng bộ hóa với dữ liệu. Tiếp theo là dữ byte dữ liệu của gói, kết thúc với tín hiệu kết thúc gói tin.
Một byte định danh gói tin (PID) theo sau trường đồng bộ của mỗi gói tin USB. Một PID có chiều dài 4 bit, và 4 bit tiếp theo được lặp lại theo hình thức lấy bù. Có 14 giá trị PID khác nhau, nó được thể hiện trong bảng 8.4. Trong đó bao gồm một giá trị để dành và một giá trị khác được sử dụng hai lần, với ý nghĩa khác nhau.
Kiểu PID | Tên PID | Bits | Miêu tả |
Token | OUT IN SOF SETUP | 1110 0001 0110 1001 1010 0101 0010 1101 | Host to device transaction Device to host transaction Start of frame Setup command |
Data (Dữ liệu) | DATA0 DATA1 DATA2 MDATA | 1100 0011 0100 1011 1000 0111 0000 1111 | Data packet PID even Data packet PID odd Data packet PID high speed Data packet PID high speed |
Handshake (Bắt tay) | ACK NAK STALL NYET | 1101 0010 0101 1010 0001 1110 1001 0110 | Receiver accepts packet Receiver does not accept packet Stalled No response from receiver |
Special (Đặc biệt) | PRE ERR SPLIT PING Reserved | 0011 1100 0011 1100 0111 1000 1011 0100 1111 0000 | Host preample Split transaction error High-speed split transaction High-speed flow control Reserved |
Bảng 8.4
Có bốn định dạng gói tin, dựa trên PID nào bắt đầu gói tin: gói tin token, gói tin dữ liệu, gói tin bắt tay, và gói tin đặc biệt.
Hình 8.4 cho thấy định dạng của một gói tin token, được sử dụng cho OUT, IN, SOF (bắt đầu của khung), và SETUP. Các gói tin có chứa một địa chỉ 7-bit, 4-bit ENDP (endpoint số), một checksum CRC có độ dài 5-bit, và một EOP (kết thúc gói).
Hình 8.4 : Gói tin token
Một gói tin dữ liệu sử dụng cho giao dịch dữ liệu DATA0, DATA1, DATA2 và MDATA . Định dạng gói tin như hình 8.5 bao gồm một PID, 0-1024 byte dữ liệu, 2 byte kiểm tra CRC, và một EOP
Hình 8.5 : Gói tin dữ liệu
Hình 8.6 cho thấy định dạng của một gói tin bắt tay, được sử dụng cho ACK, NAK, STALL, và NYET. ACK được sử dụng để báo bên nhận đã nhận được một gói tin không bị lỗi. NAK được sử dụng khi thiết bị nhận không thể chấp nhận gói tin. STALL cho thấy khi endpoint bị dừng lại, và NYET được sử dụng khi không có phản hồi từ bên nhận.
Hình 8.6 : Gói tin bắt tay
8.3.2 Kiểu luồng dữ liệu
Dữ liệu có thể truyền trên bus USB theo bốn cách: truyền số lượng lớn (bulk transfer), Truyền ngắt quản (interrupt transfer), Truyền đẳng thời (isochronous transfer) và truyền kiểm soát (control transfer)
Bulks transfers được thiết kế để truyền số lượng lớn dữ liệu với đảm bảo dữ liệu truyền không có lỗi và không đảm bảo băng thông. Nếu một enpoint Out được xác định sử dụng Bulks transfers khi đó host sẽ truyền dữ liệu đến nó sử dụng OUT transaction. Tương tự, nếu một In endpoint được xác định sử dụng bulk transfers, khi đó host sẽ truyền dữ liệu sử dụng IN transaction. Nói chung, bulk transfers được sử dụng nơi mà truyền tốc độ chậm không là vấn đề lớn. Kích thước gói tin tối đa trong một bulk transfer là 8 đến 64 gói tin tại tốc độ full speed, và 512 gói tin tại tốc độ truyền high speed (bulk transfer không cho phép tại low speed)
Interrupt transfers được sử dụng để truyền số lượng nhỏ dữ liệu với băng thông cao nơi dữ liệu phải truyền nhanh nhất có thể và không được trễ. lưu ý rằng interrupt tranfers không ảnh hưởng đến interrupts (ngắt) của hệ thống máy tính. Gói tin interrupts có kích thước từ 1 đến 8 byte tại tốc độ truyền low speed, từ 1 đến 64 byte tại full speed và lên đến 1024 byte tại high speed.
Isochronous transfers (Truyền đẳng thời) đảm bảo được băng thông, nhưng không đảm bảo lỗi của dữ liệu truyền. Đây là thể loại truyền sử dụng trong các ứng dụng chẳng hạn như truyền dữ liệu âm thanh nơi tốc độ là quan trọng nhưng có thể sai sót một vài dữ liệu. Một gói tin isochronous có thể chứa đựng 1023 bytes tại tốc độ full speed hoặc lên đến 1024 byte tại high speed (isochronous tranfer không được hỗ trợ tại low speed).
Control transfer là loại truyền dữu liệu hai chiều, sử dụng cả hai IN endpoint và out endpoint. control tranfers thường được sử dụng cho cấu hình khởi tạo thiết bị bởi host . Kích thước gói tin tối đa là 8 byte tại tốc độ thấp, 8 đến 64 byte tại tốc độ full speed , và 64 byte tại tốc độ high speed. Một control tranfer được thực thi theo ba giai đoạn SETUP (thiết lập), DATA (dữ liệu), và STATUS (trạng thái).
Khi một thiết bị kết nối đến bus USB, nó được nhận biết bởi host thông qua một quá trình gọi là enumeration. Các bước của enumeration là:
- Khi một thiết bị được kết nối đến bus USB, host nhận thức được thiết bị bởi một trong các đường dữ liệu (D+ hoặc D-) được kéo lên mức cao.
- Host gửi đến thiết bị một tín hiệu reset để đặt thiết bị vào trạng thái biết đến (known state) . Thiết bị reset phản hồi với địa chỉ 0.
- Host gửi một yêu cầu đến đến thiết bị tại địa chỉ 0 để tìm kích thước gói tin tối đa bởi sử dụng lệnh Get Descriptor.
- Thiết bị hồi đáp bởi gửi một phần bộ miêu tả thiết bị.
- Host gửi tín hiệu reset lần nữa.
- Host gán cho thiết bị một địa chỉ duy nhất và gửi một yêu cầu thiết lập địa chỉ đến thiết bị. Sau khi yêu cầu đã hoàn tất, thiết bị thừa nhận địa chỉ mới này. Tại thời điểm này host được giải phóng để reset các thiết bị khác mới gắn lên bus .
- Host gửi một yêu cầu Get Device Descriptor để nhận bộ miêu tả thiết bị đầy đủ, thu thập thông tin như nhà sản xuất, loại thiết bị, và kích thước gói tin control tối đa
- Host gửi một yêu cầu Get Configuration Descriptors để nhận dữ liệu cấu hình thiết bị chẳng hạn như nguồn yêu cầu và thể loại và số giao diện hỗ trợ
- Host có thể yêu cầu bất kỳ mô tả thêm từ thiết bị .
Các giao tiếp ban đầu giữa host và thiết bị được thực hiện bằng cách sử dụng kiểu luồng dữ liệu Control transfer.Ban đầu, thiết bị được cấp địa chỉ nhưng ở trạng thái chưa cấu hình. Sau khi host thu thập đủ thông tin về thiết bị, nó nạp trình điều khiển thiết bị (driver) phù hợp với cấu hình thiết bị bởi gửi đến thiết bị một yêu cầu Set Configuration. tại điểm này thiết bị đã được cấu hình và giao dịch gửi nhận dữ liệu có thể bắt đầu
8.4 Mô tả (Descriptor):
Tất cả các thiết bị USB có một hệ thống phân cấp các mô tả mô tả tính năng khác nhau của thiết bị: ID nhà sản xuất, phiên bản của thiết bị, phiên bản của USB nó hỗ trợ, thiết bị là gì, yêu cầu nguồn của thiết bị, số lượng và loại enpoints , và vân vân.
Các mô tả USB phổ biến nhất là:
Device descriptors (Mô tả thiết bị )
Configuration descriptors (mô tả cấu hình)
Interface descriptors ( Mô tả giao diện)
HID descriptors (mô tả HID)
Endpoint descriptors ( mô tả Endpoint)
Các mô tả là một cấu trúc phân cấp như trong hình 8.7. Ở phía trên của hệ thống phân cấp, chúng ta có các mô tả thiết bị, sau đó mô tả các cấu hình, tiếp theo là các mô tả giao diện, và cuối cùng là mô tả Endpoint. Bộ mô tả HID luôn đi theo các mô tả giao diện khi giao diện thuộc về lớp HID.Configuration descriptors (mô tả cấu hình)
Interface descriptors ( Mô tả giao diện)
HID descriptors (mô tả HID)
Endpoint descriptors ( mô tả Endpoint)
Tất cả các mô tả có một định dạng phổ biến. Các byte đầu tiên (bLength) quy định rõ chiều dài của mô tả, trong khi các byte thứ hai (bDescriptorType) chỉ ra các loại mô tả.
Hình 8.7: Phân cấp các mô tả USB
8.4.1 Mô tả thiết bị (device descriptor)
Miêu tả thiết bị là thông tin thiết lập mức cao nhất đọc từ thiết bị và đây là bộ mô tả đầu tiên mà host đọc từ thiết bị.
Thiết bị USB chỉ có một mô tả thiết bị, khi đó mô tả thiết bị đại diện cho toàn bộ thiết bị. Nó cung cấp những thông tin cơ bản nhất chẳng hạn như nhà sản xuất, số serial, số sản phẩm , phân lớp thiết bị, và số của cấu hình. Bảng 8.5 mô tả định dạng của mô tả thiết bị với ý nghĩa của các trường .
bLength là độ dài của mô tả thiết bị.
bDescriptorType là kiểu của mô tả., và là hằng số 0x01
bcdUSB là phiên bảng cao nhất của USB mà thiết bị hỗ trợ được biễu diễn theo định dạng BCD. Theo dạng 0JJMM với JJ là số phiên bảng chính, M là số phiên bảng thứ và N là số phiên bảng thứ lẻ. Ví dụ , USB 1.1 được biểu diễn là 00110.
bDeviceClass, bDeviceSubClass, and bDeviceProtocol được chỉ định bởi tổ chức USB và được sử dụng bởi hệ thống để tìm một phân lớp trình điều khiển cho các thiết bị.
bMaxPacketSize0 là kích thước gói lớn nhất nhận và truyền của endpoint 0.
idVendor được chỉ định bởi tổ chức USB và là ID của nhà cung cấp.
idProduct được chỉ định bởi nhà sản xuất và là ID của sản phẩm.
bcdDevice là số phát hành thiết bị và có định dạng giống như bcdUSB. Các nhà sản xuất sẽ gán giá trị này. Host có thể sử dụng giá trị này để quyết định nạp trình điều khiển .
iManufacturer, iProduct, và iSerialNumber là chi tiết về nhà sản xuất, sản phẩm và số serial của sản phẩm. Những trường này không bắt buộc và có thể set đến zero.
bNumConfigurations là số cấu hình thiết bị hỗ trợ.
bMaxPacketSize0. Kích thước gói tin tối đa của endpoint 0. Host sử dụng thông tin này trong các yêu cầu tiếp theo. Với thiết bị low speed , giá trị này là 8. Thiết bị full speed , giá trị có thể là 8, 16, 32 hoặc 64. High speed giá trị này là 64
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột. Chiều dài của mô tả là 18 byte (bLength = 18), và kiểu mô tả là 001 (bDescriptorType= 0 01). thiết bị hỗ trợ USB 1.1 (bcdUSB = 0 0110). bDeviceClass, bDeviceSubClass, và bDeviceProtocol được thiết lập bằng 0 để chỉ rằng thông tin lớp ở trong bộ miêu tả giao diện (interface descriptor). bMaxPacketSize0 được thiết lập bằng 8 để chỉ rằng kích thươc gói tin tối đa mà enpoint0 nhận và truyền là 8 byte, ba byte tiếp theo xác định ID nhà cung cấp , ID sản phẩm và số phiên bảng thiết bị. Ba byte tiếp theo chỉ mục trỏ đến chuổi thông tin về nhà sản xuất, sản phẩm, và số serial. Cuối cùng, chúng tôi tôi nhận thấy rằng thiết bị chuột chỉ có một cấu hình (bNumConfigurations = 1).
Offset | Các Trường | Giá trị | Miêu tả |
0 | bLength | 18 | Kích thước là 18 |
1 | bDescriptorType | 0x01 | Kiểu mô tả |
2 | bcdUSB | 0x0110 | Hỗ trợ USB 1.1 |
4 | bDeviceClass | 0x00 | Thông tin lớp trong mô tả giao diện |
5 | bDeviceSubClass | 0x00 | Thông tin lớp trong mô tả giao diện |
6 | bDeviceProtocol | 0x00 | Thông tin lớp trong mô tả giao diện |
7 | bMaxPacketSize0 | 8 | Kích thước gói tin tối đa |
8 | idVendor | 0x02A | XYZ Co Ltd. |
10 | idProduct | 0x1001 | chuột |
12 | bcdDevice | 0x0011 | Số phát hành thiết bị |
14 | iManufacturer | 0x20 | Chỉ mục trỏ đến chuổi thông tin về nhà sản xuất |
15 | iProduct | 0x21 | Chỉ mục trỏ đến chuổi thông tin về sản phẩm |
16 | iSerialNumber | 0x22 | Chỉ mục trỏ đến chuổi serial |
17 | bNumConfigurations | 1 | Số cấu hình có thể có |
8.4.2 Bộ mô tả cấu hình:
Bộ mô tả cấu hình cung cấp các thông tin về nguồn điện yêu cầu của thiết bị và nó hỗ trợ bao nhiêu giao diện khác nhau. Có thể có nhiều hơn một bộ cấu hình cho một thiết bị.
Bảng 8.7 cho ta thấy định dạng của bộ mô tả cấu hình và ý nghĩa của mỗi trường
bLength là chiều dài của bộ mô tả
bDescriptorType là kiểu mô tả , là hằng số 0x002
wTotalLength là kích thước tổng cộng của bộ các mô tả (ví dụ, tổng số mô tả cấu hình + bộ mô tảgiao diện + bộ mô tả HID + bộ mô tả endpoint). Khi bộ mô tả cấu hình được đọc bởi host, nó sẽ trả về các toàn bộ thông tin cấu hình, trong đó bao gồm tất cả các mô tả giao diện và mô tả endpoint.
bDescriptorType là kiểu mô tả , là hằng số 0x002
wTotalLength là kích thước tổng cộng của bộ các mô tả (ví dụ, tổng số mô tả cấu hình + bộ mô tảgiao diện + bộ mô tả HID + bộ mô tả endpoint). Khi bộ mô tả cấu hình được đọc bởi host, nó sẽ trả về các toàn bộ thông tin cấu hình, trong đó bao gồm tất cả các mô tả giao diện và mô tả endpoint.
bNumInterfaces là số giao diện hiện có cấu hình này
bConfigurationValue được sử dụng bởi các máy chủ (trong lệnh SetConfiguration) để chọn cấu hình.
iConfiguration là chỉ số trỏ đến chuỗi bộ mô tả miêu tả cấu hình theo định dạng có thể đọc.
bmAttributes mô tả các yêu cầu điện của thiết bị. Nếu thiết bị sử dụng điện trên bus USB, khi đó bit D7 được set (dùng cho phiên bảng USB 1.0) đối với các phiên bảng hiện nay thì điều này thực hiện thông qua bMaxPower. Bit D6 được set nếu nó dùng nguồn điện cấp từ bên ngoài . Bit D7 và D0-D4 là các bit để dành, bit D5 dùng cho remote wakeup, nó cho phép thiết bị đánh thức host khi host đang ở chế độ ngủ (suspend)
bMaxPower xác định công suất nguồn tối đa thiết bị tiêu thụ trên bus với đơn vị 2mA .
bConfigurationValue được sử dụng bởi các máy chủ (trong lệnh SetConfiguration) để chọn cấu hình.
iConfiguration là chỉ số trỏ đến chuỗi bộ mô tả miêu tả cấu hình theo định dạng có thể đọc.
bmAttributes mô tả các yêu cầu điện của thiết bị. Nếu thiết bị sử dụng điện trên bus USB, khi đó bit D7 được set (dùng cho phiên bảng USB 1.0) đối với các phiên bảng hiện nay thì điều này thực hiện thông qua bMaxPower. Bit D6 được set nếu nó dùng nguồn điện cấp từ bên ngoài . Bit D7 và D0-D4 là các bit để dành, bit D5 dùng cho remote wakeup, nó cho phép thiết bị đánh thức host khi host đang ở chế độ ngủ (suspend)
bMaxPower xác định công suất nguồn tối đa thiết bị tiêu thụ trên bus với đơn vị 2mA .
Offset | Field | Size | Description |
0 | bLength | 1 | Kích thước bộ miêu tả được tín đơn vị là byte |
1 | bDescriptorType | 1 | Device descriptor (0 02) |
2 | wTotalLength | 2 | Total bytes returned |
4 | bNumInterfaces | 1 | Số giao diện |
5 | bConfigurationValue | 1 | Value used to select configuration |
6 | iConfiguration | 1 | Index describing configuration string |
7 | bmAttributes | 1 | Power supply attributes |
8 | bMaxPower | 2 | Max power consumption in 2mA |
Bảng 8.8 ví dụ bộ mô tả cấu hình của thiết bị chuột. Chiều dài của bộ mô tả là 9 byte (bLength=9), và kiểu mô tả là 002 (bDescriptorType=0 02). Kích thước tổng của bộ mô tả là 34 (wTotalLength=34). Số giao diện cho thiết bị chuột là 1 (bNumInterfaces=1). Lệnh SetConfiguration của host phải sử dụng giá trị 1 như là tham số trong SetConfiguration() để chọn cấu hình. Không có chuỗi mô tả cấu hình này. bmAttributesis được thiết lập đến 040 để chỉ rằng thiết bị self-powered. bMaxPower được thiết lập bằng 10 để chỉ rằng dòng tối đa cho thiết bị là 20mA .
Offset | Field | Giá trị | Description |
0 | bLength | 9 | Kích tước bộ miêu tả là 9 byte |
1 | bDescriptorType | 0x02 | Device descriptor (0 x02) |
2 | wTotalLength | 34 | 34 byte |
4 | bNumInterfaces | 1 | Số giao diện là 1 |
5 | bConfigurationValue | 1 | Giá trị được sử dụng để lựa chọn cấu hình |
6 | iConfiguration | 0x2A | Index describing configuration string |
7 | bmAttributes | 0x40 | Power supply attributes |
8 | bMaxPower | 10 | tiêu thụ nguồn tối đa là 20mA |
8.4.3 Bộ mô tả giao diện
Bộ mô tả giao diện chỉ định lớp của giao diện và số endpoint được sử dụng. Có thể có nhiều hơn một giao diện.
Bảng 8.9 là định dạng của mô tả giao diện với ý nghĩa của từng trường
Offset | Trường | Kích cỡ | Miêu tả |
0 | bLength | 1 | Tính theo byte |
1 | bDescriptorType | 1 | Device descriptor (0 x04) |
2 | bInterfaceNumber | 1 | số giao diện |
3 | bAlternateSetting | 1 | Value to select alternate setting |
4 | bNumEndpoints | 1 | Số endpoints |
5 | bInterfaceClass | 1 | Mã lớp |
6 | bInterfaceSubClass | 1 | Mã lớp con |
7 | bInterfaceProtocol | 1 | Mã giao thức |
8 | iInterface | 1 | Index of string descriptor to interface |
Bảng 8.9: Bộ miêu tả giao diện
bLength là chiều dài của bộ mô tả.
bDescriptorType là kiểu mô tả.
bInterfaceNumber chỉ ra các chỉ số của các mô tả giao diện.
bAlternateSetting có thể được sử dụng để xác định các giao diện khác mà có thể được lựa chọn bởi máy chủ sử dụng lệnh Set Interface.
bNumEndpoints chỉ ra số lượng các endpoint được sử dụng bởi giao diện.
bInterfaceClass quy định cụ thể các mã lớp thiết bị (do tổ chức USB cấp).
bInterfaceSubClass chỉ định mã thiết bị phân lớp con (do tổ chức USB cấp).
bInterfaceProtocol chỉ định mã giao thức thiết bị (cấp bởi tổ chức USB)
iInterface là chỉ số trỏ đến một chuỗi miêu tả của giao diện.
bDescriptorType là kiểu mô tả.
bInterfaceNumber chỉ ra các chỉ số của các mô tả giao diện.
bAlternateSetting có thể được sử dụng để xác định các giao diện khác mà có thể được lựa chọn bởi máy chủ sử dụng lệnh Set Interface.
bNumEndpoints chỉ ra số lượng các endpoint được sử dụng bởi giao diện.
bInterfaceClass quy định cụ thể các mã lớp thiết bị (do tổ chức USB cấp).
bInterfaceSubClass chỉ định mã thiết bị phân lớp con (do tổ chức USB cấp).
bInterfaceProtocol chỉ định mã giao thức thiết bị (cấp bởi tổ chức USB)
iInterface là chỉ số trỏ đến một chuỗi miêu tả của giao diện.
Bảng 8.10 là ví dụ của bộ mô tả giao diện cho thiết bị chuột. Chiều dài bộ mô tả là 9 byte (blength=9) và kiểu mô tả là 0x04 (bDescriptorType = 0 04). Số giao diện sử dụng để tham chiếu giao diện này là 1 (bInterfaceNumber=1).
Offset | Trường | Giá trị | Miêu tả |
0 | bLength | 9 | Tính theo byte |
1 | bDescriptorType | 0x04 | Device descriptor (0 x04) |
2 | bInterfaceNumber | 0 | số giao diện |
3 | bAlternateSetting | 0 | Giá trị để chọn thiết lập thay thế |
4 | bNumEndpoints | 1 | Số endpoints |
5 | bInterfaceClass | 0x03 | Mã lớp là 0x03 |
6 | bInterfaceSubClass | 0x02 | Mã lớp con là 0x02 |
7 | bInterfaceProtocol | 0x02 | Mã giao thức là 0x02 |
8 | iInterface | 0 | Chỉ số của chuỗi mô tả giao diện |
bAlternateSetting được thiết lập bằng 0 ( ví dụ, không có giao diện thay thế). Số enpoint sử dụng bởi giao diện này là 1 (không kể endpoint 0), và đây là endpoint sử dụng cho chuột để gửi dữ liệu. Mã lớp thiết bị là 0x03 (bInterfaceClass = 0 x03). Đây là kiểu lớp HID (human interface device) . Lớp con giao diện là 0x02. Giao thức thiết bị là 0x02 (chuột). Không có chuỗi mô tả trong giao diện này interface (iInterface = 0).
8.4.4 Bộ mô tả HID.
Bộ mô tả HID luôn luôn theo sau bộ mô tả giao diện khi bộ giao diện thuộc về lớp HID. Bảng 8.11 là định dạng của bộ mô tả HID.
bLength là chiều dài của bộ mô tả của thiết bị.
bDescriptorType là kiểu bộ mô tả của thiết bị .
bcdHID là phân lớp chỉ định HID.
bCountryCodespecifies Chỉ định mã quốc gia.
bNumDescriptors quy định cụ thể nếu có bất kỳ mô tả bổ sung liên quan với lớp này.
bDescriptorType là loại mô tả bổ sung quy định tại bNumDescriptors.
wDescriptorLeng Là chiều dài của bộ mô tả thêm tính bằng byte
bLength là chiều dài của bộ mô tả của thiết bị.
bDescriptorType là kiểu bộ mô tả của thiết bị .
bcdHID là phân lớp chỉ định HID.
bCountryCodespecifies Chỉ định mã quốc gia.
bNumDescriptors quy định cụ thể nếu có bất kỳ mô tả bổ sung liên quan với lớp này.
bDescriptorType là loại mô tả bổ sung quy định tại bNumDescriptors.
wDescriptorLeng Là chiều dài của bộ mô tả thêm tính bằng byte
Offset | Trường | Kích thước | Mô tả |
0 | bLength | 1 | Kích thước bộ mô tả tính theo đơn vị byte |
1 | bDescriptorType | 1 | HID (0x21) |
2 | bcdHID | 2 | Lớp HID |
4 | bCountryCode | 1 |
Mã phụ thuộc từng quốc gia riêng
|
5 | bNumDescriptors | 1 | Số mô tả thêm |
6 | bDescriptorType | 1 |
Loại mô tả thêm
|
7 | wDescriptorLength | 2 | Chiều dài của bộ mô tả thêm |
Bảng 8.12 là một ví dụ bộ mô tả HID cho một thiết bị chuột. Chiều dài của mô tả là 9 byte (bLength = 9), và loại mô tả là 0x21 (bDescriptorType = 0x21). Lớp HID được thiết lập là 1.1 (bcdHID=0x0110). Mã quốc gia được thiết lập = 0.
Offset | Field | Giá trị | Mô tả |
0 | bLength | 9 | Bộ mô tả có kích thước là 9 byte |
1 | bDescriptorType | 0 x 21 | HID (0x21) |
2 | bcdHID | 0 x 0110 | Phân lớp phiên bảng 1.1 |
4 | bCountryCode | 0 | Mã không phụ thuộc vào quốc gia riêng nào |
5 | bNumDescriptors | 1 | Số bộ mô tả thêm |
6 | bDescriptorType | REPORT | Kiểu bộ mô tả thêm |
7 | wDescriptorLength | 5 | Chiều dài của bộ mô tả thêm |
8.4.5 Bộ mô tả Endpoint (Endpoint Descriptor)
Bộ mô tả endpoint chỉ định thể loại truyền, hướng truyền, thời gian hỏi vòng (polling interval) và kích thước tối đa của gói tin cho mỗi endpoint. Endpoint 0 (zero) là endpoint mặc định , nó là endpoint control và không có mô tả.
Bảng 8.13 cho ta thấy định dạng của bộ mô tả endpoint
bLength : là chiều dài của bộ mô tả
bDescriptorType : là thể loại bộ mô tả
bEndpointAddress : là địa chỉ của endpoint
bDescriptorType : là thể loại bộ mô tả
bEndpointAddress : là địa chỉ của endpoint
- Bit 3...0: Endpoint số- Bit 6...4: Để dành, thiết lập bằng 0- Bit 7: Hướng truyền, Ngoại trừ control endpoints.
+ 0 = OUT endpoint+ 1 = IN endpoint
bmAttributes : quy định cụ thể những loại endpoint của nó.
- Bits 1..0: Kiểu truyền
+ 00 = Control+ 01 = Isochronous+ 10 = Bulk+ 11 = Interrupt
Đối với endpoint không đẳng thời (non-isochronous), bit 5..2 phải được thiết lập bằng 0. Đối với endpoint đẳng thời (isochronous), chúng được định nghĩa như sau
- Bits 3..2: Kiểu đồng bộ
+ 00 = No Synchronization+ 01 = Asynchronous+ 10 = Adaptive+ 11 = Synchronous
- Bits 5..4: Kiểu sử dụng
+ 00 = Data+ 01 = Feedback+ 10 = Implicit feedback+ 11 = Reserved
Tất cả các bit khác là để dành và phải thiết lập bằng 0
wMaxPacketSize : là kích thước gói tin tối đa mà endpoint có khả năng gửi và nhận
bIntervalspecifies : độ thường xuyên mà các endpoint nên hỏi vòng (tính trong đơn vị ms).
Offset | Trường | Kích cỡ | Bộ mô tả |
0 | bLength | 1 | Kích thước bộ mô tả tính theo byte. |
1 | bDescriptorType | 1 | Endpoint (0x05). |
2 | bcdEndpointAddress | 1 | Địa chỉ của endpoint. |
4 | bmAttributes | 1 | Thể loại Endpoint |
5 | wMaxPacketSize | 2 | Kích thước gói tin tối đa |
6 | bInterval | 1 | Thời gian thăm dò |
Bảng 8.13: Bộ mô tả Endpoints
Offset | Trường | Kích cỡ | Bộ mô tả |
0 | bLength | 7 | Kích thước bộ mô tả tính theo byte. |
1 | bDescriptorType | 0x05 | Endpoint (0x05). |
2 | bcdEndpointAddress | 0x50 | Địa chỉ của Endpoint. |
4 | bmAttributes | 0x03 | Loại Endpoint interrupt |
5 | wMaxPacketSize | 0x0002 | Kích thước gói tin tối đa là 2 |
6 | bInterval | 0x14 | Thời gian thăm dò là 20 ms |
Bảng 8.14: Bộ mô tả endpoint của thiết bị chuột
Bảng 8.14 là mộ ví dụ bộ mô tả endpoint của thiết bị chuột. Chiều dài của bộ mô tả là 7 byte (bLength = 7), và kiểu bộ mô tả là 0x05 ( bDescriptorType = 0x05). Địa chỉ của endpoint là 0x50 (bEndpointAddress = 0x 50). Endpoint này được sử dụng như là một interrupts endpoint (bmAttributes=0x 03). Kích thước gói tin tối đa là 2 (wMaxPacketSize=0x 02) để chỉ rằng gói tin lớn hơn 2 bytes sẽ không gửi từ endpoint. Endpoint nên được kiểm tra ít nhất sau mỗi 20 ms ( bInterval=0 x14).
Bộ mô tả chuỗi (String descriptors):
Bộ mô tả chuỗi cung cấp các thông tin mà con người có thể đọc và là tùy chọn. Nếu bộ mô tả chuỗi không được sử dụng, tất cả các trường chỉ mục chuỗi của các bộ mô tả đã đề cập phải được thiết lập bằng 0 để báo rằng không có bộ mô tả chuỗi.
Chuỗi được mã hóa theo mã Unicode và thiết bị có thể được hỗ trợ nhiều ngôn ngữ. Chỉ mục chuỗi 0 (String Index 0) trả về một danh sách các ngôn ngữ được hỗ trợ. Một danh sách các ID ngôn ngữ USB các thể tìm thấy tại Universal Serial Bus Language Identifiers (LANGIDs) version 1.0
Offset | Trường | Kích cỡ | Mô tả |
0 | bLength | 1 | Kích thước bộ mô tả tính theo byte |
1 | bDescriptorType | 1 | Bộ mô tả chuỗi (0x03) |
2 | wLANGID[0] | 2 | Hỗ trợ ngôn ngữ mã 0 (e.g. 0x0409 English - United States) |
4 | wLANGID[1] | 2 | Hỗ trợ ngôn ngữ mã 1 (e.g. 0x0c09 English - Australian) |
n | wLANGID[x] | 2 | Hỗ trợ ngôn ngữ mã x (e.g. 0x0407 German - Standard) |
Một số vi điều khiển PIC18 hỗ trợ giao tiếp USB. Ví dụ, các vi điều khiển PIC18F4550 hỗ trợ cả hai chuẩn USB low speed và full speed cho phép giao tiếp giữa PC và vi điều khiển . Các ví dụ ở chương này chúng ta sẽ sử dụng vi điều khiển PIC18F4550.
Hình 8.8 mô tả tổng quan về khối giao tiếp USB của pic PIC18F4550. Pin RC4 (pin 23) và RC5 (pin 24) của PORTC được sử dụng cho giao tiếp USB. RC4 là chân dữ liệu D- và RC5 là chân dữ liệu D+. Các điện trở kéo lên được tích hợp sẳn bên trong vi điều khiển có thể kích hoạt hoặc vô hiệu hóa (UPUEN = 0) nếu muốn. Khi đó ta có thể sử dụng các điện trở mắc thêm ở ngoài. Để hoạt động ở chế độ low speed một điện trở kéo lên bên trong hoặc bên ngoài kết nối với chân D-, ở chế độ full speed một điện trở kéo lên bên trong hoặc bên ngoài kết nối với chân D+.
Hoạt động của các mô-đun USB được cấu hình sử dụng ba thanh ghi điều khiển, và tổng cộng hai mươi hai thanh ghi được sử dụng để quản lý giao tiếp USB. Cấu hình của các thanh ghi là một nhiệm vụ rất phức tạp và không được đề cập trong cuốn sách này. Bạn đọc quan tâm có thể tham khảo datasheet của PIC18F4550.
Mô-đun USB trong pic18f4550
Các hàm trong hỗ trợ giao tiếp USB của trình biên dịch CCS
usb_init()
|
Khởi tạo phần cứng USB. Khi đó chờ thiết bị kết nối đến bus bằng một vòng lặp vô tận. Hàm sẽ kích hoạt cho phép chức năng ngắt USB
|
usb_init_cs()
|
Giống như usb_init(), nhưng nó không chờ thiết bị kết nối đến bus. Đây hữu ích khi thiết bị hoạt động không sử dụng nguồn cấp từ cổng USB và thiết bị có thể hoạt động mà không cần kết nối đến cổng USB
|
usb_task()
|
Nếu bạn sử dụng kết nối nhạy (connection sense), và sử dụng hàmusb_init_cs() , khi đó bạn gọi hàm này theo định kỳ để quan sát chân kết nối nhạy (connection sense pin). Khi PIC được kết nối đến BUS, hàm này sẽ khởi tạo (chuẩn bị) các khối ngoại vi giao tiếp USB. Khi thiết bị bị ngắt kết nối khỏi bus, nó sẽ reset USB stack và các khối ngoại vi. Hàm kích hoạt cho phép chức năng ngắt USB
|
Chú ý: trong ứng dụng bạn phải định nghĩa USB_CON_SENSE_PIN đến chân kết nối nhạy
| |
usb_detach()
|
Khi bạn ngắt kết nối PIC đến Bus. Hàm này được gọi tự động bởi usb_task() nếu kết nối bị mất, nhưng nó có thể gọi bởi người sử dụng.
|
usb_attach()
|
Khi kết nối PIC đến bus. Hàm này được gọi tự động bởi usb_task() nếu có kết nối , nhưng có thể gọi bởi người sử dụng.
|
usb_attached()
|
Trả về TRUE nếu thiết bị kết nối đến cổng USB. Một đoạn macro co nhiệm vụ quan sát chân được định nghĩa trong USB_CON_SENSE_PIN
|
Một vòng lặp vô tận chờ đến khi thiết bị được enumerated | |
usb_enumerated()
|
Trả lại TRUE nếu thiết bị được enumerated thành công bởi CPU. Nếu thiết bị đã được enumerated bởi PC, khi đó bạn có thể gửi/nhận các gói tin
|
usb_put_packet
(endpoint, data, len, tgl)
|
Đặt một gói tin vào một bộ đệm của endpoint được chỉ định. Trả lại TRUE nếu thành công, FALSE nếu buffer đang còn đầy với các gói tin trước
|
usb_puts
(endpoint, data, len,
timeout)
|
Đưa dữ liệu đến endpoint được chỉ định. Sự khác biệt giữa usb_puts() và usb_put_packet() là usb_puts() gửi liên tiếp nhiều gói tin nếu dữ liệu muốn gửi có kích thước lớn hơn kích thước gói tin
|
usb_kbhit(endpoint)
|
Hàm trả về TRUE nếu endpoint chỉ định có dữ liệu trong bộ đệm nhận
|
usb_get_packet
(endpoint, ptr, max)
|
Đọc tất cả các bytes từ bộ đệm của enpoint được chỉ định và con trỏ ptr trỏ đến địa chỉ lưu của byte. Hàm trả về số byte được lưu
|
usb_gets(endpoint, ptr,
max, timeout)
|
Đọc một thông điệp ( message ) từ endpoint được chỉ định. Sự khác biệt giữa usb_get_packet() and usb_gets() đó là usb_gets() chờ thông điệp nhận đầy đủ khi thông điệp được chứa nhiều hơn trong một gói tin. Trả về số byte được nhận
|
Các phần mềm phân tích giao thức USB
Nếu vì một lý do nào đó project về giao tiếp USB mà bạn làm không chạy, khi đó bộ phân tích giao thức USB có thể được sử dụng để kiểm tra dữ liệu truyền trên bus USB. Hiện nay có nhiều bộ phân tích giao thức USB trên thị trường. Có một vài bộ phân tích chuyên nghiệp nhưng có giá thành cao dựa trên nền tảng phần cứng khi sử dụng cần đặt mua một phần cứng chuyên dụng. Hầu hết các bộ phân tích giao thức USB miễn phí sử dụng bằng phần mềm. Ở bài này ta tìm hiểu hai phần mềm điển hình.
UVCView
UVCView là một phần mềm của hãng Microsoft dùng để hiển thị bộ mô tả của một thiết bị USB sau khi cắm vào máy. Hình 8.1 là cửa sổ hiển thị UVCView. Bên trái của cửa sổ hiển thị các port USB hiện có của máy. khi click chuột chọn cổng đang kết nối đến thiết bị USB sẽ hiển thị bộ mô tả chi tiết của thiết bị ở cửa sổ bên phải. Bạn có thể tải phần mềm tại đây:
USBTrace:
USBTrace là một phần mềm phân tích giao thức USB phát triển bởi hãng SysNucleus (www.sysnucleus.com). Phần mềm này theo dõi các cổng USB của máy tính và hiển thị tất các giao dịch trên Bus. Phần mềm là một công cụ vô giá khi ta muốn tất cả các giao dịch trên đường truyền phải được theo dõi và ghi lại. Trên trang web của hãng có phiên bảng dùng thử .
Trong bài này ta viết một chương trình firmware nhỏ cho PIC 18f4550, chương trình này mục đích để kiểm tra phần cứng giao tiếp USB, cũng như quá trình enumerated bởi PC thành công hay chưa, trong bài này có sử dụng công cụ phân tích UVCView (đã đề cập ở bài 7) để xem bộ mô tả thiết bị được đọc bởi máy tính |
Sơ đồ khối của ví dụ
Sơ đồ mạch của ví dụ
Các file bạn cần include vào project CCS là:
#include
#include
#include // Chứa các tác vụ quản lý các ngắt USB, các yêu cầu thiết lập USB của enpoint 0
#include
#include // Chứa các tác vụ quản lý các ngắt USB, các yêu cầu thiết lập USB của enpoint 0
Đoạn chương trình bên dưới thực hiện khởi tạo cổng USB và kiểm tra quá trình enumerated bởi máy tính và vi điều khiển PIC đã thành công hay chưa
#include <18F4550.h> #device ADC=8 #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL2,CPUDIV1,VREGEN #use delay(clock=48000000) #include #include #include /***************************************/ void main(void) { output_d(0x00); //tắt tất cả các led kết nối đến port B usb_init_cs(); Delay_ms(1000); while(1) { usb_task(); if(usb_enumerated()) { //nếu quá trình enumerated thành công , tại đây bạn có thể truyền và nhận dữ liệu
if(usb_kbhit(1))
{
} output_d(0xff); // nếu có dữ liệu trong bộ đệm nhận thì bật tất cả các đèn led } } } |
Sau khi biên dịch và kết nối đến cổng USB , một thông điệp xuất hiện báo máy tính đã nhận thiết bi
Ta mở chương trình UVCView để xem bộ mô tả của thiết bị USB ta mới gắn vào được đọc bởi máy tính:
Đây là bộ mô tả ví dụ của CCS trong file usb_desc_hid.h, các bạn có thể mở xem và chỉnh sửa cho phù hợp với ý muốn của mình.
Trong bài này tôi viết chương trình mẫu sử dụng C# (sử dụng thư viện Hidsharp) giao tiếp với PIC18F4550
Giới thiệu Hidshard:
Hidsharp là thư viện mã nguồn mở miễn phí giúp giao tiếp với thiết bị usb thông qua lớp HID bằng C#. Các bạn có thể xem chi tiết tại địa chỉ: https://www.zer7.com/software/hidsharp các bạn có thể tải phiên bảng mới nhất tại địa chỉ này hoặc tải tại đây.
Mở visual studio và tạo mới project với tên USB_Csharp
Add thư viện Hidshard bằng cách nhấn chuột phải lên tên project, chọn Add Reference trỏ đến thư viện Hidshard (file: HidSharp.dll) đã tải về ở trên.
Add 1 button và lable1, lable2 và chương trình chúng ta
Trong sự kiện nhấn nút, chèn đoạn code bên dưới vào:
Đoạn chương trình này có chức năng đơn giản là kết nối với thiết bị chúng ta thông qua lớp HID, sao đó gửi dữ liệu xuống vi điều khiển và nhận dữ liệu từ vi điều khiển gửi lên, hiển thị dữ liệu nhận bằng lable1 và lable2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| var loader = new HidDeviceLoader(); var device = loader.GetDevices(0x0461, 0x0020).FirstOrDefault(); if (device == null ) { MessageBox.Show( "Không tìm thấy thiết bị" ); return ; } HidStream stream; if (!device.TryOpen( out stream)) { MessageBox.Show( "Failed to open device." ); return ; } var message = new byte [] { 0, 0xaa }; stream.Write(message); byte [] mybyte = stream.Read(); label1.Text = mybyte[1].ToString(); label2.Text = mybyte[2].ToString(); |
Nhớ khai báo using HidSharp; ở đầu chương trình. Code hoàn chỉnh như bên dưới:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using HidSharp; namespace USB_Csharp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click( object sender, EventArgs e) { var loader = new HidDeviceLoader(); var device = loader.GetDevices(0x0461, 0x0020).FirstOrDefault(); if (device == null ) { MessageBox.Show( "Không tìm thấy thiết bị" ); return ; } HidStream stream; if (!device.TryOpen( out stream)) { MessageBox.Show( "Failed to open device." ); return ; } var message = new byte [] { 0, 0xaa }; stream.Write(message); byte [] mybyte = stream.Read(); label1.Text = mybyte[1].ToString(); label2.Text = mybyte[2].ToString(); } } } |
Đoạn chương trình viết bằng CCS trên pic 18f4550:
Chức năng của đoạn chương trình này: Đoạn chương trình dưới vi điều khiển làm chức năng đơn giản là sau khi nhận được 1 gói tin từ phần mềm C sharp trên máy tính gửi xuống, vi điều khiển sẽ tăng biến i lên 1 đơn vị vào gửi 1 gói tin này lên máy tính.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| #include <18F4550.h> #device ADC=8 #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN #use delay(clock=48000000) #include <pic18_usb.h> #include <usb_desc_hid.h> //USB Configuration and Device descriptors for this UBS device #include <usb.h> /***************************************/ void main( void ) { int i=0; int8 out_data[USB_CONFIG_HID_TX_SIZE]; int8 in_data[USB_CONFIG_HID_RX_SIZE]; //memset(in_data, 0x00, USB_CONFIG_HID_RX_SIZE); //memset(out_data, 0x00, USB_CONFIG_HID_TX_SIZE); set_tris_d(0x00); output_d(0x00); usb_init_cs(); Delay_ms(1000); while (1) { usb_task(); if (usb_enumerated()) { //nếu quá trình enumerated thành công , tới đây bạn có thể truyền và nhận dữ liệu if (usb_kbhit(1)) { usb_get_packet(1, in_data, USB_CONFIG_HID_RX_SIZE); usb_put_packet(1, out_data, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE); output_d(0xff); // nếu có dữ liệu trong bộ đệm nhận thì bật tất cả các dèn led out_data[1]=++i; out_data[2]=2; } } } } |
Không có nhận xét nào:
Đăng nhận xét