|
使用RT-THREAD1.21的usb host协议,由于对USB不熟悉,所以代码都是到处乱拼的:从ART把stm32f4xx_hcd.c移植过来,又参考adk.c来编写U盘的驱动,现在算是编译通过了,前面的枚举都成功,而且可以跑到rt_usb_mass_run();这rt_usb_mass_run()中对u盘进行挂载,然后跑到rt_udisk_read(),现在就卡在第二个 rt_usb_hcd_bulk_xfer()函数里面(红色表示)。单步进去,看到是state = HCD_GetURB_State(&USB_OTG_Core , channel),state一直等于URB_IDLE,导致一直死在这里。这个问题有没有人遇到过?
我看其他人仅用ST的库来做也遇到过state = HCD_GetURB_State(&USB_OTG_Core , channel),state一直返回URB_IDLE的,有的人说调整USB的中断优先级就可以解决了,但是我调整了还是不可以。
static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
uint8_t i;
uint16_t nbOfPages;
uifinst_t ifinst = (uifinst_t)dev->user_data;
umassinst_t udisk = (umassinst_t)ifinst->user_data;
struct ustorage_cbw read_cbw;
rt_size_t res;
if (NULL == dev || !size)
return -RT_ERROR;
if (Stat & STA_NOINIT)
return -RT_EBUSY;
size *= USBH_MSC_PAGE_LENGTH;
read_cbw.signature = USBH_MSC_BOT_CBW_SIGNATURE;
read_cbw.tag = USBH_MSC_BOT_CBW_TAG;
read_cbw.lun = 0; /*Only one LUN is supported*/
read_cbw.xfer_len = XFER_LEN_READ_CAPACITY10;
read_cbw.dflags = USB_EP_DIR_IN;
read_cbw.cb_len = CBW_LENGTH;
for(i = CBW_CB_LENGTH; i != 0; i--)
{
read_cbw.cb = 0x00;
}
read_cbw.cb[0] = SCSI_READ_10;
/*logical block address*/
read_cbw.cb[2] = (((uint8_t*)&pos)[3]);
read_cbw.cb[3] = (((uint8_t*)&pos)[2]);
read_cbw.cb[4] = (((uint8_t*)&pos)[1]);
read_cbw.cb[5] = (((uint8_t*)&pos)[0]);
/*USBH_MSC_PAGE_LENGTH = 512*/
nbOfPages = size/ USBH_MSC_PAGE_LENGTH;
/*Tranfer length */
read_cbw.cb[7] = (((uint8_t *)&nbOfPages)[1]) ;
read_cbw.cb[8] = (((uint8_t *)&nbOfPages)[0]) ;
res = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd,udisk->pipe_out,&read_cbw,31,300);
if(res < 0)
{
return res;
}
res = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd,udisk->pipe_in,buffer,size,300);
return res;
}
static rt_err_t rt_usb_mass_run(void* arg)
{
int i = 0;
umassinst_t adkinst;
uifinst_t ifinst = (uifinst_t)arg;
uintf_desc_t intf_desc;
rt_err_t ret;
/* parameter check */
if(ifinst == RT_NULL)
{
rt_kprintf("the interface is not available\n");
return -RT_EIO;
}
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_adk_run\n"));
intf_desc = ifinst->intf_desc;
if(intf_desc->bInterfaceClass != USB_CLASS_MASS_STORAGE)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("mass type err=%u\n",intf_desc->bInterfaceClass));
return -RT_EIO;
}
if(intf_desc->bInterfaceSubClass != USB_SUB_CLASS_MASS_STORE)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("mass_sub type err=%u\n",intf_desc->bInterfaceSubClass));
return -RT_EIO;
}
if(intf_desc->bInterfaceProtocol != MSC_PROTOCOL)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("protocal type err=%u\n",intf_desc->bInterfaceProtocol));
return -RT_EIO;
}
adkinst = rt_malloc(sizeof(struct umassinst));
RT_ASSERT(adkinst != RT_NULL);
/* initilize the data structure */
rt_memset(adkinst, 0, sizeof(struct umassinst));
ifinst->user_data = (void*)adkinst;
for(i=0; i<ifinst->intf_desc->bNumEndpoints; i++)
{
uep_desc_t ep_desc;
/* get endpoint descriptor from interface descriptor */
rt_usb_get_endpoint_descriptor(ifinst->intf_desc, i, &ep_desc);
if(ep_desc == RT_NULL)
{
rt_kprintf("rt_usb_get_endpoint_descriptor error\n");
return -RT_ERROR;
}
/* the endpoint type of adk class should be BULK */
if((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK)
continue;
/* allocate pipes according to the endpoint type */
if(ep_desc->bEndpointAddress & USB_DIR_IN)
{
/* allocate an in pipe for the adk instance */
ret = rt_usb_hcd_alloc_pipe(ifinst->uinst->hcd, &adkinst->pipe_in,
ifinst, ep_desc, RT_NULL);
if(ret != RT_EOK) return ret;
}
else
{
/* allocate an output pipe for the adk instance */
ret = rt_usb_hcd_alloc_pipe(ifinst->uinst->hcd, &adkinst->pipe_out,
ifinst, ep_desc, RT_NULL);
if(ret != RT_EOK) return ret;
}
}
/* check pipes infomation */
if(adkinst->pipe_in == RT_NULL || adkinst->pipe_out == RT_NULL)
{
rt_kprintf("pipe error, unsupported device\n");
return -RT_ERROR;
}
/* set configuration */
ret = rt_usb_set_configure(ifinst->uinst, 1);
if(ret != RT_EOK)
return ret;
/* register adk device */
adkinst->device.type = RT_Device_Class_Block;
adkinst->device.init = rt_udisk_init;
adkinst->device.open = rt_udisk_open;
adkinst->device.close = rt_udisk_close;
adkinst->device.read = rt_udisk_read;
adkinst->device.write = rt_udisk_write;
adkinst->device.control = rt_udisk_ioctl;
adkinst->device.user_data = (void*)ifinst;
rt_device_register(&adkinst->device, "udisk", RT_DEVICE_FLAG_RDWR);
#ifdef RT_USING_DFS_ELMFAT
/* mount sd card fat partition 1 as root directory */
if (dfs_mount("udisk", "/", "elm", 0, 0) == 0)
{
rt_kprintf("File System initialized!\n");
}
else
rt_kprintf("File System initialzation failed!\n");
#endif
return RT_EOK;
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|