STM32F7 FATFS y tarjeta SD Problemas de escritura

-1

Tengo un tablero de descubrimiento STM32F7 y tengo una imagen en la SDRAM que quiero almacenar en la tarjeta SD como archivo BMP.

Estoy usando el módulo FATFS de Chan con el módulo sddiskio y la biblioteca BSP de ST, como aquí: enlace

Inicializar, montar y crear un archivo funciona bien, pero cuando se escriben los datos de la imagen real, la función f_write falla después de un tiempo con el error FR_DISK_ERR (error grave en la capa de bajo nivel de diskio).

Aquí está mi código de prueba actual, que debería proporcionarme una imagen RGB565 de 640x480 con barras verticales de 1 píxel de ancho:

  void SD_write_image(void)
{
    FIL file; //file object
    char file_str[30] = "image01.bmp";//filename

    int32_t i, j;
    //uint32_t tmp = 0;

    uint16_t img_buf[640];

    uint32_t bytes_written;

    FATFS_t fs_status;
    FRESULT fs_error;

    file_str[6] = (char)((img_counter % 10) + 48);//increase the filename
    file_str[5] = (char)(((img_counter/10) % 10) + 48);

    fs_status = SD_Mount();
    if(fs_status != FATFS_OK) Filesystem_ErrorHandler();

    fs_status = SD_OpenFile(&file, file_str, F_WR_CLEAR);
    if(fs_status != FATFS_OK) Filesystem_ErrorHandler();

    fs_error = f_write(&file, bmp_fileheader640, 138, &bytes_written);

    if(fs_error != FR_OK)
    {
        Filesystem_ErrorHandler();
    }

    for(j = 0; j < 640; j++)
    {
        if((j%2) == 0) img_buf[j] = 0xfb54;
        else img_buf[j] = 0xF7E0;
    }

    for(i = 0; i < 480; i++)//480 lines
    {
        fs_error = f_write(&file, img_buf, 1280, &bytes_written);
        if(fs_error != FR_OK)
        {
            Filesystem_ErrorHandler();
        }
        //tmp = tmp + 640*sizeof(uint8_t);
    }

    fs_status = SD_CloseFile(&file);
    if(fs_status != FATFS_OK) Filesystem_ErrorHandler();

    fs_status = SD_UnMount();
    if(fs_status != FATFS_OK) Filesystem_ErrorHandler();

    img_counter++;
    sprintf((char*)text, "Images stored: %d", (int)img_counter);
    BSP_LCD_DisplayStringAt(5, LINE(9), (uint8_t*)text, LEFT_MODE);
}

Si tiene éxito, la imagen se ve así:

Sin embargo, la interfaz de la tarjeta SD es muy inestable, a veces funciona, a veces no.

Actualización:

Pude localizar el error de bajo nivel de SD. Ocurre en la función HAL_SD_WriteBlocks. El código de error es SD_TX_UNDERRUN , lo que significa que hay una insuficiencia en el FIFO de transmisión de la interfaz de la tarjeta SD.

¿Cuál puede ser la razón de esto?

Segunda actualización:

Aquí está mi encabezado bmp, pero creo que el error no está aquí:

uint8_t bmp_fileheader320[138]=
{
        0x42, 0x4D,
        0x8A, 0x58,
        0x02, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x8A, 0x00,
        0x00, 0x00,
        0x7C, 0x00,
        0x00, 0x00,
        0x40, 0x01,
        0x00, 0x00,
        0xf0, 0x00,
        0x00, 0x00,
        0x01, 0x00,
        0x10, 0x00,
        0x03, 0x00,
        0x00, 0x00,
        0x00, 0x58,
        0x02, 0x00,
        0x13, 0x0B,
        0x00, 0x00,
        0x13, 0x0B,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0xF8,
        0x00, 0x00,
        0xE0, 0x07,
        0x00, 0x00,
        0x1F, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x42, 0x47,
        0x52, 0x73,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x02, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00,
        0x00, 0x00
};
    
pregunta deinoppa

2 respuestas

1

Intenta mover esta parte:

for(j = 0; j < 640; j++) { 
    if((j%2) == 0) 
        img_buf[j] = 0xfb54; 
    else 
        img_buf[j] = 0xF7E0; 
}

A la posición inmediatamente anterior a la llamada SD_Mount () en la parte superior. Si esto no funciona, comente los bloques IF de comprobación de errores (después de f_writes) e intente nuevamente. Por lo general, la falta de funcionamiento significa que el búfer de fifo de TX no se está llenando lo suficientemente rápido con datos, por lo que esto podría ser una solución.

    
respondido por el TisteAndii
1

He tenido exactamente el mismo problema. Intente deshabilitar la rutina de servicio INTERRUPT antes de llamar al f_write y cuando haya terminado de escribir, habilite la INTERRUPCIÓN.

Por ejemplo:

__disable_irq();
if (f_write(....)==FR_OK)
{
}
else
{
}
__enable_irq();
    
respondido por el Paolo Frigerio

Lea otras preguntas en las etiquetas