Jump to content
    

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

Share this post


Link to post
Share on other sites

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

Вообщем в своем приложении нужно было создать таблицу разделов на 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);

 

Share this post


Link to post
Share on other sites

..

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

 

ик?

 

 

Share this post


Link to post
Share on other sites

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

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

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й бит номера цилиндра не тот, номер сектора получился тоже непонятно какой, вот и интересуюсь... :)

 

 

 

 

Share this post


Link to post
Share on other sites

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

 

 

Нашел глючок у Чана небольшой :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);

}

Share this post


Link to post
Share on other sites

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

 

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

Share this post


Link to post
Share on other sites

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

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

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

Edited by mantech

Share this post


Link to post
Share on other sites

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

...

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

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

 

Share this post


Link to post
Share on other sites

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

 

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

Edited by Ndf

Share this post


Link to post
Share on other sites

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

 

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

 

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

 

И зачем поле

BYTE drv; /* Physical drive number */

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

 

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

Share this post


Link to post
Share on other sites

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

 

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

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

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

 

 

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

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

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

 

 

 

Share this post


Link to post
Share on other sites

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

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

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

 

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

 

 

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

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

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

 

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...