Здравствуйте. Задача - открывать файл-образ fat32 flash накопителя и читать/записывать данные и него/в него. Данные читаются или записываются блоками по 512 * n байт. Выхода за пределы файла гарантировано быть не может (по сути, имитируется доступ к аппаратному flash накопителю, с которым работает fatfs).
Имеется:
Операционная система: Ubuntu 18.04.3 LTS, x64
Файл (образ fat32 micro-sd на 256 мегабайт), созданный следующей последовательностью команд:
$ 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
Программа собирается с флагами:
-m32 -O0 -g3 -fdata-sections -ffunction-sections -Wl,--gc-sections -std=gnu99
Программа должна быть обязательно собрана под x32, по-этому флаг -m32 обязателен (целевая платформа 32-х битная).
Файл успешно создается, его чтение-запись из системы происходит успешно на всем объеме (скидывал на накопитель файл близкий ко всему объему и вычитывал обратно).
Чтение/запись в файл/из файла осуществляется следующим кодом:
// Путь до файла верный, работа ведется только с 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;
}
Если запустить запись множество раз подряд, то в какой-то момент при следующем открытии файла fopen будет возвращать ошибку. Всегда на одном и том же месте при запуске без отладки. Однако, если включить отладку и ставить точку остановки перед открытием файла, то весь цикл открытия, записи или чтения будет проходить успешно и никаких ошибок не будет. Отсюда напрашивается желание поставить некоторую задержку после закрытия файла. Например, 100 миллисекунд. Но это не спасает ситуацию (да и не правильно). Если какой-то способ решить данную проблему нормальными способами? Может есть функция, сообщающая о том, что файл действительно был закрыт и к нему можно обратиться снова или что0то подобное?
P.S. Файл гарантировано закрывается после каждого обращения, возвращая при этом флаг успешного закрытия.