本文PDF文档下载
接着上节的SCSI 命令。
<!--[if !supportLists]-->● <!--[endif]-->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定义了数据的连续逻辑块的数量。
<!--[if !supportLists]-->● <!--[endif]-->WRITE(10)(Opcode 2Ah)
<!--[if !supportLists]-->● <!--[endif]-->REQUEST SENSE(6)(Opcode 03h)<?xml:namespace prefix = o />
<!--[if !supportLists]-->● <!--[endif]-->MODE SENSE(6)(Opcode 1Ah)
<!--[if !supportLists]-->● <!--[endif]-->PREVENT ALLOW MEDIUM REMOVAL(Opcode 1Eh)
<!--[if !supportLists]-->● <!--[endif]-->TEST UNIT READY(Opcode 00h)
<!--[if !supportLists]-->● <!--[endif]-->VERIFY(10)(Opcode 2Fh)
<!--[if !supportLists]-->● <!--[endif]-->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,而且返回‘<?xml:namespace prefix = st1 />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)。
用户137871 2009-5-31 15:30