Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FatFs на STM32 - кеширование FAT32?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
sonycman
Всем доброго времени суток.

На девайсе под управлением STM32 есть процедура, которая создаёт сортированный по алфавиту список файлов FAT32 диска на флеш карточке.
Используется FatFs версии 0.08.
Количество файлов в списке может быть максимум 500.

На днях обратил внимание, что львиная доля времени (около 90%), затрачиваемого на сортировку, потребляется функцией файловой системы f_open().
Поковырявшись в её дебрях, обнаружил, что в свою очередь это вызвано подфункцией move_window(), которая подгружает по одному сектору из, вероятно, каталога фат.

То есть чтобы открыть файл, файловая система продирается через структуру фат до того, как найдёт запись с информацией по нужному файлу.
Считывание ведётся по одному сектору.
И так для каждого файла.

Вот и подумалось тут, а почему бы не ввести кеширование для секторов, запрашиваемых функцией move_window()?

Главный вопрос здесь - хватит ли для этого 10-20 килобайт оперативки?
К сожалению, приходится довольствоваться только внутренним ОЗУ контроллера.

Наверное, для FAT32 с большим количеством файлов кеширование 20 килобайт (40 секторов) не будет эффективным?
aaarrr
Цитата(sonycman @ Jul 5 2010, 13:55) *
Наверное, для FAT32 с большим количеством файлов кеширование 20 килобайт (40 секторов) не будет эффективным?

Ну почему же? Любой кэш лучше, чем его отсутствие. Особенно если использовать чтение группы блоков для заполнения строки.
sonycman
Цитата(aaarrr @ Jul 5 2010, 14:04) *
Ну почему же? Любой кэш лучше, чем его отсутствие. Особенно если использовать чтение группы блоков для заполнения строки.

Хм, спасибо, тогда попробую, когда будет время.

move_window() запрашивает по одному сектору, как тут организуешь мультисекторное чтение?
Если только запросы будут идти последовательно по порядку.

В любом случае, надо сначала посмотреть, как именно идёт чтение - организовать лог и писать туда номера запрашиваемых секторов.
Тогда будет видна общая картина smile.gif
aaarrr
Цитата(sonycman @ Jul 5 2010, 14:35) *
move_window() запрашивает по одному сектору, как тут организуешь мультисекторное чтение?

Читать сразу строку, получится своего рода упреждающее чтение. Если не увлекаться увеличением длины строки, то в мусор пойдет не так много данных.
Если интересно, могу описать систему кэширования, которую я применяю в своих проектах.
sonycman
Цитата(aaarrr @ Jul 5 2010, 14:43) *
Читать сразу строку, получится своего рода упреждающее чтение. Если не увлекаться увеличением длины строки, то в мусор пойдет не так много данных.
Если интересно, могу описать систему кэширования, которую я применяю в своих проектах.

Конечно интересно, опишите пожалуйста smile.gif

Я пока глубоко не копал в структуру FAT на диске, поэтому слабо понимаю механику работы файловой системы.

Тут ведь ещё есть нюанс с записью - надо ли будет перед выполнением записи на диск/в фат сбрасывать кеш?
aaarrr
Цитата(sonycman @ Jul 5 2010, 14:52) *
Конечно интересно, опишите пожалуйста smile.gif

Хорошо.

Используются две структуры:
Код
struct SD_CACHE_ENTRY
{
    struct SD_CACHE_ENTRY    *next;
    unsigned int            sec;
    unsigned char            *data;
};

struct SD_WRITE_BUFFER_ENTRY
{
    unsigned int            sec;
    unsigned char            *data;
};

Первая описывает строку кэша, из этих записей формируется односвязный список. Вторая - для буфера записи, сложены в виде массива. Отдельно вводим переменную, указывающую текущее заполнение буфера записи - sd_wbuff_level.
Данные отделены от списка для более эффективной работы кэша самого процессора, для STM32 можно буферы внести в структуру.
При инициализации диска формируется список из SD_CACHE_ENTRY, поля sec заполняются значением SD_CACHE_INVALID_SEC (0xffffffff); переменную sd_wbuff_level устанавливаем в 0.
Число секторов в строке у меня выбрано равным 8.

Чтение:
1. Последовательно проходим по списку, если запрашиваемый сектор находится внутри имеющейся в кэш строки:
1.1. Копируем данные из кэш
1.2. Переставляем строку в начало списка (это нужно для увеличения производительности - редко использующиеся строки будут постепенно падать в конец списка)
2. Если данные в кэш отсутствуют, то:
2.1. Сбрасываем на диск буфер записи (некоторое упрощение, чтобы не искать данные в буфере)
2.2. Читаем с карты строку, заполняя при этом последнюю из записей, по которым ходили в п.1
2.3. Переставляем заполненную строку в начало списка

Запись:
1. Проходим по списку. Если нужная строка найдена, заменяем в ней данные и запоминаем адрес
2. Проходим по буферу записи до уровня sd_wbuff_level, добавляем запись и увеличиваем sd_wbuff_level, если целевой сектор отсутствует
3. При заполнении структуры буфера записи заменяем адрес в SD_WRITE_BUFFER_ENTRY на адрес в кэше, если в п.1 строка была найдена (исключаем лишнее копирование)

Очистка буфера записи:
1. Сортируем записи в буфере по возрастанию номеров блоков
2. Пишем данные с использованием мультиблочной записи

Вот как-то так.

P.S. У меня, правда, файловая система написана в расчете на кэшируемый диск, поэтому не стесняется что-то прочитать или записать, когда надо. Если над этой системой будет надстроена еще одна, то производительность несколько снизится.
sonycman
Спасибо!
Что-то вроде этого задумывал и я, только в условиях нехватки памяти кешировать нужно исключительно сектора каталогов фат (или как правильно называется область со структурами имён файлов?).

Вероятно, move_window() читает/пишет только такие сектора, поэтому попробую привязать кеш именно к ней...
sonycman
Хм, вот все же странно как то у Чена сделан подход к кешированию.
То есть кешировать абсолютно весь диск - нет проблем, делается это просто через функции ReadSectors() и WriteSectors().
Но это не сильно умно в условиях ограниченного количества оперативки.

Логичнее было бы закешировать только корневой каталог и FAT (при интенсивной работе с большим кол-вом файлов).

Но как это сделать, не модифицируя исходники Чена?
Почему он не предусмотрел такой возможности?
AHTOXA
Цитата(sonycman @ Jul 5 2010, 19:36) *
Вероятно, move_window() читает/пишет только такие сектора, поэтому попробую привязать кеш именно к ней...

Нет, move_window() универсальная, вызывается во всех случаях.
Цитата(sonycman @ Jul 6 2010, 00:49) *
Логичнее было бы закешировать только корневой каталог и FAT (при интенсивной работе с большим кол-вом файлов).

А может и нетsmile.gif Логичнее сделать кеширование как написал aaarrr, и тогда в кеше автоматически будут храниться наиболее востребованные данные. Чаще идёт обращение к FAT - значит в кеше FAT. К данным (многократный парсинг одного файла) - в кеше данные. И не надо будет гадать ничегоsmile.gif
sonycman
Цитата(AHTOXA @ Jul 5 2010, 23:26) *
Нет, move_window() универсальная, вызывается во всех случаях.

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

Цитата
А может и нетsmile.gif Логичнее сделать кеширование как написал aaarrr, и тогда в кеше автоматически будут храниться наиболее востребованные данные. Чаще идёт обращение к FAT - значит в кеше FAT. К данным (многократный парсинг одного файла) - в кеше данные. И не надо будет гадать ничегоsmile.gif

Это смотря какие условия.
К примеру - открыли мы файл (при этом кеш заполнился секторами корневого каталога), затем считали большой кусок этого файла.
В кеше будет содержимое считанного файла, которое и без него читается быстро.
Затем открываем другой файл - так как в кеше уже нет секторов каталога - снова идёт обращение к диску.

Зачем мне это надо?

Мне бы просто ускорить работу с каталогом smile.gif
aaarrr
Цитата(sonycman @ Jul 5 2010, 23:43) *
Мне бы просто ускорить работу с каталогом smile.gif

Увы, в условиях дефицита оперативки, придется так или иначе выкручиваться - добавлять в функцию чтения флаг запрета кэширования, например. Или встроить в FatFS отдельный кэш для каталогов и FAT. Просто прикрутить что-то снаружи не выйдет.
Хотя даже с ограниченным объемом памяти приведенный мной вариант может несколько облегчить жизнь за счет наличия своего рода упреждающего чтения.
AHTOXA
Цитата(sonycman @ Jul 6 2010, 01:43) *
А во всех - это в каких?

Ну вообще во всех. Эта функция грузит сектор в единственный буфер объекта-файловой системы. Нужен сектор FAT - грузит его. Читаем данные - грузит их (и FAT конечно выгружен)

Цитата
Это смотря какие условия.
К примеру - открыли мы файл (при этом кеш заполнился секторами корневого каталога), затем считали большой кусок этого файла.
В кеше будет содержимое считанного файла, которое и без него читается быстро.

Если файл больше чем кэш, то да, придётся предпринять дополнительные шаги. Первый из возможных - кешировать только сектора из FAT. Кстати, в другой известной имплементации FAT - чтение данных и чтение FAT изначально разделены.
Хотя можно и с кешированием похимичить. Например, оставлять в кэше сектор лишь на второй раз.
sonycman
Цитата(aaarrr @ Jul 6 2010, 00:21) *
Увы, в условиях дефицита оперативки, придется так или иначе выкручиваться - добавлять в функцию чтения флаг запрета кэширования, например. Или встроить в FatFS отдельный кэш для каталогов и FAT. Просто прикрутить что-то снаружи не выйдет.
Хотя даже с ограниченным объемом памяти приведенный мной вариант может несколько облегчить жизнь за счет наличия своего рода упреждающего чтения.

Оптимальный способ для меня - использовать флаг разрешения кеширования.
Тогда в исходники FatFs достаточно встроить пару строк (к примеру, в функцию f_open() или в move_window()), остальным займётся драйвер.

Однако, это имеет смысл только в случае, когда все требуемые сектора каталога смогут поместиться в кеш.
Иначе пользы будет ноль sad.gif

Цитата(AHTOXA @ Jul 6 2010, 00:56) *
Ну вообще во всех. Эта функция грузит сектор в единственный буфер объекта-файловой системы. Нужен сектор FAT - грузит его. Читаем данные - грузит их (и FAT конечно выгружен)

А как же мультисекторные чтение/запись?

Нет, конечно-же, не пугайте так smile.gif
Эта функция используется только в конфигурации _FS_TINY.
В остальных случаях идёт прямое обращение к disk_read() - к драйверу.

Привыкли, наверное, к AVR?

Цитата
Если файл больше чем кэш, то да, придётся предпринять дополнительные шаги. Первый из возможных - кешировать только сектора из FAT.

Да, именно это мне и требуется.

Хотя, даже в случае наличия 20 килобайт памяти их для этого не хватает sad.gif
Нужны "метры"! biggrin.gif
aaarrr
Цитата(sonycman @ Jul 6 2010, 00:59) *
Однако, это имеет смысл только в случае, когда все требуемые сектора каталога смогут поместиться в кеш.
Иначе пользы будет ноль sad.gif

Если используется именно FAT32 (или не корневой каталог FAT16), то смысл будет иметь любой кэш объемом более одного кластера - так по крайней мере активный сектор FAT'а будет всегда "на плаву". Словом, некоторый выигрыш получите практически в любом случае.
Конечно, чем больше объем - тем лучше. Можно сделать "как у больших", отдав всю не выделенную приложениям память под нужды дискового кэша. Правда, в случае STM32 без внешней ОЗУ это уже излишества.
sonycman
Цитата(aaarrr @ Jul 6 2010, 01:12) *
Конечно, чем больше объем - тем лучше. Можно сделать "как у больших", отдав всю не выделенную приложениям память под нужды дискового кэша. Правда, в случае STM32 без внешней ОЗУ это уже излишества.

Вот именно.
Мне просто стало интересно, почему основное время процедура сортировки теряет не на собственно сортировке, а на банальном открытии файла sad.gif, вот и полез разбираться.
Особых проблем не будет и без кеша, конечно.

ЗЫ: Правильно ли я рассуждаю: к примеру, выделяем на кеш 40 секторов.
Вызываем f_open() - она начинает двигаться по корневому каталогу в поисках целевого файла, последовательно считывая сектора.
Скажем, находит его после считывания пятидесяти секторов, то есть в кеше находятся сектора 10 - 50.

Вызываем f_open() снова - другой файл - чтение корневого каталога повторяется опять с первого сектора... которого в кеше нет.
Соответственно, снова последовательно считываются все сектора заново, так как первый сектор замещает 10, второй - 11 и т.д.

В этой ситуации пользы от кеша - ровно ноль.

Но это теория. Надо проверить на практике.
aaarrr
Цитата(sonycman @ Jul 6 2010, 01:35) *
В этой ситуации пользы от кеша - ровно ноль.

Нет, это не совсем так. Во-первых, читаем не по одному сектору, что уже дает преимущество в скорости (причем иногда в разы). Во-вторых, вы упускаете чтение собственно FAT. Если же речь идет о чтении корневого каталога FAT16, то его длина обычно составляет 16кбайт, что позволяет спокойно разместить его даже в памяти STM32.
sonycman
Цитата(aaarrr @ Jul 6 2010, 01:51) *
Нет, это не совсем так. Во-первых, читаем не по одному сектору, что уже дает преимущество в скорости (причем иногда в разы). Во-вторых, вы упускаете чтение собственно FAT. Если же речь идет о чтении корневого каталога FAT16, то его длина обычно составляет 16кбайт, что позволяет спокойно разместить его даже в памяти STM32.

Речь о FAT32.

А для чего читать FAT, разве добраться до записи с информацией о файле (с именем и первым сектором) нельзя просто последовательно читая каталог?

Если, кроме каталога, читаются ещё и другие сектора - тогда это только увеличивает требования к размеру кеша...
aaarrr
Цитата(sonycman @ Jul 6 2010, 02:01) *
А для чего читать FAT, разве добраться до записи с информацией о файле (с именем и первым сектором) нельзя просто последовательно читая каталог?

А как последовательно читать каталог, не читая при этом FAT? Каталог - это тот же файл, за исключением случая корневого каталога FAT12/16.

Цитата(sonycman @ Jul 6 2010, 02:01) *
Если, кроме каталога, читаются ещё и другие сектора - тогда это только увеличивает требования к размеру кеша...

FAT нужно будет читать при переходе на каждый следующий кластер файла, то есть данные FAT не будут выведены из кэша, если только его размер превышает размер одного кластера диска. Таким образом кэш размером 20кбайт вполне может быть полезен.
sonycman
Получил результаты своего отладочного логгера, который сохранил историю запросов на чтение диска при работе функции f_open().
Цифры - LBA сектора в шестнадцатеричном виде:
CODE

00004000
00004001
00004002
00004003
00004004
00004005
00004006
00004007
00004008
00004009
0000400a
0000400b
0000400c
0000400d
0000400e
0000400f
00004010
00004011
00004012
00004013
00004014
00004015
00004016
00004017
00004018
00004019
0000401a
0000401b
0000401c
0000401d
0000401e
0000401f
00004020
00004021
00004022
00004023
00004024
00004025
00004026
00004027
00004028
00004029
0000402a
0000402b
0000402c
0000402d
0000402e
0000402f
00004030
00004031
00004032
00004033
00004034
00004035
00004036
00004037
00004038
00004039
0000403a
0000403b
0000403c
0000403d
0000403e
0000403f
0000386c
00004040
00004041
00004042
00004043
00004044
00004045
00004046
00004047
00004048
00004049
0000404a
0000404b
0000404c
0000404d
0000404e
0000404f
00004050
00004051
00004052
00004053
00004054
00004055
00004056
00004057
00004058
00004059
0000405a
0000405b
0000405c
0000405d
0000405e
0000405f
00004060
00004061
00004062
00004063
00004064
00004065
00004066
00004067
00004068
00004069
0000406a
0000406b
0000406c
0000406d
0000406e
0000406f
00004070
00004071
00004072
00004073
00004074
00004075
00004076
00004077
00004078
00004079
0000407a
0000407b
0000407c
0000407d
0000407e
006006c0
006006c1
006006c2
006006c3
006006c4
006006c5
006006c6
006006c7
006006c8
006006c9
006006ca
006006cb
006006cc
006006cd
006006ce

Кластер на карточке равен 32 килобайтам.

Как видно, чтобы открыть файл, считывается два с лишним кластера каталогов (!!!) (а между ними проскакивает сектор FAT?).

И так практически для всех 57 файлов папки, а если точнее - методом односекторного чтения считывается 131 сектор для первого файла, и уже 143 сектора для последнего.

Хм, действительно, если читать сразу по 8 секторов за раз, то можно несколько выиграть. smile.gif

ЗЫ: завтра посмотрю, какая картина будет при сортировке 500 файлов.
Аж страшно становится smile3046.gif

ЗЗЫ: до чего убогая файловая система, господи.
Чтобы добраться до грошового файлика весом в сотню байт, требуется перерыть килобайты мусора в виде каталогов... sad.gif
AHTOXA
Цитата(sonycman @ Jul 6 2010, 03:09) *
А как же мультисекторные чтение/запись?

Нет, конечно-же, не пугайте так smile.gif
Эта функция используется только в конфигурации _FS_TINY.
В остальных случаях идёт прямое обращение к disk_read() - к драйверу.
Да, действительно. Видимо я ковырял очень старую версию FatFs, где ещё не было мультисекторного чтения/записи. Или просто что-то перепуталsmile.gif
Цитата
Привыкли, наверное, к AVR?

Вы меня наверное с кем-то путаете?
sonycman
Цитата(AHTOXA @ Jul 6 2010, 13:11) *
Вы меня наверное с кем-то путаете?

Показалось просто.
Извините unsure.gif

Прогнал сортировщик на файлах в другой папке, общим количеством в 500.
Первый файл - 129 секторов каталога, похоже на предыдущий скан.
Зато вот последний:
CODE

00004000
00004001
00004002
00004003
00004004
00004005
00004006
00004007
00004008
00004009
0000400a
0000400b
0000400c
0000400d
0000400e
0000400f
00004010
00004011
00004012
00004013
00004014
00004015
00004016
00004017
00004018
00004019
0000401a
0000401b
0000401c
0000401d
0000401e
0000401f
00004020
00004021
00004022
00004023
00004024
00004025
00004026
00004027
00004028
00004029
0000402a
0000402b
0000402c
0000402d
0000402e
0000402f
00004030
00004031
00004032
00004033
00004034
00004035
00004036
00004037
00004038
00004039
0000403a
0000403b
0000403c
0000403d
0000403e
0000403f
0000386c
00004040
00004041
00004042
00004043
00004044
00004045
00004046
00004047
00004048
00004049
0000404a
0000404b
0000404c
0000404d
0000404e
0000404f
00004050
00004051
00004052
00004053
00004054
00004055
00004056
00004057
00004058
00004059
0000405a
0000405b
0000405c
0000405d
0000405e
0000405f
00004060
00004061
00004062
00004063
00004064
00004065
00004066
00004067
00004068
00004069
0000406a
0000406b
0000406c
0000406d
0000406e
0000406f
00004070
00004071
00004072
00004073
00004074
00004075
00004076
00004077
00004078
00004079
0000407a
0000407b
0000407c
0000407d
0000407e
00612980
00612981
00612982
00612983
00612984
00612985
00612986
00612987
00612988
00612989
0061298a
0061298b
0061298c
0061298d
0061298e
0061298f
00612990
00612991
00612992
00612993
00612994
00612995
00612996
00612997
00612998
00612999
0061299a
0061299b
0061299c
0061299d
0061299e
0061299f
006129a0
006129a1
006129a2
006129a3
006129a4
006129a5
006129a6
006129a7
006129a8
006129a9
006129aa
006129ab
006129ac
006129ad
006129ae
006129af
006129b0
006129b1
006129b2
006129b3
006129b4
006129b5
006129b6
006129b7
006129b8
006129b9
006129ba
006129bb
006129bc
006129bd
006129be
006129bf
00003b73
006129c0
006129c1
006129c2
006129c3
006129c4
006129c5
006129c6
006129c7
006129c8
006129c9
006129ca
006129cb
006129cc
006129cd
006129ce
006129cf
006129d0
006129d1
006129d2
006129d3
006129d4
006129d5
006129d6
006129d7
006129d8
006129d9
006129da
006129db
006129dc
006129dd
006129de
006129df
006129e0
006129e1
006129e2
006129e3
006129e4
006129e5
006129e6
006129e7
006129e8
006129e9
006129ea
006129eb
006129ec
006129ed
006129ee
006129ef
006129f0
006129f1
006129f2
006129f3
006129f4
006129f5
006129f6
006129f7
006129f8
006129f9
006129fa
006129fb
006129fc
006129fd
006129fe

это вообще жесть - 256 секторов, четыре полных кластера!

Попробую сделать простой кеш в виде считывания при любом запросе сразу 8 секторов.
Отводить 20 килобайт не вижу смысла - огромное количество запрашиваемых секторов в них разместить никак не получится.

Отведу память чисто под эти 8 секторов, и всё.
Посмотрим, какие будут результаты...
defunct
Цитата(sonycman @ Jul 6 2010, 13:24) *
это вообще жесть - 256 секторов, четыре полных кластера!

А что мешает менять порядок просмотра каталога? Пусть закешированы у вас с 10 по 40-й сектора, так посмотрите вначале в них, а потом читайте с 0 по 9 и все остальные выше 40-го...
aaarrr
Цитата(defunct @ Jul 13 2010, 00:13) *
А что мешает менять порядок просмотра каталога? Пусть закешированы у вас с 10 по 40-й сектора, так посмотрите вначале в них, а потом читайте с 0 по 9 и все остальные выше 40-го...

Подобное решение хоть и возможно теоретически, но весьма значительно усложнит реализацию файловой системы. Как минимум придется соорудить еще один кэш для цепочки FAT просматриваемого каталога.
sonycman
Цитата(aaarrr @ Jul 13 2010, 01:41) *
Подобное решение хоть и возможно теоретически, но весьма значительно усложнит реализацию файловой системы. Как минимум придется соорудить еще один кэш для цепочки FAT просматриваемого каталога.

Не стоит это того.
Если нужен нормальный кеш - надо ставить много памяти.

Простым чтением по запросу MoveWindow() вместо одного сектора - сразу восьми, я получил выигрыш в скорости в 20%.
Не бог весть что, но тоже результат, с учётом всего лишь 4 килобайт отведённой под такой кеш памяти smile.gif
aaarrr
Цитата(sonycman @ Jul 13 2010, 01:47) *
Не стоит это того.
Если нужен нормальный кеш - надо ставить много памяти.

Это верно. Совсем недавно пришлось в одном проекте выделить под кэш 4 мегабайта, так как каталог может содержать 100 тысяч файлов с именами вида:
XX000000.XXX
XX000001.XXX
До кучи было добавлено битовое поле на 100 кбит, чтобы быстро выяснять наличие файла с произвольным номером.
Грубо, зато просто и эффективно.

Цитата(sonycman @ Jul 13 2010, 01:47) *
Простым чтением по запросу MoveWindow() вместо одного сектора - сразу восьми, я получил выигрыш в скорости в 20%.
Не бог весть что, но тоже результат, с учётом всего лишь 4 килобайт отведённой под такой кеш памяти smile.gif

А не собирали статистику, сколько из этих восьми идет впрок?
sonycman
Цитата(aaarrr @ Jul 13 2010, 02:52) *
А не собирали статистику, сколько из этих восьми идет впрок?

Я выше в этой теме приводил списки запрашиваемых секторов каталога.
Если судить по ним, только редкие обращения к фат (один сектор из 64) идут в оверхед.

Пробовал читать по 16 секторов - уже эффективность немного хуже, чем по 8.
Ivan Kuznetzov
извиняюсь за оффтоп, sonycman, как у Вас объявлена структура FATFS fs; ? как глобальная? или в процедуре main()? у меня возникла интересная проблемка: когда эта структура объявлена глобально, запись в файл глючит, а именно, при записи в файл первый элемент байтового массива искажается процедурой f_write. (байтовый массив объвлен глобально).
sonycman
Цитата(Ivan Kuznetzov @ Aug 23 2010, 00:20) *
извиняюсь за оффтоп, sonycman, как у Вас объявлена структура FATFS fs; ? как глобальная? или в процедуре main()? у меня возникла интересная проблемка: когда эта структура объявлена глобально, запись в файл глючит, а именно, при записи в файл первый элемент байтового массива искажается процедурой f_write. (байтовый массив объвлен глобально).

Именно глобально.
Наверное, у Вас какая то накладочка выходит с массивом или со стеком, f_write() тут не при чём, имхо.
Ivan Kuznetzov
Цитата(sonycman @ Aug 23 2010, 07:41) *
Именно глобально.
Наверное, у Вас какая то накладочка выходит с массивом или со стеком, f_write() тут не при чём, имхо.

массив из 512 байт тоже объявлен глобально.
Если объявляю FATFS fs глобально, а массив data[512] запихиваю в функцию - начинает работать нормально, тоесть меняю местами. если всё делаю глобально - опять косяк, после f_write содержимое первого байта массива меняетя. Именно после того, как мы записываем массив на карту командой f_write (смотрю дебаггером), первый байт становится красненьким ... smile3046.gif
файловый объект FIL file; у меня объявлен глобально, это правильно?
aaarrr
Посмотрите в map-файле, что стоит перед data[], от этого можно оттолкнуться при поиске виновных. Ну, или если уж дебаггер под рукой - так и поставьте ему точку останова по событию записи в первый элемент портящегося массива.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.