苏华显
苏华显

注册于 10 months ago

回答
2
文章
0
关注者
0

分区分错了吧, 最大512K , param 那里应该从0x64000开始刚好512K,如果从0x74000开始就超过了512K了.

之前祼机编程时,在发送数据之前都会清空接收缓冲如下代码:
rec_cnt = 0; /接收计数清空/
rec_finish = 0; /接收完成标志清空/
send_data(buf, 10); /发送数据/

如果不清空,那么这前的数据会保留:
如之前有数据在接收缓冲区123,
那再次收到时数据时变成 123456,
显然,有时候我们不想这样,因为新的接收一帧是错误的,本来接收456数据才是正确。这对一问一答的协议非常不好,只有问了才应答,不问时,却收到了数据则要丢弃。
目前查看了源码并未有清除函数操作。但可以用读取函数来清空缓冲,效率可能低了些,经过测试,性能稳定。
读取接收清空操作:rt_device_read(serial, 0, buf,0,config.bufsz);
其中config.bufsz初始化时设置是接收最大接收量。
在中断回调函数里使用邮箱,邮箱只容纳一个邮件,邮件发送数据为串口DMA空闲接收到的一包数据的字节数量。经过优化后程序如下:
while(1)
{

rt_thread_mdelay(5);
rt_device_read(encoder_serial, 0, rx_buf,0,config.bufsz); /*清空接收数据缓冲,*/
rt_mb_recv(&encoder_mb,&rec_size,0);                      /*清空邮件*/
encoder_t.send_buf[0] = 0x19;                             /*读角度值*/     
rt_device_write(encoder_serial, 0,encoder_t.send_buf, 1);           
result = rt_mb_recv(&encoder_mb, &rec_size, 100);         /*接收等待超时100ms*/
if(result == RT_EOK)   
{
    rx_len = rt_device_read(encoder_serial, 0, rx_buf, rec_size);  /*接收数据*/   
    if(rx_len > 6) 
    {
        parse_data((encoder_msg_typedef*)rx_buf);  /*解析数据*/
    }
}

}
通过以上代码实现了祼机编程思路,如果觉得有用,可以参考,有写得不好,欢迎大家拍砖。

看打印信息偏移地址写错了,应该改为0x80000

大家好,通过调试打印输出已经找到问题的所在了,主要是在第一次读取端点0数据返回的wMaxPacketSize = 8, rtthread这个表达式,
send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size;
实际赋值 8 = (18 > 8)? 8:18 ,因此发送的只是请求返回前8个字节的设备描述符,使得出现返回的只有8个字节, 和读取18个字节
的设备描述符对不上,打印出get full device descriptor failed,
而U盘之所以能正常是因为第一次读取端点0数据返回wMaxPacketSize = 64, 实际赋值 18 = (18> 64)? 64:18,即send_size = 18,
因此能正常读回完整的设备描述符. 通过读读取全部设备描述符时增加测试debug_dat代码人为更改send_size = 18, 可以读取
全部设备描述符了.,官方的USB HOST U盘程序 只能枚举wMaxPacketSize > 18字节的,小于的话,像鼠标类8字节会枚举失败。:)

if(debug_dat)
{
send_size = 18;
}

int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout)
{
rt_size_t remain_size;
rt_size_t send_size;
remain_size = nbytes;
rt_uint8_t * pbuffer = (rt_uint8_t *)buffer;
do
{
RT_DEBUG_LOG(RT_DEBUG_USB,("pipe transform remain size,: %d\n", remain_size));
send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size;
RT_DEBUG_LOG(RT_DEBUG_USB,("pipe->ep.wMaxPacketSize = %d\r\n", pipe->ep.wMaxPacketSize));
RT_DEBUG_LOG(RT_DEBUG_USB,("send_size = %d\r\n", send_size));
if(debug_dat)
{
send_size = 18;
}
if(hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, pbuffer, send_size, timeout) == send_size)
{
remain_size -= send_size;
pbuffer += send_size;
}
else
{
return 0;
}
}while(remain_size > 0);
return nbytes;
}

rt_err_t rt_usbh_attatch_instance(uinst_t device)
{
int i = 0;
rt_err_t ret = RT_EOK;
struct uconfig_descriptor cfg_desc;
udev_desc_t dev_desc;
uintf_desc_t intf_desc;
uep_desc_t ep_desc;
rt_uint8_t ep_index;
upipe_t pipe;
ucd_t drv;

RT_ASSERT(device != RT_NULL);

rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor));
dev_desc = &device->dev_desc;

/* alloc address 0 ep0 pipe*/
ep0_out_desc.wMaxPacketSize = 8;
ep0_in_desc.wMaxPacketSize = 8;
rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc);
rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc);

RT_DEBUG_LOG(RT_DEBUG_USB, ("start enumnation\n"));

/* get device descriptor head */
ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8);
if(ret != RT_EOK)
{
rt_kprintf("get device descriptor head failed\n");
return ret;
}

/* reset bus */
rt_usbh_hub_reset_port(device->parent_hub, device->port);
rt_thread_delay(2);
rt_usbh_hub_clear_port_feature(device->parent_hub, i + 1, PORT_FEAT_C_CONNECTION);
/* set device address */
ret = rt_usbh_set_address(device);
if(ret != RT_EOK)
{
rt_kprintf("set device address failed\n");
return ret;
}
/* free address 0 ep0 pipe*/

rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out);
rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in);

/* set device max packet size */
ep0_out_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0;
ep0_in_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0;

/* alloc true address ep0 pipe*/
rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc);
rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc);
RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n",
dev_desc->bLength));

/* get full device descriptor again */
ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength);
if(ret != RT_EOK)
{
rt_kprintf("get full device descriptor failed\n");
return ret;
}

RT_DEBUG_LOG(RT_DEBUG_USB, ("Vendor ID 0x%x\n", dev_desc->idVendor));
RT_DEBUG_LOG(RT_DEBUG_USB, ("Product ID 0x%x\n", dev_desc->idProduct));

/* get configuration descriptor head */
ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, &cfg_desc, 18);
if(ret != RT_EOK)
{
rt_kprintf("get configuration descriptor head failed\n");
return ret;
}

/* alloc memory for configuration descriptor */
device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength);

/* get full configuration descriptor */
ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION,
device->cfg_desc, cfg_desc.wTotalLength);
if(ret != RT_EOK)
{
rt_kprintf("get full configuration descriptor failed\n");
return ret;
}

/* set configuration */
ret = rt_usbh_set_configure(device, 1);
if(ret != RT_EOK)
{
return ret;
}
for(i=0; icfg_desc->bNumInterfaces; i++)
{
/* get interface descriptor through configuration descriptor */
ret = rt_usbh_get_interface_descriptor(device->cfg_desc, i, &intf_desc);
if(ret != RT_EOK)
{
rt_kprintf("rt_usb_get_interface_descriptor error\n");
return -RT_ERROR;
}

RT_DEBUG_LOG(RT_DEBUG_USB, ("interface class 0x%x, subclass 0x%x\n",
intf_desc->bInterfaceClass,
intf_desc->bInterfaceSubClass));
/* alloc pipe*/
for(ep_index = 0; ep_index < intf_desc->bNumEndpoints; ep_index++)
{
rt_usbh_get_endpoint_descriptor(intf_desc, ep_index, &ep_desc);
if(ep_desc != RT_NULL)
{
if(rt_usb_hcd_alloc_pipe(device->hcd, &pipe, device, ep_desc) != RT_EOK)
{
rt_kprintf("alloc pipe failed\n");
return RT_ERROR;
}
rt_usb_instance_add_pipe(device,pipe);
}
else
{
rt_kprintf("get endpoint desc failed\n");
return RT_ERROR;
}
}
/* find driver by class code found in interface descriptor */
drv = rt_usbh_class_driver_find(intf_desc->bInterfaceClass,
intf_desc->bInterfaceSubClass);

if(drv != RT_NULL)
{
/* allocate memory for interface device */
device->intf

    = (struct uhintf*)rt_malloc(sizeof(struct uhintf));
    device->intf
      ->drv = drv;
      device->intf
        ->device = device;
        device->intf
          ->intf_desc = intf_desc;
          device->intf
            ->user_data = RT_NULL;

            /* open usb class driver */
            ret = rt_usbh_class_driver_enable(drv, (void*)device->intf
              );
              if(ret != RT_EOK)
              {
              rt_kprintf("interface %d run class driver error\n", i);
              }
              }
              else
              {
              rt_kprintf("find usb device driver failed\n");
              continue;
              }
              }

              return RT_EOK;
              }

发布
问题