原创 U盘例程在智林开发板上的移植

2010-5-1 21:58 4249 16 16 分类: MCU/ 嵌入式

 


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


一、移植前的准备工作


1、有哪些操作必须重新实现?


主要是三个函数:


1SD卡读扇区


2SD卡写扇区


3)获取SD卡的块数、每块字节数和总容量


这三个函数我以前实际上都实现了,但是用到这个例程中,还需要改变一些参数的对应问题。


 


2、为了更清晰的了解U盘的整个工作流程,在关键的地方加一些调试函数,向串口输出信息。


 


二、开始移植


1、准备源文件


usb目录下新建udisk目录,在其下建srcinc两个子目录。


usb_istr.cusb_pwr.cusb_desc.cusb_prop.chw_config.cusb_endp.cusb_bot.cusb_scsi.cscsi_data.cmemory.cmsd.cmain.c等共12个文件复制如src目录。


将相应的头文件复制入inc目录。


 


在工程里新建文件组,把所有c源文件加入工程。


 


2、添加命令udisk


当在串口输入udisk命令时,整个开发板将成为一个读卡器。


 


3、修改各个源文件的包含关系、单独编译


1)主程序main.c改变成“udisk”命令处理程序。


 


void UartCmdUsbMouse(u8 argc,void **argv){


  Uart_PutString ( "进入U盘实现过程!\r\n" );


  USB_Connect_Init();


  USB_Interrupts_Config();


  Set_USBClock();


  Get_Medium_Characteristics();


  USB_Init();


  while (1)


}


在这个过程中,去掉了Set_System()函数、led等配置函数等,这些函数都在hw_config.c文件中,该文件编译通过以后,再修改hw_config.c的函数实现。


 


2)修改hw_config.c


其它函数的修改在鼠标例程中已经分析过了,这里主要是以下这个函数:


void Get_Medium_Characteristics(void)


{


  u8 res;


  CardInfo MsdInfo;


  res=SD_GetCardInfo(&MsdInfo);


 


  if ( res == 0 ){


        Mass_Block_Count = MsdInfo.BlockNumber;


        Mass_Block_Size =  MsdInfo.BlockLength;


        Mass_Memory_Size = MsdInfo.Capacity;


  }


}


获取SD卡容量的函数重新修改,也不需要头文件msd.h了。


 


3)有9个文件只要修改头文件包含关系就行了


 


4)修改文件msd.c


因为我在sduser.c文件中已经实现了大部分的SD操作函数,所以这里实际上读卡、写卡函数调用以前编写的函数就行了。


当然,在入口参数有不一致的地方必须做调整。


u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)


{


   u8 res;


   rea = SD_WriteBlock ( WriteAddr>>9, pBuffer);


   if ( res == 0 )return res;


   return 0xFF;


}


读扇区的修改跟这个类似。


 


三、下载、测试和修改


1、整个工程编译,生成Hex文件,下载到开发板。


 


2、输入命令udisk


PC识别了该设备,但是磁盘为空。


这是串口发回来的消息。


 


Sh>udisk


进入U盘实现过程!


setup中断   80 06 00 01 00 00 40 00    获取设备描述符


设备准备发送12 字节: 12 01 00 02 00 00 00 40 83 04 20 57 00 01 01 02 03 01


IN令牌04 中断


OUT状态中断


 


setup中断  00 05 02 00 00 00 00 00  设置地址


IN状态中断


 


setup中断  80 06 00 01 00 00 12 00  获取设备描述符


设备准备发送12 字节: 12 01 00 02 00 00 00 40 83 04 20 57 00 01 01 02 03 01


IN令牌04 中断


OUT状态中断


 


setup中断    80 06 00 02 00 00 09 00    获取配置描述符


设备准备发送09 字节:   09 02 20 00 01 01 00 80 32


IN令牌04 中断


OUT状态中断


 


setup中断    80 06 00 03 00 00 FF 00     获取字符串描述符


设备准备发送04 字节:   04 03 09 04


IN令牌04 中断


OUT状态中断


 


setup中断    80 06 00 02 00 00 FF 00    获取配置描述符


设备准备发送20 字节:   09 02 20 00 01 01 00 80 32 09 04 00 00 02 08 06 50 04 07 05 81 02 40 00 00 07 05 02 02 40 00 00


IN令牌04 中断


OUT状态中断


 


setup中断   80 06 00 06 00 00 <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0A 00  这是与高速有关的,这里不支持。


 


setup中断   80 06 00 01 00 00 40 00    获取设备描述符


设备准备发送12 字节: 12 01 00 02 00 00 00 40 83 04 20 57 00 01 01 02 03 01


IN令牌04 中断


OUT状态中断


 


setup中断   00 09 01 00 00 00 00 00   设置配置


IN状态中断


 


setup中断  A1 FE 00 00 00 00 01 00  类请求:获取逻辑盘数量.


设备准备发送01 字节:   00


IN令牌04 中断


OUT状态中断


 


3、加入批量端点输入输出调试函数


在批量输出函数中,也加入调试命令,结果发现问题是“读格式化容量”和“读容量”命令没有返回正确的数值。


调整获取磁盘信息的函数,再次下载。程序就成功了。


下面是批量端口调试输出,有一些关键的信息再熟悉一下。


 


本次接收到 1F字节.


55 53 42 43 28 C5 BD 88 24 00 00 00 80 00 06 12 00 00 00 24 00 00 00 00 00 00 00 00 00 00 00


主机命令:查询.


本次发送 24 字节.


00 80 02 02 20 00 00 00 53 54 4D STM20 20 20 20 20 53 54 52 20 20 46 6C 61 73 68 20 44 69 73 6B 20 31 2E 30 20


本次发送 0D 字节.


命令状态封包:  55 53 42 53 28 C5 BD 88 00 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 80 78 C9 88 FC 00 00 00 80 00 0A 23 00 00 00 00 00 00 00 FC 00 00 00 00 00 00 00


主机命令:读格式化容量.


本次发送 0C字节.


00 00 00 08 00 0F 34 00 02 00 02 00  //这里计算出来是510M


本次发送 0D 字节.


命令状态封包:  55 53 42 53 80 78 C9 88 F0 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 28 C5 BD 88 08 00 00 00 80 00 0A 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


主机命令:读容量.


本次发送 08 字节.


00 0F 33 FF 00 00 02 00


本次发送 0D 字节.


命令状态封包:  55 53 42 53 28 C5 BD 88 00 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 28 C5 BD 88 00 02 00 00 80 00 0A 28 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  //0号扇区开始读,读1个扇区。


主机命令:读扇区.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.


本次发送扇区数据 40 字节.  //总共要读8次。


本次发送 0D 字节.


命令状态封包:  55 53 42 53 28 C5 BD 88 00 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 40 92 0B 89 C0 00 00 00 80 00 06 1A 00 1C00 C0 00 00 00 00 00 00 00 00 00 00 00  //这是个什么命令。


本次发送 04 字节.


03 00 00 00 #define SCSI_MODE_SENSE6  0x1A


本次发送 0D 字节.  //


命令状态封包:  55 53 42 53 40 92 0B 89 BC 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 70 6E FB 88 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


本次发送 0D 字节.  //测试是否准备好。


命令状态封包:  55 53 42 53 70 6E FB 88 00 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 28 C5 BD 88 00 10 00 00 80 00 0A 28 00 00 00 00 3F00 00 08 00 00 00 00 00 00 00


主机命令:读扇区.  //3F扇区开始,一次性读8个扇区。


//读取8个扇区的调试输出我删掉了,太长了。


本次发送 0D 字节.


命令状态封包:  55 53 42 53 28 C5 BD 88 00 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 28 C5 BD 88 00 10 00 00 80 00 0A 28 00 00 00 00 5F 00 00 08 00 00 00 00 00 00 00


主机命令:读扇区.//5F扇区开始是FAT表。


//读取8个扇区的调试输出我删掉了,太长了。


本次发送 0D 字节.


命令状态封包:  55 53 42 53 28 C5 BD 88 00 00 00 00 00


 


本次接收到 1F字节.


55 53 42 43 28 C5 BD 88 00 10 00 00 80 00 0A 28 00 00 00 00 67 00 00 08 00 00 00 00 00 00 00


主机命令:读扇区.  /这是再次读取FAT


//读取8个扇区的调试输出我删掉了,太长了。


本次发送 0D 字节.


命令状态封包:  55 53 42 53 28 C5 BD 88 00 00 00 00 00


以下,还有很长一段读取8个扇区的代码,我估计是把用到的FAT表读完了。


 


本次接收到 1F字节.


55 53 42 43 00 F8 EC 88 00 08 00 00 80 00 0A 28 00 00 00 07 FA 00 00 04 00 00 00 00 00 00 00


主机命令:读扇区.


本次发送 0D 字节.  //这次只读了四个扇区,我估计已经是根目录了,因为我设置的簇扇区个数为4利用sdrd读扇区的命令看了一下,果然是根目录区。


命令状态封包:  55 53 42 53 00 F8 EC 88 00 00 00 00 00


 


以下都是一些测试硬盘是否准备好的代码。而且这个代码始终不停的在发。


本次接收到 1F字节.


55 53 42 43 08 70 C1 88 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


本次发送 0D 字节.


命令状态封包:  55 53 42 53 08 70 C1 88 00 00 00 00 00


 


 

 


 


 

文章评论0条评论)

登录后参与讨论
我要评论
0
16
关闭 站长推荐上一条 /2 下一条