问题描述
在使用 rt_thread 的USB库的时候发现,主动发送的数据容易出现丢PC端收不到的情况:
从调试的日志上看
snd seq:20 数据发送的应答已经发送过了但是PC端没有收到数据
于是研究 HID 类的函数,有发送成功的回调
static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
{
struct hid_s *data;
RT_ASSERT(func != RT_NULL);
RT_ASSERT(func->device != RT_NULL);
data = (struct hid_s *) func->user_data;
if(data->parent.tx_complete != RT_NULL)
{
data->parent.tx_complete(&data->parent,RT_NULL);
rt_kprintf("tx_complete s0\n");
}
rt_kprintf("tx_complete s1\n");
return RT_EOK;
}
看到这个 tx_complete 是一个回调函数, 发送数据的时候只有输出 “tx_complete s1”,于是查找代码,这个 tx_complete 的调用如下:
// device.c
/**
* This function will set the indication callback function when device has
* written data to physical hardware.
*
* @param dev the pointer of device driver structure
* @param tx_done the indication callback function
*
* @return RT_EOK
*/
rt_err_t
rt_device_set_tx_complete(rt_device_t dev,
rt_err_t (*tx_done)(rt_device_t dev, void *buffer))
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
dev->tx_complete = tx_done;
return RT_EOK;
}
RTM_EXPORT(rt_device_set_tx_complete);
于是显示这个函数
// 初始化
rt_device_t hiddev = rt_device_find("hidd");
/* 注册 USB 发送完成回调函数 */
rt_device_set_tx_complete(hiddev, usb_hid_tx_done);
/*打开查找到的 hid 设备 */
rt_device_open(hiddev, RT_DEVICE_FLAG_RDWR);
// 发送数据完成回调
rt_err_t usb_hid_tx_done(rt_device_t dev, void *buffer)
{
usb_stcb.busy = 0;
return RT_EOK;
}
// 阻塞发送:等待完成回调函数,增加5次重发(没有使用信号量)
void usb_hw_snd_pac(rt_device_t hiddev, usb_fs_pac_t *spac)
{
#define USB_SND_ONE_MS 5
uint8_t usb_wait_ms = 0;
do
{
if ((usb_wait_ms % USB_SND_ONE_MS) == 0)
{
rt_device_write(hiddev, 5, spac, 64);
usb_stcb.busy = 1;
}
rt_thread_mdelay(1);
usb_wait_ms++;
} while ((usb_stcb.busy == 1) && (usb_wait_ms < USB_SND_ONE_MS*5));
}
再次测试,就没有出现这个问题了