V
V
Vadim Deryabkin2020-01-12 16:00:26
linux
Vadim Deryabkin, 2020-01-12 16:00:26

Why is a file no longer available for opening (fopen) after a multiple number of write cycles?

Hello. The task is to open the image file of the fat32 flash drive and read / write data to / from it. Data is read or written in blocks of 512 * n bytes. There can be no guaranteed way out of the file (in fact, access to the hardware flash drive that fatfs works with is simulated).
Available:
Operating system: Ubuntu 18.04.3 LTS, x64
File (256 MB fat32 micro-sd image) created by the following command sequence:

$ sudo dd if=/dev/zero of=microsd.img bs=512 count=524288
$ sudo mkfs.fat -F32 -v -I microsd.img
$ sudo chmod 777 microsd.img
$ sudo chown user_name:user_name microsd.img

The program is built with flags:
-m32 -O0 -g3 -fdata-sections -ffunction-sections -Wl,--gc-sections  -std=gnu99

The program must be compiled under x32, so the -m32 flag is required (the target platform is 32-bit).
The file is successfully created, its reading-writing from the system is successful on the entire volume (I dumped a file close to the entire volume onto the drive and read it back).
Reading/writing to/from a file is done by the following code:
// Путь до файла верный, работа ведется только с 1 файлом.
const char FILE_MICROSD_PATH[] = "../resurse/microsd.img";

// Размер блока стандартные 512 байт.
#define SD_BLOCK_SIZE 512
static FILE *sd = NULL;

int sdio_write (const uint32_t *buf, uint32_t block_num, uint32_t num_block) {
    if ((sd = fopen(FILE_MICROSD_PATH, "r+b")) == NULL) {
        return -1;
    };

    if (fseek(sd, block_num*SD_BLOCK_SIZE, SEEK_SET) != 0) {
        fclose(sd);
        sd = NULL;
        return -1;
    }

    if (fwrite(buf, SD_BLOCK_SIZE, num_block, sd) != num_block) {
        fclose(sd);
        sd = NULL;
        return -1;
    };

    int rv = fclose(sd);
    sd = NULL;
    return rv;
}

int sdio_read (uint32_t *buf, uint32_t block_num, uint32_t num_block) {
if ((sd = fopen(FILE_MICROSD_PATH, "r+b")) == NULL) {
        return -1;
    };

    if (fseek(sd, block_num*SD_BLOCK_SIZE, SEEK_SET) != 0) {
        fclose(sd);
        sd = NULL;
        return -1;
    }

    if (fread(buf, SD_BLOCK_SIZE, num_block, sd) != num_block) {
        fclose(sd);
        sd = NULL;
        return -1;
    };

    int rv = fclose(sd);
    sd = NULL;
    return rv;
}

If you start writing many times in a row, then at some point the next time you open the file, fopen will return an error. Always in the same place when running without debugging. However, if you enable debugging and put a breakpoint before opening the file, then the entire cycle of opening, writing or reading will be successful and there will be no errors. Hence the desire to put some delay after closing the file. For example, 100 milliseconds. But this does not save the situation (and not correctly). If any way to solve this problem in normal ways? Maybe there is a function that reports that the file has really been closed and can be accessed again or something like that?
PS The file is guaranteed to be closed after each access, while returning the flag of successful closing.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
K
Karpion, 2020-01-12
@Vadimatorikda

Examine the exit code of the fopen() operator.
Check how it works with a delay of "100 milliseconds" or more.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question