1
\$\begingroup\$

I also asked this on SE: Stack Overflow


In my application, I've set up a STM32F4, SD-Card and USB-CDC (all with CubeMX). Using a PC, I send commands to the STM32, which then does things on the SD-Card.

The commands are handled using a "communicationBuffer" (implemented by me) which waits for commands over USB, UART, ... and sets a flag, when a \n character was received. The main loop polls for this flag and if it is set, a parser handles the command. So far, so good.

When I send commands via UART, it works fine, and I can get a list of the files on the SD-Card or perform other access via FatFs without a problem.

The problem occurs, when I receive a command via USB-CDC. The parser works as expected, but FatFs claims FR_NO_FILESYSTEM (13) in f_opendir. Also other FatFs commands fail with this error-code.

After one failed USB-command, commands via UART will also fail. It seems, as if the USB somehow crashes the initialized SD-Card-driver.

Any idea how I can resolve this behaviour?


My USB-Implementation:

I'm using CubeMX, and therefore use the prescribed way to initialize the USB-CDC interface:

main() calls MX_USB_DEVICE_Init(void).

In usbd_conf.c I've got:

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 */
  }
}

and the receive-process is implemented in usbd_cdc_if.c as follows:

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 is implemented as follows (I use the same implementation for UART and USB transfer - with separate instances for the respective interfaces. mBuf is an instance-variable of type std::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;
    }
}
\$\endgroup\$
8
  • 1
    \$\begingroup\$ Did you even try to debug this? \$\endgroup\$ – Turbo J Nov 6 '16 at 14:55
  • \$\begingroup\$ @Turbo J: As I wrote, I know the error code of FatFs that occurs. Unfortunately I don't know a starting point to begin the debugging, because the same access to the SD card is working, when the command came from a UART. \$\endgroup\$ – DPF Nov 6 '16 at 14:59
  • 1
    \$\begingroup\$ Which means you have a software problem, and we have absolutely no idea how your source code looks like. There are many possible reasons for your error... \$\endgroup\$ – Turbo J Nov 6 '16 at 15:37
  • \$\begingroup\$ @Turbo J: OK, I will soon provide more information about the USB data processing chain. \$\endgroup\$ – DPF Nov 6 '16 at 15:46
  • \$\begingroup\$ @Turbo J: Please see my edit. \$\endgroup\$ – DPF Nov 6 '16 at 16:16
4
\$\begingroup\$

I resolved the problem:

In usb_cdc_if.c the #define APP_RX_DATA_SIZE was set to 4 (for some unknown reason). As this is lower than the packet size 64, incoming packets of a larger size than 4 bytes were overwriting my memory.

It happened, that the following portion of my memory was the FATFS* FatFs[] pointer-list to the initialized FATFS-Filesystem structs.

So subsequently the address to this struct was overwritten, when a command of 5 or more bytes arrived.

Phew, that was a tough one.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.