硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1297|回复: 12
收起左侧

STM32H7:USB复合设备MSC+CDC,USBD_CDC_TransmitPacket函数发送不正常

  [复制链接]

1

主题

22

回帖

25

积分

新手上路

积分
25
发表于 2023-9-27 14:45:25 | 显示全部楼层 |阅读模式
本帖最后由 wandeng123 于 2023-9-27 14:58 编辑

OS:freertos MCU:STM32H743
使用USB作为虚拟串口和U盘,虚拟串口作为控制台使用,用于打印日志和接收控制指令


1、设备在USB复合状态下,设备主动向USB发送数据,只有在刚开机的一两组数据发送成功,后面的数据一个都不行

2、在接收到usb数据之后的1s内可以发送数据包,超过1s后数据依然无法主动发送。期间如果进行打开串口、关闭串口或更改波特率,能间接的发出一些数据
3、设备单独工作在CDC(虚拟串口)模式下,以上的问题统统不存在

经过测试发现,复合设备状态下,USB中断中的设备枚举每次都是MSC地址,只有在接收到数据后才会枚举到CDC地址。
1、无法发送的原因是设备没有枚举到CDC,导致无法执行USBD_CDC_DataIn函数
5E69799C-4A65-4a6c-A75C-EAAC8DAE9D44.png
2、USBD_CDC_DataIn这个函数中会将hcdc->TxState标志清零。不清零的话在USBD_CDC_TransmitPacket函数内部判断会不执行。所以导致数据发送不出去
62F6D830-CF2D-4c4c-89A1-FEC8FD92ACBA.png B3208F47-17B4-4429-91CC-CD40AEA40351.png


回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2023-9-27 14:49:35 | 显示全部楼层
如果直接使用USBD_LL_Transmit函数发送数据的话倒也能发送出一些数据,只要加延时即可,但是数据量大的话还是会出现很多组数据发送失败的情况,而且很多数据包和上一组的一样,似乎在传递数据指针时没有赋值成功
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2023-9-27 14:56:48 | 显示全部楼层
本帖最后由 wandeng123 于 2023-9-27 15:01 编辑

被这个问题给困住了现在,有哪位兄弟碰到过这种虚拟串口发不出去的情况吗
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2023-10-9 09:47:01 | 显示全部楼层
问题解决了
微信图片_20231009094128.png

在发送数据的时候需要单字节发送,在发送完后循环等待USB HOST端确认消息。并且为了防止发送大量数据时出现没有接收到确认消息的bug,在发送之前加上一段强制置位hcdc->TxState状态。
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2023-10-9 09:47:55 | 显示全部楼层
总之和复合设备没有关系
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2023-10-9 09:53:01 | 显示全部楼层
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2023-10-24 16:50:52 | 显示全部楼层
更正下,上次并没有真正解决问题,在后期的使用中陆续还是会出现问题。
经仔细排查后发现是因为PC每隔1s会轮询一遍设备的虚拟U盘,导致USB设备指针切到了U盘模式。在这种情况下,如果虚拟串口正在发送数据的话,hcdc->TxState标志会被置1,使串口在发送前的判断标志出错,从而程序执行不下去
void MC_Switch_CDC(USBD_HandleTypeDef *pdev)
{
  static USBD_CDC_HandleTypeDef cdc_handle;
  
        USBD_CDC_RegisterInterface(pdev,&USBD_CDC_fops);
        pdev->pClassData = &cdc_handle;
       
}
void usb_printf(char* fmt,...)  
{  
                uint16_t i,len;
                va_list ap;
       
                MC_Switch_CDC(&USBD_Device);                //每次发送前切换到CDC模式(串口),防止PC将设备切换到MSC模式(U盘)
                va_start(ap,fmt);
                vsprintf((char*)USART_PRINTF_Buffer,fmt,ap);
                va_end(ap);
                len=strlen((const char*)USART_PRINTF_Buffer);
               
                for(i=0;i<len;i++)
                {
                        USB_USART_SendData(&USART_PRINTF_Buffer);
                }
                SCB_CleanDCache_by_Addr((uint32_t *)USART_PRINTF_Buffer,i);
}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2023-10-25 16:03:13 | 显示全部楼层
wandeng123 发表于 2023-10-24 16:50
更正下,上次并没有真正解决问题,在后期的使用中陆续还是会出现问题。
经仔细排查后发现是因为PC每隔1s会 ...

谢谢分享。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-3-10 23:58:42 来自手机 | 显示全部楼层
wandeng123 发表于 2023-10-24 16:50
更正下,上次并没有真正解决问题,在后期的使用中陆续还是会出现问题。
经仔细排查后发现是因为PC每隔1s会 ...

请问楼主最后解决了该问题吗?请教一下楼主,调用CDC_TransmitFS这个函数,只能在回环中发送,无法在main中发送数据。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2024-4-12 10:38:48 | 显示全部楼层

楼主,请问使用ST H7,是不是可以做到让USB于虚拟串口模式(从机,用来收发数据),和U盘(用于写一些故障数据到U盘)之间切换呢?纯小白,
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2024-4-13 09:10:08 | 显示全部楼层
小嵌 发表于 2024-4-12 10:38
楼主,请问使用ST H7,是不是可以做到让USB于虚拟串口模式(从机,用来收发数据),和U盘(用于写一些故 ...

可以运行的时候动态切换。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2024-4-15 15:07:10 | 显示全部楼层
eric2013 发表于 2024-4-13 09:10
可以运行的时候动态切换。

咱们硬汉有参考吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2024-4-16 08:51:17 | 显示全部楼层
小嵌 发表于 2024-4-15 15:07
咱们硬汉有参考吗

之前测试过可以,只是没有做参考例子。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 03:04 , Processed in 0.221761 second(s), 31 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表