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

FatFS и SD-карта. Ускорить чтение файлов с карты

2 часа назад, __inline__ сказал:

Не могли бы вы осветить этот момент подробнее? Пробовал читать больше чем по 512 байт:  по 1024 и по 4096 - файловая система работает некорректно с такими длинами чтений.

Смотреть размеры буфера драйвера и ФС, ну и честно говоря, не помню, в SPI режиме может ли карта работать с блоками 4К, уже сто лет в однобитке не работал...

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


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

Эксперимент выявил следующее:

 

Чтение 2048 секторов (8 МБ) мультиблочной командой чтения  занимает 3,6 секунды.  Причем класс скорости не важен - 4 или 10. Всё читается одинаково, ибо этот класс скорости описывает операции записи, которые лично мне в данной задаче неинтересны.   Выходит 2,2 МБайт/с

 

Кеширование секторов в функции move_window() у Чана (FatFS) ни к чему не привело.  Кеширование делал по принципу индексации секторов и проставлению лайков к ним если при чтении кеша они находятся.  Заполнение кеша происходит от начала к концу и в первую очередь по принципу "слабого звена" - чем меньше лайков у индекса (редко используется) тем выше вероятность замены.  Считал сектор - закешируй и поставь ему лайк.....

 

Дальнейшее ускорение я вижу за счёт небольшого сжатия - добавить RLE или Хаффмана для исходных  данных - картинки в формате 16 бит   и звук  -ADPCM.

 

На счёт размера блоков карты памяти  - там от 1 до 512, карт с бОльшим размером блока я не видел.   HxD  под виндами видит сектор 512 байт.  На счёт установить буфер в FatFs больше 512 - это приведет к тому что надо будет чтение 1 сектора  имитировать чтением сразу 4-х.  Под виндой не закинешь на карту ничего, если самому FatFS под виндой не использовать и писать работу с диском через IOCTL (такую штуку я написал давно, но распостранения она не получила)

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

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


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

51 минуту назад, __inline__ сказал:

Чтение 2048 секторов (8 МБ) мультиблочной командой чтения  занимает 3,6 секунды.  Причем класс скорости не важен - 4 или 10. Всё читается одинаково, ибо этот класс скорости описывает операции записи, которые лично мне в данной задаче неинтересны.   Выходит 2,2 МБайт/с

Как говорит спецификация на SD:

As opposed to SD mode, the card cannot guarantee its Speed Class. In SPI mode, host shall treat the 
card as Class 0 no matter what Class is indicated in SD Status.

Так что про классы скорости можно забыть. Да и как я понял оттуда же: для высокоскоростных режимов нужно использовать питание 1.8V и соответствующие уровни сигналов. А в SPI это тоже недоступно.

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


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

13 minutes ago, jcxz said:

Да и как я понял оттуда же: для высокоскоростных режимов нужно использовать питание 1.8V и соответствующие уровни сигналов.

Уровни сигналов 1.8V появились с введением UHS-I, "обычный" 50MHz Hi-Speed работает с уровнями 3.3V. Питание всегда остается 3V (UHS-II не рассматриваем).

 

1 hour ago, __inline__ said:

Под виндой не закинешь на карту ничего, если самому FatFS под виндой не использовать и писать работу с диском через IOCTL (такую штуку я написал давно, но распостранения она не получила)

Звбавно, что под Линуксом такое вполне проходит (сектор диска 512, сектор FAT 4096).

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


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

18 minutes ago, aaarrr said:

Звбавно, что под Линуксом такое вполне проходит (сектор диска 512, сектор FAT 4096).

У меня стоит убунта второй осью, надо будет попробовать )))  А вообще, я давным давно написал файловый эксплорер на FatFs под винду для SD-карточек ))) Можно делать размер виртуального сектора любым, я делал 8 кБ - скорость на порядок возрастала, да!  Но проблема в том, что отформатировать карту проблема - приходится под виндой тереть нулевой сектор, перевтыкать карту и только потом форматировать своими побрякушками.   Иначе винда определяет логический диск и не даёт отформатировать его.

 

41 minutes ago, jcxz said:

Как говорит спецификация на SD:


As opposed to SD mode, the card cannot guarantee its Speed Class. In SPI mode, host shall treat the 
card as Class 0 no matter what Class is indicated in SD Status.

Так что про классы скорости можно забыть. Да и как я понял оттуда же: для высокоскоростных режимов нужно использовать питание 1.8V и соответствующие уровни сигналов. А в SPI это тоже недоступно.

 

Это очень пичально.. (( Что же они SPI режимы невзлюбили?   Не всегда удаётся SDIO задействовать, по причине банальной занятости ножек контроллера на другие интерфейсы ))) А мультиплексировать и делить во времени тоже не вариант.

 

1 hour ago, __inline__ said:

Дальнейшее ускорение я вижу за счёт небольшого сжатия - добавить RLE или Хаффмана для исходных  данных - картинки в формате 16 бит   и звук  -ADPCM

 

Хаффман плохо жмёт ADPCM, на 18 % выигрыш.  RAR ещё хуже жмёт.  Для звука скорее всего лучше будет только сжатие с потерями качества.   А вот картинку в 16 бит Хаффман ужал в 5 раз почти ( RAR лучше, но он более ресурсоёмкий).

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

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


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

56 minutes ago, jcxz said:

Да и как я понял оттуда же: для высокоскоростных режимов нужно использовать питание 1.8V и соответствующие уровни сигналов. А в SPI это тоже недоступно.

Нет.  HighSpeed доступен и при 3,3 V.   Есть ещё более быстрый режим, и он требует 1,8V.    У меня карты без проблем переводятся в HighSpeed при питании 3,3V и через SPI.   Во всяком случае, я вижу прирост скорости.   И ответ после переключения карты получаю положительный.  И на запрос переключится в HighSpeed получаю добро от карты.

 

s8 SDCARD_HighSpeed(void) /* ??? */
{
 u8 CCCR[64];
 u8 crc[2];

 //Проверяем, умеет ли карта HS режим
 {
  SDCARD_Select();

  SDCARD_WaitNotBusy();

  //CMD6 command
  static const u8 cmd[]={0x40|0x06 /* CMD6 */,0x00,0xFF,0xFF,0xF1 /* ARG */,(0x7F<<1)|1 /* CRC7 + end bit*/ };
  SPI_TX((u8*)cmd,sizeof(cmd));

  if(SDCARD_ReadR1()!=0x00)
  {
   SDCARD_Unselect();
   return -1;
  }

  if(SDCARD_WaitDataToken(DATA_TOKEN_CMD6)<0)
  {
   SDCARD_Unselect();
   return -2;
  }

  SDCARD_ReadBytes(CCCR,sizeof(CCCR));

  SDCARD_ReadBytes(crc,sizeof(crc));

  SDCARD_Unselect();

  //Проверка бита SHS регистра карты CCCR
  if((CCCR[63-(400/8)]&0x01)!=0x01) return -3;
 }

 //Просим карту переключиться в HS режим
 {
  SDCARD_Select();

  SDCARD_WaitNotBusy();

  //CMD6 command
  static const u8 cmd[]={0x40|0x06 /* CMD6 */,0x80,0xFF,0xFF,0xF1 /* ARG */,(0x7F<<1)|1 /* CRC7 + end bit*/ };
  SPI_TX((u8*)cmd,sizeof(cmd));

  if(SDCARD_ReadR1()!=0x00)
  {
   SDCARD_Unselect();
   return -4;
  }

  if(SDCARD_WaitDataToken(DATA_TOKEN_CMD6)<0)
  {
   SDCARD_Unselect();
   return -5;
  }

  SDCARD_ReadBytes(CCCR,sizeof(CCCR));

  SDCARD_ReadBytes(crc,sizeof(crc));

  SDCARD_Unselect();
 }

 return 0;
}

 

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

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


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

Opus отлично жмёт музыку )))

А RLE оказался лучше Хаффмана на 16-битных картинках (используется модифицированный RLE, который  понимает что сжимать, а что оставлять)

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


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

5 часов назад, aaarrr сказал:

Звбавно, что под Линуксом такое вполне проходит (сектор диска 512, сектор FAT 4096).

У меня и не под линухом это идет "на ура", только не по SPI, конечно...

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


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

1 minute ago, mantech said:

У меня и не под линухом это идет "на ура", только не по SPI, конечно...

Речь о PC: винда считает такие карты неисправными.

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


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

5 часов назад, __inline__ сказал:

Это очень пичально.. (( Что же они SPI режимы невзлюбили? 

Дык наверно потому, что эи режимы уже при появлении сд карт первой редакции считались устаревшими (перешли в наследство от ММС карточек) вот и прикрывают их совсем уже так сказать...

6 часов назад, __inline__ сказал:

На счёт размера блоков карты памяти  - там от 1 до 512, карт с бОльшим размером блока я не видел.   HxD  под виндами видит сектор 512 байт. 

Сектор-то сектором, но в ФАТе все меряется на кластеры, а вот его размер, как правило, всегда больше сектора, и интерфейс SDIO позволяет читать за один запрос целым блоком по 4, 8, 16 и 32 КБайта. При этом резко повышается скорость чтения, т.к. "накладных расходов" гораздо меньше.

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

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


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

10 hours ago, mantech said:

Сектор-то сектором, но в ФАТе все меряется на кластеры, а вот его размер, как правило, всегда больше сектора,

 

Так карты давно уже отформатированы на размер кластера 32 кБ программой SDFormatter!  Но FatFs от этого быстрее не заработала. Потому что внутри неё идёт чтение секторов архаичными порциями по 512 байт даже в мультисекторной командой:  ждём токена, выкачиваем 512 байт, 2 байта CRC, и так по кругу. Да и вообще, FatFS не учитывает размер кластера.  Только сектор - минимальный и максимальный (обычно они равны)

 

и интерфейс SDIO позволяет читать за один запрос целым блоком по 4, 8, 16 и 32 КБайта. При этом резко повышается скорость чтения, т.к. "накладных расходов" гораздо меньше.

 

Не видал такого!  В STM-ном коде от кало-куба идёт общение карты через 4-битный SDIO,  но чтение порциями в мультисекторных командах там по-прежнему - по 512 байт :biggrin:

 

Нет такого там чтобы сделать чтение 4 кбайт через SPI, везде идут SPI-чтения по 512 байт.   Тем не менее, мультисекторное чтение даёт и в этом случае выигрыш в разы по сравнению с чтением по 1 сектору.   Но речь шла о том как заставить карту выдать  к примеру 4 кБайт данных, с минимум опросом одного токена + 2 байта ЦРЦ

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

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


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

15 часов назад, __inline__ сказал:

е видал такого!  В STM-ном коде от кало-куба идёт общение карты через 4-битный SDIO,  но чтение порциями в мультисекторных командах там по-прежнему - по 512 байт :biggrin:

 

Нет такого там чтобы сделать чтение 4 кбайт через SPI, везде идут SPI-чтения по 512 байт. 

С калокубом к счастью дел не имел, поэтому не знаю, что и чем он там читает... Про spi тоже спорить не буду - очень давно имел с ним дело, но про 4-32К на чтение и запись по SDIO скажу точно - работает! Смотрите, что у вас в фатфс не настроено или версия очень древняя

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

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


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

16 hours ago, __inline__ said:

Потому что внутри неё идёт чтение секторов архаичными порциями по 512 байт даже в мультисекторной командой:  ждём токена, выкачиваем 512 байт, 2 байта CRC, и так по кругу.

Это чтение одного блока сектора. Я уже не помню, но кажется размер блока тоже можно считать. Есть флешки, у которых стоит 2-4 чипа памяти - дык вот для них размер блока почти всегда выше в 2-4 раза.

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


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

9 hours ago, AVI-crak said:

Я уже не помню, но кажется

самая употребляемая фраза топика!

максимальный размер транзакции как и сказал @__inline__ для SPI режима не может быть больше 512байт. Для SDHC карт это жестко 512, для SDSC(<=2GB) от 1 до 512 вычитывается из READ_BL_LEN(CSD).

Чтобы не быть голословным, кусочек спеки Physical Layer Simplified Specification

image.thumb.png.738bd8f4f3634d73ac5207e9589ba51d.png

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


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

On 12/27/2019 at 5:06 PM, Integro said:

Чтобы не быть голословным, кусочек спеки Physical Layer Simplified Specification

 

Спасибо! :yes: Теперь я могу быть спокойным и искать другие пути решения.

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


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

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

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

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

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

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

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

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

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

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