GD32F103单片机USB HID设备连续接收数据崩溃,直接进入HardFault中断

        最近测试USB HID设备,发现多次接收数据后崩溃,在线DEBUG测试,程序最终进入到HardFault中断,源代码如下:

void USBD_LP_CAN0_RX0_IRQHandler (void)
{
	uint8_t  rece_buffer[CUSTOMHID_OUT_PACKET] = {0};
	/*该中断函数包含USB的多种中断*/
	usbd_isr();
	/*读取接收到的数据*/
	custom_hid_report_receive (&usb_device_dev, rece_buffer, CUSTOMHID_OUT_PACKET);
	/*处理接收到的数据*/
	if(rece_buffer[0] == 0x12)
	{
	} 
}

        经过查询GD32官方USBD设备资料,发现中断处理已集成在usbd_isr()函数中,进入到该函数中:

void  usbd_isr (void)
{
    __IO uint16_t interrupt_flag = 0U;
    __IO uint16_t ctlr = 0U;

    interrupt_flag = USBD_REG_GET(USBD_INTF);

    if (g_interrupt_mask & INTF_STIF & interrupt_flag) {
        /* the endpoint successful transfer interrupt service */
        usbd_intf_lpst(&usb_device_dev);
}
..................
..................
}

        进一步查找,找到端点传输中断函数usbd_intf_lpst(&usb_device_dev),该函数包括输入、输出端点的中断处理。函数如下:

static uint8_t  usbd_intf_lpst (usbd_core_handle_struct *pudev)
{
    uint8_t ep_num = 0U;

    __IO uint16_t int_status = 0U;
    __IO uint16_t ep_value = 0U;

    usb_ep_struct *ep = NULL;

    /* wait till interrupts are not pending */
    while (0U != ((int_status = USBD_REG_GET(USBD_INTF)) & (uint16_t)INTF_STIF)) {
        /* get endpoint number and the value of control and state register */
        ep_num = (uint8_t)(int_status & INTF_EPNUM);
        ep_value = USBD_REG_GET(USBD_EPxCS(ep_num));

        if (0U == (int_status & INTF_DIR)) {
            /* handle the in direction transaction */
            /* 处理发送端点中断*/ 
        } 
        else/* 处理接收端点中断*/ 
        {
            /* handle the out direction transaction */
            uint16_t count = 0U;
            ep = &(pudev->out_ep[ep_num]);
            if (0U != (ep_value & EPxCS_RX_ST)) {
                /* clear successful receive interrupt flag */
                USBD_ENDP_RX_STAT_CLEAR(ep_num);

                count = (pbuf_reg + ep_num)->rx_count & (uint16_t)EPRCNT_CNT;

                if (0U != count) {
                    if (0U != (ep_value & EPxCS_SETUP)) {
                        /* handle setup packet */
                        usbd_ep_data_read(&(pudev->setup_packet[0]), pbuf_reg->rx_addr, count);

                        /* enter setup status */
                        usbd_setup_transaction(pudev);

                        return USBD_OK;
                    } else {
                        usbd_ep_data_read(ep->trs_buf, (pbuf_reg + ep_num)->rx_addr, count);
                    }

                    /*读取接收到的数据,并进行标志位处理*/
				    rece_buffer[0] = ep->trs_buf[0];
				
				    if(rece_buffer[0] == 0x12)
				    {
					    s_Device.Key_Val++;
				    }


              ............................
}

        从该函数可以看出,先是判断端点中断类型,发送or接收;接收中又分为枚举过程和数据接收过程,在接收函数 usbd_ep_data_read()之后,获取数据进行处理,置位对应的标志位,然后在中断外部具体处理事件。

        按上面过程处理后,再次进行测试,程序没有崩溃,能正常工作。

        不知道,之前在中断处理函数usbd_isr()之外,读取接收的数据的操作,是否引起哪里冲突了?在此标记一下,欢迎补充。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值