clm705 发表于 2017-11-18 09:09:27

usb中断函数栈溢出

移植stm32f4Discovery的usb 虚拟串口程序到rtthread, 运行时出现 USBD_OTG_ISR_Handler()中断函数溢出。

中断函数不是任务,不知道在哪里设置中断函数的堆栈大小。修改startup_stm32f4xx.s中的堆栈参数,不能解决问题。

望高人能指点一下,谢谢

yu0405jie 发表于 2017-11-18 10:23:01

是不是在数组操作越界了?

clm705 发表于 2017-11-18 12:33:18

   不是数组越界,是中断处理函数的栈溢出。由于是中断处理函数,不是具体的thread,rtthread打印不出thread名(中断处理函数本就不在任务里),finsh里显示的任务栈都是正常的。
   rtthread支持的文档很少,当初选用这个系统主要是因为它对lwip的支持。而技术文档太少也是现在遇到最大的问题。

无薪税绵 发表于 2018-3-12 11:24:34

本帖最后由 无薪税绵 于 2018-3-12 11:27 编辑

在对USB的寄存器初始化之后,就是对USB的枚举过程,枚举过程都是通过USB中断完成的,
下面可以看USB的中断函数,在stm32fxxx_it.c中,找到USB中断的入口,
其中断的原函数是在usb_dcd_int.c中。

uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDefgintr_status;
uint32_t retval = 0;

if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
{
    gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
    if (!gintr_status.d32) /* avoid spurious interrupt */
    {
      return 0;
    }

    if (gintr_status.b.outepintr)
    {
      retval |= DCD_HandleOutEP_ISR(pdev);
    }   

    if (gintr_status.b.inepint)
    {
      retval |= DCD_HandleInEP_ISR(pdev);
    }

    if (gintr_status.b.modemismatch)
    {
      USB_OTG_GINTSTS_TypeDefgintsts;

      /* Clear interrupt */
      gintsts.d32 = 0;
      gintsts.b.modemismatch = 1;
      USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
    }

    if (gintr_status.b.wkupintr)
    {
      retval |= DCD_HandleResume_ISR(pdev);
    }

    if (gintr_status.b.usbsuspend)
    {
      retval |= DCD_HandleUSBSuspend_ISR(pdev);
    }
    if (gintr_status.b.sofintr)
    {
      retval |= DCD_HandleSof_ISR(pdev);

    }

    if (gintr_status.b.rxstsqlvl)
    {
      retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);

    }

    if (gintr_status.b.usbreset)
    {
      retval |= DCD_HandleUsbReset_ISR(pdev);

    }
    if (gintr_status.b.enumdone)
    {
      retval |= DCD_HandleEnumDone_ISR(pdev);
    }

    if (gintr_status.b.incomplisoin)
    {
      retval |= DCD_IsoINIncomplete_ISR(pdev);
    }

    if (gintr_status.b.incomplisoout)
    {
      retval |= DCD_IsoOUTIncomplete_ISR(pdev);
    }   
#ifdef VBUS_SENSING_ENABLED
    if (gintr_status.b.sessreqintr)
    {
      retval |= DCD_SessionRequest_ISR(pdev);
    }

    if (gintr_status.b.otgintr)
    {
      retval |= DCD_OTG_ISR(pdev);
    }   
#endif   
}
return retval;
}


通过 gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
这句话读取的是USB的中断标志位,来判断是什么引起的中断,
这个我们可以查看USB的中断状态寄存器来了解这些中断源。
建议楼主在这里,查看一下,是什么中断源引起的。

同时注意gintr_status这是一个共用体,
其中两个参数是b和d32,
并且其中b的还是一个结构体,
里面的变量分别对应了USB中断状态寄存器的对应位。
这里面主要的是注意上面两个中断,
一个是USB的输出数据的函数DCD_HandleOutEP_ISR,
一个是写入数据的函数DCD_HandleInEP_ISR。

资料来源于:http://bbs.elecfans.com/jishu_1106608_1_1.html

这里有源代码,可以参考:http://www.cnblogs.com/hiker-blogs/p/stm32_usb.html

maxtch 发表于 2018-3-12 15:36:16

中断处理函数是跳到核心态的,看看内核堆栈够不够用。

feixiang20 发表于 2018-3-12 22:01:50

移植中出现的问题大多数是由堆栈设置不合理造成的,检查启动代码。论坛里有很多设置疑问,可以去做参考。
页: [1]
查看完整版本: usb中断函数栈溢出