Как восстановить FR_DISK_ERR во время f_write в STM32 - PullRequest
0 голосов
/ 03 августа 2020

Теперь я использую STM32F103RE для чтения данных из кода c через I2S и записи на SD-карту. Я использую библиотеку HAL в STM32CubeMX с FATFS Чена и I2S DMA. К сожалению, f_write когда-нибудь вернет FR_DISK_ERR. Согласно fatfs, в этом случае я могу только f_close. Но он возвращает только FR_INVAILD_OBJECT, что бы я ни делал. Если я добавлю задержку опроса 1 мс (HAL_Delay (1)) между каждым f_write, он будет работать нормально. Так есть ли способ избежать или исправить проблему?

Вот мой код:

FRESULT u8_sd_fat_status = FR_DISK_ERR;   // 0 = SD card FAT file system is ok, otherwise 1.
uint16_t u32_array_codec_in[512];

f_mount(&SDFatFS, (TCHAR const*)SDPath, 0);

f_unlink("record.wav");
u8_sd_fat_status = f_open(&SDFile, "record.wav", FA_CREATE_NEW | FA_READ | FA_WRITE);
for(unsigned char i = 0; i < 10 && u8_sd_fat_status != FR_OK; i++)
{
    HAL_Delay(100);
    u8_sd_fat_status = f_open(&SDFile, "record.wav", FA_CREATE_NEW | FA_READ | FA_WRITE);
}
if(u8_sd_fat_status == FR_OK)
{
    uint16_t u16_array_mic_adc[512];
    uint32_t u32_rec_file_ptr = 0;
    uint32_t u32_i2s_ptr = 22;

    f_sync(&SDFile);
    
    HAL_I2S_Receive_DMA(&hi2s2, u32_array_codec_in, sizeof(u32_array_codec_in)/sizeof(uint16_t));

    while(u32_rec_file_ptr < 512000)
    {
        UINT u32_i = 0;

        u32_i2s_ptr += CodecRead(u16_array_mic_adc, sizeof(u16_array_mic_adc)/sizeof(uint16_t) - u32_i2s_ptr);

        if(u32_i2s_ptr >= sizeof(u16_array_mic_adc)/sizeof(uint16_t))
        {
            u8_sd_fat_status = f_write (&SDFile, u16_array_mic_adc, sizeof(u16_array_mic_adc), &u32_i);
            if(u8_sd_fat_status != FR_OK)
            {
                u8_sd_fat_status = f_close(&SDFile);
                if(u8_sd_fat_status != FR_OK)
                    __asm("nop");
                u8_sd_fat_status = f_open(&SDFile, "record.wav", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
                if(u8_sd_fat_status != FR_OK)
                    __asm("nop");
                u8_sd_fat_status = f_lseek (&SDFile, u32_rec_file_ptr);
                if(u8_sd_fat_status != FR_OK)
                    __asm("nop");
                break;
            }
            f_sync(&SDFile);
        }
        u32_rec_file_ptr += u32_i;
        u32_i2s_ptr = 0;
        }
    }
    f_close(&SDFile);
}

Спасибо, Sin

[Edit] Просто посмотрите с отладчиком. Код зависает в disk_write @ ff. c (строка 2823). Возвращает RES_ERROR. Но, похоже, больше подробностей предоставить нельзя.

Похоже, что данные записываются за границу блока сектора SD. Но я каждый раз записываю 1024 байта, чего не должно быть. И это не должно быть решено добавлением задержки

...