我最近采购了一款ART-Pi进行测试,发现板上有usb-otg的外设,我把它配置成了CDC设备,但是没有找到相关的资料。
能否提供一个loopback的demo。
在尝试了很长时间后,我发现了几个问题:
我想要向主机发送数据,于是用了rt_device_write方法,但是运行的时候提示设备没有write方法,于是我修改了drv_usbd.c文件中的内容,增加了write方法
static rt_size_t _write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
HAL_PCD_EP_Transmit(&_stm_pcd, 1, (uint8_t *)buffer, size);
return size;
}
并在stm_usbd_register函数中注册:_stm_udc.parent.write = _write(原本该函数中只注册了init方法)
下面是我在main函数中的task,art-pi收到任意消息后会回复hello,world给PC
extern uint8_t send_flag;
void usb_task(void* param)
{
usbd0 = rt_device_find("usbd");
const char usb_msg[15] = "hello, world!\n";
if(usbd0!=RT_NULL)
{
rt_kprintf("usbd found.\n");
if(rt_device_open(usbd0, RT_DEVICE_OFLAG_RDWR)==RT_EOK)
{
rt_kprintf("usbd open succesfully.\n");
}
}
else {
rt_kprintf("no available usbd device.\n");
return;
}
while(true)
{
//rt_device_write(usbd0, 0, usb_msg, sizeof(usb_msg));
if(send_flag)
{
rt_device_write(usbd0, 0, usb_msg, sizeof(usb_msg));
send_flag = 0;
}
rt_thread_mdelay(5);
}
}
但是这样修改了之后还是不行,会导致线程挂掉,我把rt_usbd_ep_in_handler注释了,才能够正常运行
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
if (epnum == 0)
{
rt_usbd_ep0_in_handler(&_stm_udc);
}
else
{
//rt_usbd_ep_in_handler(&_stm_udc, 0x80 | epnum, hpcd->IN_ep[epnum].xfer_count);
}
}
我想我这样写可能不符合设计者的本意,设计者本意是在rt_usbd_ep_in_handler中触发某个事件,然后发送信息,能否提供一份正确的示例程序。另外关于读取PC给art-pi的接收函数我也不知道怎么去作,下面是我现在的处理方式,肯定也不是正确的,但能够工作。
uint8_t send_flag;
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
uep_t ep;
ufunction_t func;
udevice_t device;
device = rt_usbd_find_device(&_stm_udc);
if (epnum != 0)
{
rt_usbd_ep_out_handler(&_stm_udc, epnum, hpcd->OUT_ep[epnum].xfer_count);
ep = rt_usbd_find_endpoint(device, &func, epnum);
if(ep != RT_NULL)
{
send_flag = 1;
rt_kprintf("%d bytes received, start with: %02X\n", hpcd->OUT_ep[epnum].xfer_count, *(uint8_t *)ep->buffer);
}
}
else
{
rt_usbd_ep0_out_handler(&_stm_udc, hpcd->OUT_ep[0].xfer_count);
}
}