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

本文针对STM32在USB CDC类开发中遇到的无法发送64整数倍数据的问题进行深入分析和解决。问题的本质原因是USB标准要求发送64个字节的整数倍数据时,需要发送零长度数据包(ZLP)。之前的解决方案在STM32F0上不适用,因为不同STM32系列使用不同的USB IP核。新的解决方法不依赖底层数据,通过在usbd_conf.c和usbd_cdc.c中更新数据长度变量实现通用性。经过STM32F0和STM32F4的测试验证,方案有效。
摘要由CSDN通过智能技术生成

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 = 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值