发表于
2008-7-1 7:50:41
接着上节的SCSI 命令。
● READ(10)(Opcode 28h)
READ(10)命令定义了设备服务器读指定的逻辑块(Logical blocks)并且将数据发送到Data-In 缓冲区。READ(10)命令是在第18和第19字节定义了TRANSFER LENGTH的10字节的CBWCB。(参考:“SCSI Command and Data Format”)。TRANSFER LENGTH定义了数据的连续逻辑块的数量。
● WRITE(10)(Opcode 2Ah)
● REQUEST SENSE(6)(Opcode 03h)
● MODE SENSE(6)(Opcode 1Ah)
● PREVENT ALLOW MEDIUM REMOVAL(Opcode 1Eh)
● TEST UNIT READY(Opcode 00h)
● VERIFY(10)(Opcode 2Fh)
● START/STOP(Opcode 1Bh)
不支持的命令
如果CBWCB中的命令操作码是不支持的,SENSE KEY被设为无效请求,表示CDB中有无效的参数。
MASS STORAGE 设备(MSD)固件
本固件实现了一个支持SD卡的USB Mass Storage 设备。当插入USB口后,固件将SD卡枚举为可移动磁盘而且允许用户执行磁盘驱动的所有功能。用户可以像操作任何可移动磁盘一样的写,读,编辑和删除 MSD上的文件。本应用也允许用户将SD卡格式化为下列的FAT文件格式:FAT16,FAT32或NTFS。固件通过读取SD卡的CSD 寄存器(Card Specific Data)计算SD卡的容量。这些信息通过响应READ
CAPACITY命令将SD卡容量信息返回给PC 主机。磁盘的准确容量可以通过观察PC上的磁盘属性获得。
FW目录结构
(frm注:全部的Firmware可以从Microchip的网站下载。)
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en024394
图6显示了MSD应用的FW的目录结构。

函数功能描述
表1和表2对msd.c和sdcard.c文件中的函数进行了描述。


内存管理
数据内存的Data Bank
4~7被映射到特定的双口RAM(见例程2)。当USB模块被禁用时,这些Bank中的通用功能寄存器(General Purpose Registers
GPRs)也可像数据内存空间中的其它Bank的GPRs一样使用。当USB模块有效后,内存中的这些Bank被分配为USB操作的缓冲RAM。这些区域由MCU的核与SIE共享,用于两者之间的数据交换。注意,链接器的脚本已经将MSD定义为512字节的单数据Bank。512字节 msd_buffer已经在MSD数据Bank中定义了(见例程1)。

图7显示了包括端点缓冲的完整的内存映射。
FW描述
图8显示了FW中各文件间的相互关系。USB框架文件的更详细描述可以通过PICDEM
FS USB演示板的用户指南获得。本AN仅注重USB Mass Storage应用和SD 卡通信。
USB请求可以分为标准请求或类相关请求。USB标准请求由USBCheckStdRequest()函数处理。它负责处理USB2.0规范的第9章描述的标准请求。Msd.c中的固件负责处理USB
Mass Storage类规定的请求。如果有USBCheckStdRequest()不能处理的请求,它会调用USBCheckMSDRequest()函数。USBCheckMSDRequest()函数判断请求是否是一个类相关请求。(SetupPkt.RequestType==CLASS)而且SetupPkt.bRequest==FFh(Bulk-Only Mass Storage Reset)或FEh(Get Max LUN)。如果收到了Bulk-Only Mass Storage Reset请求,FW清除STALL状态并且开始初始化Endpoint1。Get Max LUN请求的响应是包含设备支持的最大LUN数的一个字节。例如,如果设备支持3个LUN,那么LUN的序号为0~2,而且返回‘2’。本应用中,LUN为1,所以返回值为‘0’。
Usb9.c主要处理USB枚举过程。USBStdSetCfgHandler()函数处理SET_CONFIGURATION请求。这个函数调用函数MSDInitEP()。函数MSDInitEP()配置并初试化一个Bulk-In和一个Bulk-Out端点。
Main.c文件中的main()函数实现一个无限循环来执行两个不同的任务-USB或Mass Storage应用任务。USB任务由USBDriverService()函数来处理。它负责处理全部的USB硬件中断。Mass Storage任务由ProcessIO()函数处理。
(frm注:main()函数的代码及说明)
void main(void)
{
InitializeSystem();
while(1)
{
USBTasks(); // USB Tasks—此处调用了USBDriverService()函数
ProcessIO(); // See msd.c
& msd.h
}
//end while
}//end main
ProcessIO()函数是mass storage 与端点1通信的核心。图9显示了ProcessIO()函数的流程。
当端点1被初始化后,MSD_State被设置为MSD_WAIT。FW基本上是在等待Endpoint1接收CBW。如果接收到一个有意义的CBW,就要将CSW的数据准备好。基本上是将CBW中的dCBWTag拷贝到CSW的dCSWTag中,并将dCSWSignature设置为“53425355h”。读取Direction位来判断数据传输的方向(例如,从主机到设备或相反)并将MSD_State设置为MSD_DATA_OUT或MSD_DATA_IN(详见图10)。

这篇够长,争取下一篇将这个AN学完。就要进入实际的USB Mass Storage开发的实验了。
待续...................