【发布时间】:2018-10-23 00:34:08
【问题描述】:
我正在使用 STM32F405 微控制器进行嵌入式项目,并且有一些非常令人困惑的行为。我正在将一个现有(工作)项目从 STM32F1 移植到 STM32F4,但我已经为 VCP 添加了 ST 的标准外设库 USB 堆栈。
如果我使用-O0 优化编译程序,那么它会无限期地按预期运行。但是,如果我使用-O2 进行编译,那么该项目将运行 10-15 分钟,但随后我会看到 ST 的 VCP 驱动程序代码中发生的堆栈溢出。
实际的错误表现为指针 (GREGS) 变得无效,即使该指针之前已在同一函数中使用过。这个指针指向USB外设的硬件中断配置寄存器,所以实际数据没有消失,但是当指针被访问时,我得到了一个错误,我可以用我的调试器看到指针无效。 (我已经从下面的usb_dcd_int.c 复制了实际功能,并指出了麻烦的行。)
static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTMSK_TypeDef int_mask;
USB_OTG_DRXSTS_TypeDef status;
USB_OTG_EP *ep;
/* Disable the Rx Status Queue Level interrupt */
int_mask.d32 = 0;
int_mask.b.rxstsqlvl = 1;
/*****************************************************************/
/*********** POINTER IS READ HERE - NO PROBLEMS ******************/
/*****************************************************************/
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
/* Get the Status from the top of the FIFO */
status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
ep = &pdev->dev.out_ep[status.b.epnum];
switch (status.b.pktsts)
{
case STS_GOUT_NAK:
break;
case STS_DATA_UPDT:
if (status.b.bcnt)
{
USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
ep->xfer_buff += status.b.bcnt;
ep->xfer_count += status.b.bcnt;
}
break;
case STS_XFER_COMP:
break;
case STS_SETUP_COMP:
break;
case STS_SETUP_UPDT:
/* Copy the setup packet received in FIFO into the setup buffer in RAM */
USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
ep->xfer_count += status.b.bcnt;
break;
default:
break;
}
/* Enable the Rx Status Queue Level interrupt */
/*****************************************************************/
/************************* GREGS == :-( ************************/
/*****************************************************************/
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
return 1;
}
我使用 vanilla GNU make 和 gcc-arm-none-eabi 5-4-2016q3 作为我的工具,ST 的 2015 年用于 STM32F405 的 vanilla 链接器和启动脚本,VCP 代码来自 2012 年 3 月。我是启动和链接器脚本的新手,但我在任何一个中都看不到任何可疑之处。我也没有在 ST 的 VCP 代码中看到任何明显的东西,但我当然不理解每一行。
我有三个问题:
- 这听起来像是堆栈溢出吗?
- 如何为 IRQ 分配堆栈?在 ST 的实现中,VCP 中断有一个非常深的调用树。我只需要为 VCP IRQ 分配更多吗?
-
-O2中的哪些优化可能导致此行为?我想知道是否可以有选择地禁用一些可能有助于我追踪错误的优化。
【问题讨论】:
标签: c optimization usb stack-overflow stm32