usb拷贝buf数据,有没有类似原子操作,拷贝组装数据稍微大一点,数据会出错

在端点2里面组装一个1024byte数据,组装完拷贝出去,发现有时部分64byte数据会出错,被新值覆盖



in offset = 0;

u8 usb_tmp_buf[1024] = {0};

u8 my_buf[1024] = {0};


case UIS_TOKEN_OUT | 2://端点2 Out

{

    len = R8_USB_RX_LEN;

    memcpy(&usb_tmp_buf[offset], pEP2_OUT_DataBuf, len); //组装数据每次最大64byte

    offset += len;


    if(offset>=1024)

    {

        //有没有 可以 暂停usb pEP2_OUT_DataBuf接收 

        memcpy(my_buf,  usb_tmp_buf , 1024); //发现拷贝数据时间比较长,pEP2_OUT_DataBuf数据更新了,来不及接收,后面会覆盖

        // 打开usb pEP2_OUT_DataBuf接收


        offset = 0;

    }


    //没有其他操作,清中断,退出中断

    ....


}

芯片是ch579


有没有一种可能,memcpy前先NAK,拷贝完数据再ACK这种骚操作


附注:

测试过了,usb会暂停,是不是打开方式不对,

给点思路  :)


用两个buf或许可以?复制数据之前把buf换成另一个,下次复制再换回来,交替执行


出错的64字节中,是大面积与前一包不同吗,还是只有前N个字节与上一包不同,64-N个字节与上一包是相同的?

如果后续的包比较小,出现后者的情况,比较好判断是在pEP2_OUT_DataBuf被取出前就被覆盖了这个情况。


看描述,拷贝异常出现的环节似乎有待商榷,最好是数组内容都打印出来看看哪个环节出现了错误。

 memcpy(&usb_tmp_buf[offset], pEP2_OUT_DataBuf, len); //组装数据每次最大64byte”

如果出现覆盖问题,在此处发生的可能性较大。

“memcpy(my_buf,  usb_tmp_buf , 1024); //发现拷贝数据时间比较长,pEP2_OUT_DataBuf数据更新了,来不及接收,后面会覆盖”

这里已经是与USB的DMA缓存区域无关的数组之间的拷贝了,即使是pEP2_OUT_DataBuf在拷贝期间更新,也不应该影响my_buf中的内容。


先置USB回NAK再memcpy这个思路没问题。

测试过了,usb会暂停,是不是打开方式不对

USB暂停是不是因为没有将NAK再置回ACK?
建议USB中断中发现收满1024字节后,置标志变量,置NAK,先释放USB中断退出来到主循环;

1024字节长的memcpy放到主循环中执行,拷贝完成后清标志变量,置ACK,再在USB中断中收后续包。


感谢楼上2位的解答,特别是是 TECH_JW 详细的解答!


问题已经解决,CH579功能拉满,高优先级中断过于频繁,解决办法是:

端点2  IN挪到其他端点进行上传,然后空出in的buf做双buf

芯片DS第83页


只有登录才能回复,可以选择微信账号登录