在进行USB CDC类开发时,无法发送64整数倍的数据(续)

1 前言

此文延续之前相同文章的话题,是对上篇文章的补充,之所以会有此文,主要是之前发现问题是在STM32F4上,解决方案也是基于CubeF4,但是,当相同问题出现在STM32F0上时,使用之前的代码修改并不能适用,这也就是本文的目的所在。
注:需要读懂此文的内容,请先了解上篇文章的内容:
http://blog.csdn.net/flydream0/article/details/53205286

2 分析

2.1 问题的本质原因

在进行USB CDC类开发时,无法从设备端向主机端发送64整数倍数据,最本质的原因就是,当发送数据长度恰好是Data In端点的最大包长整数倍时,最后一包数据必须是零长度的数据包(ZLP)。这是由于在USB标准中,接收端并不是通过已经接收的数据长度来判断是否接收完成,且发送端也并没有给出将要发送多长的数据,因此,接收端在接收数据前,并不知道将要接收的数据是多少,那么,问题就来了,接收端又是如何判断当前的数据已经全部接收了呢?有两点:

  • 若接收到的数据包长不足最大包长时,则认为当前传输完成
  • 如接收到的数据包长为零时,则认为当前传输完成。

正式由于上述两种判断,当传输的数据刚好是端点的最大包长时,当发送完最后一包(比如64个字节)时,接收端无法判断是否传输结束,进而继续等待下一包数据。这个就是问题本质所在。

2.2 之前的解决方案

知道问题原因后,解决的方法也就变得简单了,总的原则就是,在发送完最后一包数据后,判断发送的包长是否为端点最大包长的整数倍,如是,则补发一个零长度的数据包(ZLP)。

现在来看看上篇文章的修改代码:
在usbd_cdc.c文件中:

static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
{
    USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;

    PCD_HandleTypeDef *hpcd =pdev->pData;
    USB_OTG_EPTypeDef *ep;

    ep = &hpcd->IN_ep[epnum];
    if(ep->xfer_len >0 &&ep->xfer_len%ep->maxpacket ==0)//判断当前发送包长是否为端点的最大包长整数倍
    {
        USBD_LL_Transmit (pdev,epnum,NULL,0);
        return USBD_OK;
    }
    else
    {
        if(pdev->pClassData != NULL)
        {
            hcdc->TxState = 
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值