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

Чтение из CF

Имеем некое автономное устройство, которое должно заглатывать данные из CF в свой внутренний буфер. Файлы имеют достаточно большие размеры (десятки-сотни мегабайт), поэтому скорость загрузки достаточно актуальна. CF отформатирована под FAT-16. Загрузка производится блоками по 2КБайта, т.е по 4 сектора. Устройство поддерживает PIO-4. Алгоритм действий:

 

1. Вычисляем очередной кластер (если надо), выискиваем в нем сектор, который пойдет первым в блоке.

2. Инициализируем процесс чтения из CF: устанавливаем адрес сектора, количество читаемых секторов (4), даем команду старт.

3. Ждем готовность карты.

4. Забираем данные. 1024 цикла по 2 байта.

5. Идем к пункту 1.

 

При PIO-4 пункт 4 занимает порядка 130 мкс.

Но вот что не очень приятно, пункт 3 занимает еще больше - около 150 мкс. Проверял на разных карточках. Понятно, что все мои потуги в плане ускорения непосредственно считывания из CF упираются в конечном счете в это время ожидания.

 

Какие здесь есть возможные варианты? Можно ли заставить карточку "думать" быстрее?

 

И еще попутный вопрос: столкнулся тут с таким понятием как "dual-channel interface" в применении к Compact Flash - что за зверь такой?

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


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

1. Вычисляем очередной кластер (если надо), выискиваем в нем сектор, который пойдет первым в блоке.

2. Инициализируем процесс чтения из CF: устанавливаем адрес сектора, количество читаемых секторов (4), даем команду старт.

3. Ждем готовность карты.

4. Забираем данные. 1024 цикла по 2 байта.

5. Идем к пункту 1.

 

 

При начальной инициализации в IdeInfo блоке смотрю на размер буфера карточки.

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

Скорректировав на размер буфера, вычислим номер следующего кластера и т.д.

 

Если нужно потреблять блоками по 2кБ и не хочется хранить всю цепочку FAT можно завести счётчик блоков имеющихся в буфере карточки и выбирать их из него пока буфер не исчерпается.

Лично я запоминал в памяти микроконтроллера номера стартового и последнего кластера файла,

после чтения/использования порции файла номер стартового кластера менял на следующий кластер блока, если достигли номера последнего кластера, то всё чтение окончено.

 

п.4 можно ускорить только используя DMA вместо PIO, из всего разнообразия карточек используемых мной не встретилась ни одна у которой не было-бы этого режима.

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


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

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

Заметил такую вещь: пункт №3 (ожидание готовности карточки) не зависит от того, сколько я попросил в команде на чтение секторов - 1 или 256, время ожидания всегда постоянное, около 150 мкс. Кроме того, если я "заказал" 1 сектор, а реально считываю больше, то они считываются правильно, как если бы я изначально заказал больше. Отсюда вывод: карточка использует Prefetch (упреждающую выборку), заполняя буфер по максимуму, отсюда и постоянное время ожидания.

А можно ли этот самый prefetch отключить?

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


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

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

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

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

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

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

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

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

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

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