Перейти к содержанию
    

FatFS пофиксена

Added selection of character encoding on the file. (_STRF_ENCODE)

Added f_closedir().

Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)

Added forced mount feature with changes of f_mount().

Improved behavior of volume auto detection.

Improved write throughput of f_puts() and f_printf().

Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().

Fixed f_write() can be truncated when the file size is close to 4GB.

Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.

 

http://elm-chan.org/fsw/ff/ff10.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спрошу здесь дабы новую тему не создавать.

Вообщем в своем приложении нужно было создать таблицу разделов на SD карте и отформатировать - посмотрел код f_fdisk().

глаз зацепился за следуюжее:

	/* Set partition table */
...
 p[2] = (BYTE)((b_cyl >> 2) + 1);	/* Start sector */
 p[3] = (BYTE)b_cyl;		/* Start cylinder */
 ... 
p[6] = (BYTE)((e_cyl >> 2) + 63);	/* End sector */
p[7] = (BYTE)e_cyl;		/* End cylinder */

При удачном стечении обстоятельств в p[2] (p[6]) для номера цилиндра окажутся не те значения.

Если использовать LBA - нет проблем. А если через CHS - то ...

Собственно вопрос: я придираюсь или в f_disk() есть ошибка при заполнении полей таблицы разделов?

PS: В своем коде сделал примерно так: p[6] = ((BYTE)((e_cyl >> 2)&(0xC0)) | 63);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

..

p[6] = (BYTE)((e_cyl >> 2) + 63);	/* End sector */

PS: В своем коде сделал примерно так:
p[6] = ((BYTE)((e_cyl >> 2)&(0xC0)) | 63);

для номера цилиндра окажутся не те значения....есть ошибка..?

 

не вдаваясь логику работы...

>>2 есть сдвиг в право на две позиции бит. насколько я понимаешь - старшие биты заполняются нулями.

имеем

e_cyl = xxxx xxxx

после сдвига (деление на 4)

e_cyl = 00xx xxxx

в оригинале имеем

00xx xxxx + 0011 1111 (т.е. полностью будет звучать так (Z/4 + 63)

в Вашем варианте

(00xx xxxx & 1100 0000) + 0011 1111

что после наложения маски даст

0000 0000 + 0011 1111

что является всегда константой

0011 1111 т.е. всегда(!) 63

 

ик?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не вдаваясь логику работы...

немного подробностей:

1) e_cyl (b_cyl) - 16 или 32-битная пременная если смотреть исходники f_fdisk()

2) Под номер цилиндра используется 10-bit

3) p[6] должна содержать в старших 2х битах -> 8,9 биты номера цилиндра, а в младших 6 битах - номер сектора

В итоге:

допустим e_cyl = 0b0000001010001100 (0x028C)

0b0000001010001100 >> 2 == 0b0000000010100011 (0x00A3)

0b0000000010100011 + 63 == 0b0000000011100010 (0x00E2)

9й бит номера цилиндра не тот, номер сектора получился тоже непонятно какой, вот и интересуюсь... :)

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

немного подробностей:

 

 

Нашел глючок у Чана небольшой :rolleyes:

Делаю многодисковую систему, при монтировании диска выскакивала ошибка, если был не 0й диск.

Ошибка в неучете изменения указателя пути и имени файла. Вот пофиксенная функция f_mount:

 

FRESULT f_mount (

FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/

const TCHAR* path, /* Logical drive number to be mounted/unmounted */

BYTE opt /* 0:Do not mount (delayed mount), 1:Mount immediately */

)

{

FATFS *cfs;

int vol;

FRESULT res;

const TCHAR* cpath; //добавил копию указателя

cpath=path; //тоже

 

 

vol = get_ldnumber(&path);

if (vol < 0) return FR_INVALID_DRIVE;

cfs = FatFs[vol]; /* Pointer to fs object */

 

if (cfs) {

#if _FS_LOCK

clear_lock(cfs);

#endif

#if _FS_REENTRANT /* Discard sync object of the current volume */

if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;

#endif

cfs->fs_type = 0; /* Clear old fs object */

}

 

if (fs) {

fs->fs_type = 0; /* Clear new fs object */

#if _FS_REENTRANT /* Create sync object for the new volume */

if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;

#endif

}

FatFs[vol] = fs; /* Register new fs object */

 

if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */

 

res = find_volume(&fs, &cpath, 0); /* Force mounted the volume - ИСПРАВЛЕНО! */

 

LEAVE_FF(fs, res);

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашел глючок у Чана небольшой :rolleyes:

А автору сообщили? :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А автору сообщили? :laughing:

 

Каюсь, не силен в языках...(человеческих) :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пользуясь случаем про этот модуль. Вопрос - возможны-ли одновременные операции на одном физ. диске когда 1 или 2 файла читаются, а один пишется. На разных дисках работает нормально, а вот когда на одном, иногда сносится FAT. Еслт какая-то плюшка _FS_LOCK пока детально не разбирался, описание у чана - 3 предложения, примеров не видел.

Может у кого есть что сказать?

ЗЫ. да, файловые операции происходят в одном потоке, без ртосин, прерываний и многозадачности.

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

возможны-ли одновременные операции на одном физ. диске когда 1 или 2 файла читаются, а один пишется.

...

ЗЫ. да, файловые операции происходят в одном потоке, без ртосин, прерываний и многозадачности.

Делал одновременные обращения к разным файлам на запись и на чтение на одном диске - все работает (версия FatFs - R0.08b). _FS_LOCK не использовал. Все делал через очередь запросов к файловой системе (была многопоточность). Низкоуровневые дисковые операции (disk_write() disk_read() ничего не знают о файлах и FAT - они работают с секторами диска. Если все в одном потоке - проблем быть не должно и при прямом обращении к функциям fatfs, без очередей.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Также воспользуюсь случаем... привожу простую функцию которая укладывает проц намертво:

 

if ((res = f_opendir(&dirs, path)) == FR_OK){

print("Open dir ok...\n");

while (((res = f_readdir(&dirs, &finfo)) == FR_OK) && finfo.fname[0]){

print("Read dir entry...\n");

//... любой код далее приводит к перезагрузке

}

}

Взято из примеров Chana, FatFs R0.10 ©ChaN, 2013 Revision ID 80960, платформа BlackFin.

Получаем:

Open dir ok...

Read dir entry...

Exception handler:: Hardware error

Убил пол дня на поиски места падения, но терпения не хватило.. пришлось вернуться к FatFs R0.07c где все работает без проблем :(

ps: Проблема решилась установкой параметра:

#define _USE_LFN 1

Изменено пользователем Ndf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делал одновременные обращения к разным файлам на запись и на чтение на одном диске - все работает (версия FatFs - R0.08b). _FS_LOCK не использовал.

 

Да, тоже заработало. Были проблемы с доступом к СД-карте(слишком быстро) и УСБ запрос некорректно отрабатывался. Теперь все пишет и читает одновременно, хоть из 5и файлов :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надеюсь, перед этим вызовом

while (((res = f_readdir(&dirs, &finfo)) == FR_OK) && finfo.fname[0]){

Вы делали finfo.lfsize = 0; finfo.lfname = NULL; ?

Это такая засадная засада :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возник такой вопрос :

 

Использую библиотеку FatFS совместно с операционкой freertos . В устройстве две SD карты, и разумеется возникает желание создать два независимых потока записи. Но вот беда : в fatFS перед работой с файлом требуется выбрать диск функией f_chdrive, эта функция меняет глобальную переменную CurrVol . Получается, нельзя создать два независимых потока, а нужно ждать пока в первом потоке закончится работа с диском, переключится на второй, изменить выбор диска вызвав f_chdrive , и т.д. Это глупость fatFS , или я чего-то не понимаю ?

 

И зачем поле

BYTE drv; /* Physical drive number */

находится в структуре FATFS которая в свою очередь находится в структуре FIL ? Т.е. если в объекте файла уже есть номер диска, то зачем нужна функция f_chdrive, которая сохраняет номер диска в какой-то глобальной переменной ? Может быть выбирать диск при помощи f_chdrive нужно только при создании файла , а дальше при работе с файлом номер диска берётся из объекта файла, и с многопотоковостью проблем не возникает ? Ну а почему тогда не сделана просто передача номера диска как параметра в функцию f_open ?

 

Заранее спасибо за разъяснения !

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возник такой вопрос :

 

не знаю насколько в тему...но..

вроде как есть понятие текущий путь для каждого тома свой.

и собственно путь объекта файловой системы(если задаётся явно). скорее всего отсюда ноги растут.

 

 

И встречный вопрос:

Вы говорите что юзаете больше чем одну флэш. А что за железку запускаете? Интересует камень и как оперируете CS-ами? На аппаратном уровне

или софтверном? Есть ли поддержка со стороны железа, и что является фазой переключения(если переключаете)?

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не знаю насколько в тему...но..

вроде как есть понятие текущий путь для каждого тома свой.

и собственно путь объекта файловой системы(если задаётся явно). скорее всего отсюда ноги растут.

 

Ну так это всё касается локальных переменных, с которыми происходит переключение контекста. А глобальная - она физически одна.

 

 

И встречный вопрос:

Вы говорите что юзаете больше чем одну флэш. А что за железку запускаете? Интересует камень и как оперируете CS-ами? На аппаратном уровне

или софтверном? Есть ли поддержка со стороны железа, и что является фазой переключения(если переключаете)?

 

STM32L151RDT6 . У него хватает SPI что бы развесить флэшки. CS просто ногой. Т.е. для каждой флэшки независимый SPI

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...