首页 文章

STM32F4:使用FatF和USB的SD卡出现故障

提问于
浏览
0

(也问SE: Electrical Engineering

在我的应用程序中,我已经设置了STM32F4,SD卡和USB-CDC(都使用CubeMX) . 使用PC,我向STM32发送命令,然后STM32在SD卡上执行操作 .

这些命令使用"communicationBuffer"(由我实现)处理,当收到 \n 字符时,它等待USB,UART等命令并设置标志 . 主循环轮询此标志,如果已设置,则解析器处理该命令 . 到现在为止还挺好 .

当我通过UART发送命令时,它工作正常,我可以获得SD卡上的文件列表或通过FatF执行其他访问没有问题 .

当我通过USB-CDC收到命令时,会出现问题 . 解析器按预期工作,但FatFs在 f_opendir 中声明 FR_NO_FILESYSTEM (13) . 此错误代码也会失败其他FatFs命令 .

在USB命令失败后,通过UART的命令也将失败 . 看起来好像USB以某种方式崩溃了初始化的SD卡驱动程序 .

知道如何解决这个问题吗?还是调试的起点?


我的USB实现:

我正在使用CubeMX,因此使用规定的方式初始化USB-CDC接口:

main()调用 MX_USB_DEVICE_Init(void) .

usbd_conf.c 我有:

void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(pcdHandle->Instance==USB_OTG_FS)
  {
  /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */

  /* USER CODE END USB_OTG_FS_MspInit 0 */

    /**USB_OTG_FS GPIO Configuration    
    PA11     ------> USB_OTG_FS_DM
    PA12     ------> USB_OTG_FS_DP 
    */
    GPIO_InitStruct.Pin = OTG_FS_DM_Pin|OTG_FS_DP_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();

    /* Peripheral interrupt init */
    HAL_NVIC_SetPriority(OTG_FS_IRQn, 7, 1);
    HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
  /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */

  /* USER CODE END USB_OTG_FS_MspInit 1 */
  }
}

接收过程在 usbd_cdc_if.c 中实现,如下所示:

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */

    mRootObject->mUsbBuffer->fillBuffer(Buf, *Len);

    USBD_CDC_ReceivePacket(&hUsbDeviceFS);

    return (USBD_OK);

  /* USER CODE END 6 */ 
}

fillBuffer 实现如下(我对UART和USB传输使用相同的实现 - 为各个接口使用单独的实例. mBufstd::vector<char> 类型的实例变量):

void commBuf::fillBuffer(uint8_t *buf, size_t len)
{
    // Check if last fill has timed out
    if(SystemTime::getMS() - lastActionTime > timeout) {
        mBuf.clear();
    }
    lastActionTime = SystemTime::getMS();

    // Fill new content
    mBuf.insert(mBuf.end(), buf, buf + len);

    uint32_t done = 0;
    while(!done) {
        for(auto i = mBuf.end() - len, ee = mBuf.end(); i != ee; ++i) {
            if(*i == '\n') {
                newCommand = true;
                myCommand = std::string((char*) &mBuf[0],i - mBuf.begin() + 1);

                mBuf.erase(mBuf.begin(), mBuf.begin() + (i - mBuf.begin() + 1));
                break;
            }

        }
        done = 1;
    }
}

1 回答

  • 0

    我解决了这个问题:

    usb_cdc_if.c 中, #define APP_RX_DATA_SIZE 被设置为 4 (由于某种未知原因) . 由于这比数据包大小要小,因此大于4字节的传入数据包会覆盖我的内存 .

    碰巧,我记忆的下一部分是初始化的FATFS文件系统结构的 FATFS* FatFs[] 指针列表 .

    因此,当5个或更多字节的命令到达时,该结构的地址随后被覆盖 .

    P,这是一个艰难的 .

相关问题