在《USB系列之三》中,我們實現了一系列的SCSI命令,在這個系列中,我們要實現向U盤上寫扇區的命令,所以,本文相對比較容易,更多地是給出一個實現的源程序。
在《USB系列之三》中,我們實現的SCSI命令有:INQUIRY、READ CAPACITY(10)、TEST UNIT READY、REQUEST SENSE、READ(10);都是一些讀出的命令,所以不會破壞U盤的內容,在文檔SBC-2的第29頁有一個SCSI命令的表,在這個表中列出了所有的命令,其TYPE為“M”的都是SCSI設備必須實現的命令,這些命令有:
Num
|
Command Name
|
Operation Code
|
Type
|
Reference
|
1
|
FORMAT UNIT |
04h
|
M
|
SBC-2 |
2
|
INQUIRY |
12h
|
M
|
SPC-3 |
3
|
READ(6) |
08h
|
M
|
SBC-2 |
4
|
READ(10) |
28h
|
M
|
SBC-2 |
5
|
READ(16) |
88h
|
M
|
SBC-2 |
6
|
READ CAPACITY(10) |
25h
|
M
|
SBC-2 |
7
|
READ CAPACITY(16) |
9Eh/10h
|
M
|
SBC-2 |
8
|
REQUEST SENSE |
03h
|
M
|
SPC-3 |
9
|
SEND DIAGNOSTIC |
1Dh
|
M
|
SPC-3 |
10
|
TEST UNIT READY |
00h
|
M
|
SPC-3 |
11
|
WRITE(10) |
2Ah
|
O
|
SBC-2 |
這里面最后的一個命令并不是SBC-2中要求強制實現的,而是可選的,但如果我們不去實現,U盤的操作將失色很多;我們不打算去實現序號為1、3、5、7和9的命令,READ(6)、READ(16)和READ(10)十分相似,只是LBA的長度不同而已,如果需要實現,參考READ(10)就可以了,FORMAT和SEND DIAGNOSTIC兩個命令對使用芯片的U盤來說沒有什么意義,當然對硬盤是有意義的,所以在本文中,我們只需要實現一個很重要的WRTE(10),向U盤上寫數據,我們需要準備一張沒有有用數據的U盤,因為我們要改變其中的內容。
WRITE(10)源代碼下載地址:
http://blog.hengch.com/source/usb-write.zip
程序中,我們向《USB系列三》中的程序一樣,先reset,然后得到最大的LUN,這個步驟不是必須的,然后我們向device發出WRITE(10)命令,注意,這是一個OUT事務,所以,CBW_FLAGS=0X00而不是像以前一樣是0X80,發出WRITE(10)命令后,我們還要向device發送要寫入的數據,每次64個字節,一個扇區512字節需要啟動8個OUT事務,這個工作又函數putData完成,每次發送的64個字節我們分別寫入了0--63,程序中,我們把這些數據寫入到了LBA=100的扇區中,寫入后,我們在使用在《USB系列之三》中介紹過的READ(10)命令把相同的扇區讀出來,我們會看到我們所希望的結果,由于在讀之前,我們已經把buffer全部清為0了,所以我們有把握相信,我們讀到的數據是真實的。
到這里,我們已經把控制U盤的主要命令都介紹完了,利用DOSUSB,我們已經有可能為U盤編寫一個簡單的驅動程序,但可能我們還不知道DOS下的驅動程序該如何寫,從下一篇文章開始,我們將暫時放下USB系列文章,介紹一下DOS下驅動程序的寫法。