- /*-----------------------------------------------------------------------*/
 
- /* Read Sector(s)                                                        */
 
- /*-----------------------------------------------------------------------*/
 
- DRESULT disk_read (
 
-   BYTE pdrv,    /* Physical drive nmuber to identify the drive */
 
-   BYTE *buff,    /* Data buffer to store read data */
 
-   LBA_t sector,  /* Start sector in LBA */
 
-   UINT count    /* Number of sectors to read */
 
- )
 
- {
 
-   usb_sts_type status;
 
 
-   status = usbh_msc_read(&otg_core_struct.host, sector, count, buff, pdrv);
 
 
-   if(status == USB_OK)
 
-     return RES_OK;
 
 
-   return RES_ERROR;
 
- }
 
磁盘数据读取函数的内部是调用了USB主机的读数据函数“usbh_msc_read”,这个函数在上面说的USB主机数据处理接口函数“usbh_msc_class.c”中,通过usbh_msc_read调用USB主机的数据读写中断控制函数“usbh_msc_rw_handle”来执行相应的数据处理。在这里要注意,因为是读取数据,所以函数中先赋值了“pmsc->l_unit_n[lun].state = USBH_MSC_READ10;”来告诉事件执行读数据处理。
- usb_sts_type usbh_msc_read(void *uhost, uint32_t address, uint32_t len, uint8_t *buffer, uint8_t lun)
 
- {
 
-   usbh_core_type *puhost = (usbh_core_type *)uhost;
 
-   usbh_msc_type *pmsc = (usbh_msc_type *)puhost->class_handler->pdata;
 
-   uint32_t timeout = 0;
 
-   if(puhost->conn_sts == 0 || puhost->global_state != USBH_CLASS
 
-     || pmsc->l_unit_n[lun].state != USBH_MSC_IDLE)
 
-   {
 
-     return USB_FAIL;
 
-   }
 
-   pmsc->bot_trans.msc_struct = &usbh_msc;
 
-   pmsc->l_unit_n[lun].state = USBH_MSC_READ10;
 
-   pmsc->use_lun = lun;
 
 
-   timeout = puhost->timer;
 
 
-   while(usbh_msc_rw_handle(uhost, address, len, buffer, lun) == USB_WAIT)
 
-   {
 
-     if(puhost->conn_sts == 0 || (puhost->timer - timeout) > (len * 10000))
 
-     {
 
-       pmsc->l_unit_n[lun].state = USBH_MSC_IDLE;
 
-       return USB_FAIL;
 
-     }
 
-   }
 
-   return USB_OK;
 
- }
然后"usbh_msc_rw_handle"通过调用“usb_sts_type usbh_msc_bot_scsi_read”创建“usbh_cmd_read”函数读取数据。- usb_sts_type usbh_msc_bot_scsi_read(void *uhost, msc_bot_trans_type *bot_trans,
 
-                                      uint32_t address, uint8_t *read_data,
 
-                                      uint32_t read_len, uint8_t lun)
 
- {
 
-   usb_sts_type status = USB_WAIT;
 
-   switch(bot_trans->cmd_state)
 
-   {
 
-     case CMD_STATE_SEND:
 
-       usbh_bot_cbw(&bot_trans->cbw, read_len * 512,
 
-                    MSC_READ_CMD_LEN, MSC_CBW_FLAG_IN);
 
-       bot_trans->cbw.bCBWLUN = lun;
 
-       usbh_cmd_read(bot_trans, bot_trans->cbw.CBWCB, lun, read_len, address, read_data);
 
-       bot_trans->cmd_state = CMD_STATE_WAIT;
 
-       bot_trans->bot_state = BOT_STATE_SEND_CBW;
 
-     break;
 
 
-     case CMD_STATE_WAIT:
 
-       status = usb_bot_request(uhost, bot_trans);
 
-       if(status == USB_OK)
 
-       {
 
-          bot_trans->cmd_state = CMD_STATE_SEND;
 
-       }
 
-       if(status == USB_FAIL)
 
-       {
 
-         bot_trans->cmd_state = CMD_STATE_SEND;
 
-       }
 
-       break;
 
-     default:
 
-       break;
 
-   }
 
-   return status;
 
- }
USB主机的事件处理,在main.c中,通过“usbh_init(&otg_core_struct,USB_FULL_SPEED_CORE_ID, USB_ID, &uhost_msc_class_handler, &usbh_user_handle)”中定义“uhost_msc_class_handler”和“usbh_user_handle”创建USB主机接口和用户数据处理接口。
然后通过主while循环不断调用“usbh_loop_handler(&otg_core_struct.host)”事件处理USB接口状态监测及相关事件处理。
在“uhost_msc_class_handler”中申明了USB接口主机相关的底层接口处理事件。
- usbh_class_handler_type uhost_msc_class_handler =
 
- {
 
-  uhost_init_handler,
 
-  uhost_reset_handler,
 
-  uhost_request_handler,
 
-  uhost_process_handler,
 
-  &usbh_msc
 
- };
- usbh_user_handler_type usbh_user_handle =
 
- {
 
-   usbh_user_init,
 
-   usbh_user_reset,
 
-   usbh_user_attached,
 
-   usbh_user_disconnect,
 
-   usbh_user_speed,
 
-   usbh_user_mfc_string,
 
-   usbh_user_product_string,
 
-   usbh_user_serial_string,
 
-   usbh_user_enumeration_done,
 
-   usbh_user_application,
 
-   usbh_user_active_vbus,
 
-   usbh_user_not_support,
 
- };
- static usb_sts_type usbh_user_application(void)
 
- {
 
-   usb_sts_type status = USB_OK;
 
-   FRESULT res;
 
 
-   uint32_t len;
 
-   uint8_t write_data[] = "usb host msc demo";
 
-   uint8_t read_data[32] = {0};
 
 
-   switch(usr_state)
 
-   {
 
-     case USR_IDLE:
 
-       usr_state = USR_APP;
 
-       break;
 
-     case USR_APP:
 
-       res = f_mount(&fs, "", 0);
 
-       if(res == FR_OK)
 
-       {
 
-         /* start write data */
 
-         if(f_open(&file, "0:AT32.txt", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
 
-         {
 
-           // error
 
-           USBH_DEBUG("Open AT32.txt failed");
 
-         }
 
-         else
 
-         {
 
-           res = f_write(&file, write_data, sizeof(write_data), &len);
 
-           if(res != FR_OK || len == 0)
 
-           {
 
-             //write error
 
-             USBH_DEBUG("Write AT32.txt failed");
 
-           }
 
-           else
 
-           {
 
-             //write success
 
-             USBH_DEBUG("Write AT32.txt Success");
 
-           }
 
-           f_close(&file);
 
-         }
 
 
-         /* start read file */
 
-         if(f_open(&file, "0:AT32.txt", FA_READ) != FR_OK)
 
-         {
 
-           // error
 
-           USBH_DEBUG("Open AT32.txt failed");
 
-         }
 
-         else
 
-         {
 
-           res = f_read(&file, read_data, sizeof(read_data), &len);
 
-           if(res != FR_OK || len == 0)
 
-           {
 
-             //read error
 
-             USBH_DEBUG("Read AT32.txt failed");
 
-           }
 
-           else
 
-           {
 
-             //read success
 
-             USBH_DEBUG("Read AT32.txt Success");
 
-           }
 
-           f_close(&file);
 
-         }
 
-         f_mount(NULL, "", 0);
 
-       }
 
-       usr_state = USR_FINISH;
 
-       break;
 
-     case USR_FINISH:
 
-       break;
 
-   }
 
-   return status;
 
- }
 
程序分析完成,最后我们编绎并下载到开发板,将开发板上的J8调试串口通过USB转串口模块连接到PC上,在开发板上的USB主机接口(TYPE-A)中插入一个在PC上格式化好的U盘(注意U盘格式化时,要选择格式为FAT32),这时有串口调试助手上会打印出开发板检测到U盘执行的相关事件信息。
 
当串口助手打印出“Read AT32.txt Success”的信息后,从开发板上拨出U盘,再插到电脑上,打开U盘,会发现在U盘的根目录下,开发板往U盘里创建了一个名为"AT32.TXT"的文件,打开这个txt文件,可以发现里面写入了代码中写入的字符“usb host msc demo”。
 
 
至此,本次测试完成,相关的代码分析也完成。