STM32F4: Tarjeta SD que usa FatFs y falla el USB [cerrado]

1

También pregunté esto en SE: Stack Overflow

En mi aplicación, he configurado un STM32F4, una tarjeta SD y un USB-CDC (todos con CubeMX). Utilizando una PC, envío comandos al STM32, que luego realiza tareas en la tarjeta SD.

Los comandos se manejan utilizando un "communicationBuffer" (implementado por mí) que espera los comandos a través de USB, UART, ... y establece un indicador cuando se recibe un carácter \n . El bucle principal sondea este indicador y, si está establecido, un analizador maneja el comando. Hasta ahora, todo bien.

Cuando envío comandos a través de UART, funciona bien y puedo obtener una lista de los archivos en la tarjeta SD o realizar otro acceso a través de FatFs sin ningún problema.

El problema ocurre cuando recibo un comando a través de USB-CDC. El analizador funciona como se esperaba, pero FatFs reclama FR_NO_FILESYSTEM (13) en f_opendir . También otros comandos de FatFs fallan con este código de error.

Después de un comando USB fallido, los comandos a través de UART también fallarán. Parece, como si el USB fallara de alguna manera el controlador de la tarjeta SD inicializado.

¿Alguna idea de cómo puedo resolver este comportamiento?

Implementación de mi USB:

Estoy usando CubeMX y, por lo tanto, uso la forma prescrita para inicializar la interfaz USB-CDC:

main () llama a MX_USB_DEVICE_Init(void) .

En usbd_conf.c tengo:

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

y el proceso de recepción se implementa en usbd_cdc_if.c de la siguiente manera:

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 se implementa de la siguiente manera (uso la misma implementación para UART y transferencia USB, con instancias separadas para las interfaces respectivas. mBuf es una variable de instancia de tipo 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;
    }
}
    
pregunta DPF

1 respuesta

4

Resolví el problema:

En usb_cdc_if.c , #define APP_RX_DATA_SIZE se estableció en 4 (por alguna razón desconocida). Como este es inferior al tamaño de paquete 64 , los paquetes entrantes de un tamaño mayor que 4 bytes sobrescribieron mi memoria.

Ocurrió que la siguiente parte de mi memoria era el FATFS* FatFs[] pointer-list a las estructuras inicializadas del sistema de archivos FATFS.

Por lo tanto, posteriormente se sobrescribió la dirección de esta estructura, cuando llegó un comando de 5 o más bytes.

Uf, eso fue difícil.

    
respondido por el DPF

Lea otras preguntas en las etiquetas