硬汉嵌入式论坛

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

GD32F305RE USB CDC做device 出现的异常情况

[复制链接]

1

主题

5

回帖

8

积分

新手上路

积分
8
发表于 2025-7-24 17:39:00 | 显示全部楼层 |阅读模式
设备通过usb进行固件升级,上位机每2k发送给我。现在的问题是 在接收过程中,卡死不动,用bus hound抓包没抓到上位机发送的下一帧数据,但是上位机的log日志中已经发送下一帧。
现在问题在下位机这边,我先贴出代码,卡住时 USB中断正常进入,程序没有hardfault,中断优先级  分组2  usb (2,0),usb的时钟定时器(1,0),串口接收(3,0)
还有就是 这个升级流程 只在我做的产品上出现了,其他产品没有出现过这种情况,同样是gd305re。而且我这个有时候可以正常运行,有时候就会卡住
1.我在主循环中这样调用

int cdc_acm_ft232_recv(usb_dev *udev, uint8_t*data, uint32_t data_len)
{
    usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];
    debug_cdc= (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];
    if(cdc->packet_receive == 1U)
    {
        #if RTT_DEBUG
        SEGGER_RTT_SetTerminal(0);
        rtt_printf(RTT_CTRL_TEXT_BRIGHT_GREEN"packet_receive==1");
        rtt_printf("\n");
        #endif
        uint16_t len = USB_MIN(data_len, cdc->receive_length);
        memcpy(data,cdc->data_rcv,len);
        cdc_acm_data_receive(udev);
        return len;

    }
    return 0;
}

void cdc_acm_data_receive (usb_dev *udev)
{
    usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];

    cdc->packet_receive = 0U;
    //cdc->packet_sent = 0U;

    usbd_ep_recev(udev, CDC_DATA_OUT_EP, (uint8_t*)(cdc->data_rcv), USB_CDC_DATA_PACKET_SIZE);
}
2.当接收卡住的时候,就是这个cdc->packet_receive没有被再次置1,。正常情况下 是在下面这段程序中置1,这段在usb的中断中

static uint8_t cdc_acm_out (usb_dev *udev, uint8_t ep_num)
{
    usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];
    #if RTT_DEBUG
        SEGGER_RTT_SetTerminal(0);
        rtt_printf(RTT_CTRL_TEXT_BRIGHT_WHITE"enter_acm_out!!!");
        rtt_printf("\n");
    #endif
    if (0U == ep_num) {
        #if RTT_DEBUG
        SEGGER_RTT_SetTerminal(0);
        rtt_printf(RTT_CTRL_TEXT_BRIGHT_RED"false_ep_num!!!");
        rtt_printf("\n");
        #endif
        if (udev->dev.class_core->alter_set != NO_CMD)
        {
            /* Process the command data */
            cdc->line_coding.dwDTERate = (uint32_t)((uint32_t)cdc->data_cmd[0] |
                                                   ((uint32_t)cdc->data_cmd[1] << 8U) |
                                                   ((uint32_t)cdc->data_cmd[2] << 16U) |
                                                   ((uint32_t)cdc->data_cmd[3] << 24U));

            cdc->line_coding.bCharFormat = cdc->data_cmd[4];
            cdc->line_coding.bParityType = cdc->data_cmd[5];
            cdc->line_coding.bDataBits = cdc->data_cmd[6];

            udev->dev.class_core->alter_set = NO_CMD;
        }
    } else {
        cdc->packet_receive = 1U;
        cdc->receive_length = ((usb_core_driver *)udev)->dev.transc_out[ep_num].xfer_count;
        
        #if RTT_DEBUG
        SEGGER_RTT_SetTerminal(0);
        rtt_printf(RTT_CTRL_TEXT_BRIGHT_GREEN"true_ep_num==1");
        rtt_printf("\n");
        #endif
    }

    return USBD_OK;
}

3.我再贴出我的rtt打印

4.现在的问题就是进入不了cdc_acm_out 。
求大佬帮忙解答一下,
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-7-25 11:04:10 | 显示全部楼层
帮顶。没用过GD32F305的USB
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2025-7-29 08:41:47 | 显示全部楼层
补充一下,我这个升级是CDC和U盘升级共存,通过检测引脚切换,我重新移植其他305re的cdc,连续20次没有升级卡住,但是我把msc加进去后,升级前几次ok,后面就开始卡了。是不是msc的移植有问题,我再看一下
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2025-7-29 08:44:45 | 显示全部楼层
补充一下,我这个是cdc和U盘共存的,通过检测引脚来选择。我重新移植了其他工程的305re 的cdc 连续20次升级成功,我把msc的移植之后,前几次正常,后面卡住。我重新看一下是不是我的msc移植有问题
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-7-30 10:36:18 | 显示全部楼层
问题少年 发表于 2025-7-29 08:41
补充一下,我这个升级是CDC和U盘升级共存,通过检测引脚切换,我重新移植其他305re的cdc,连续20次没有升级 ...

可以加大端点得FIFO大小试试。之前STM32是这样处理得
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2025-8-1 10:50:25 | 显示全部楼层
eric2013 发表于 2025-7-30 10:36
可以加大端点得FIFO大小试试。之前STM32是这样处理得

应该是解决了。用cdc连续升级20次没卡住,用U盘连续升级10次也没卡住。
更改的点:我通过IO口检测是msc还是cdc,检测完成后,会将全局变量置位,然后再中断处理函数中,通过判断这个标志进入相应的处理程序中。
新的处理方式:在中断处理中不用变量判断,而是在检测完成之后,用函数指针指向中断要处理的函数,在中断中,通过函数指针调用。
旧的处理方式:
void USBFS_IRQHandler(void)
{
    if (get_usb_link() == LINK_USB_M) {
        usbh_iar_progress();
    } else {
        usbd_isr(&cdc_acm);
    }
}
新的处理
void USBFS_IRQHandler (void)
{
    if (usb_user_handle != NULL) {
        usb_user_handle();
    }
}
我也不知道为什么会这样,以前出问题的时候,我debug进去,这个全局变量的值并没有被更改,理论上来讲 不会进错函数。有没有彻底解决,后续还要再观察,按照目前的测试结果来说,没问题了。但是找不到问题原因,还是有点慌,说实话。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-8-2 09:32:44 | 显示全部楼层
问题少年 发表于 2025-8-1 10:50
应该是解决了。用cdc连续升级20次没卡住,用U盘连续升级10次也没卡住。
更改的点:我通过IO口检测是msc还 ...

谢谢解决办法分享
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-11 23:57 , Processed in 0.042569 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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