Jump to content

    
Sign in to follow this  
pvo125

SD карта. Размер блока стирания и запись на нее.

Recommended Posts

Приветствую всех! Вопрос следующий у SD карт есть такой параметр как блок стирания. И размер этого блока (пробовал на двух 1гиговых картах) у одной 32 другой 64 КБ. Правильно ли я понимаю что при записи командами CMD24 или CMD25 карта предварительно стирает сектора в которые будет идти запись но так как у нее блок стирания например 64 килобайта то она стирает все 128 секторов (пусть сектор 512 байт) и не меньше. С того адреса который в качестве аргумента отправлен с командой CMD24/25 даже если пишется один сектор или несколько но их количество например 20 (некий блок по 10240 байт).

Тогда если я буду писать через fatfs файлы на такой карте. Может ли получится следующая ситуация. Файл существует он открывается для дозаписи в него. На уровне fatfs единица измерения уже кластер и пусть например этот кластер 16 КВ. Далее я вызываю f_write c количеством байт 10240. Внутри вызывается disk_write из которой вызывается уже моя реализация SD_MultiBlockWrite() и там предварительно стираются сектора на карте для ускорения процесса записи командой ACMD23. И вот карта стирает не только те сектора которые я запросил (10240 байт) не только тот кластер в который будет дописываться но и соседние следующие 3 кластера ( если кластер 16 КБ а блок очистки 64КБ ) Но ведь следующие соседние кластеры могут принадлежать другому файлу. Про это fatfs известно но самой то карте нет. Она чистит с заданного адреса +64КБ.

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

 

Если это так то подскажите кто как реализовывал. Слышал что нужно писать большими блоками но контроллер у меня stm32f103 там 20КБ ОЗУ но даже 16 не получится выделить под буфер для записи на карту.

 

Share this post


Link to post
Share on other sites
Но ведь следующие соседние кластеры могут принадлежать другому файлу. Про это fatfs известно но самой то карте нет. Она чистит с заданного адреса +64КБ.

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

Вот именно что известно. А если просто открыть файл и записать в середину 1 байт? По Вашей логике вокруг этого байта в файле вся инфа должна потеряться.

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

Share this post


Link to post
Share on other sites
Если это так то подскажите кто как реализовывал. Слышал что нужно писать большими блоками но контроллер у меня stm32f103 там 20КБ ОЗУ но даже 16 не получится выделить под буфер для записи на карту.

 

В современных картах блок стирания уже не имеет жестко определенного размера, wear leveling там гораздо сложней.

Поэтому ловить в FatFS уже нечего.

Если нужен жесткий детерминизм надо брать голую NAND и ставить на неё свою FS со своим выравниванием износа.

Например в MQX такое есть.

Share this post


Link to post
Share on other sites
Скорей всего она, при модификации части файла, переписывает весь блок стирания в новый чистый блок,

Может так оно и есть. Хотя единственное место где вызывается функция disk_ioctl c параметром GET_BLOCK_SIZE ( размер блока стирания карты ) это функция f_mkfs. форматирование карты. Слышал также что лучше делать при форматировании размер кластера равным как раз этому блоку стирания.

Получается что при записи кластера нет инфы у функции записи сколько будет стерто на карте...

Тут другое разглядел.В спецификации есть еще один параметр в CSD структуре он называется ERASE_BLK_EN и если он равен 0 то хост может стереть один или несколько units равных (поле SECTOR_SIZE+1)*512 байт. Как раз там пример показан когда запрашивается стереть с 5 по 40 сектор а карта стирает с 0 по 63 потому что у нее блок очистки равен (31+1) сектор.

А если он равен ERASE_BLK_EN=1 то размер блока стирания равен 1 или несколько блоков по 512 байт. Т е минимальный блок стирания равен 512 байт. На карте с которой пробовал как раз ERASE_BLK_EN=1 а поле erase sector size (SECTOR_SIZE) равно 0x7F те (127+1)*512=64КБ но я так понимаю когда ERASE_BLK_EN=1 то это поле не действует? Если это так то это конечно все меняет к лучшему. Все опасения о чем писал выше не сбудутся.

Кстати карты будут используются SDSC на 1 может быть 2 Гигабайта. Это про современность карт.

Если нужен жесткий детерминизм надо брать голую NAND и ставить на неё свою FS со своим выравниванием износа.

Например в MQX такое есть.

:laughing: Мне пожалуй проще выбрать какой то конкретный тип карт(минимальный блок очистки или кластер размером с этот блок стирания или если ERASE_BLK_EN=1 так как я писал то вообще тогда проблем нет ) и жестко его придерживаться. Изучить наверное дольше будет чем отсеять карты.

Share this post


Link to post
Share on other sites
Если это так то подскажите кто как реализовывал. Слышал что нужно писать большими блоками но контроллер у меня stm32f103 там 20КБ ОЗУ но даже 16 не получится выделить под буфер для записи на карту.

 

Вся прелесть работы с картами памяти как-раз в том, что весь этот гемор тут не нужен! Ибо всем низкоуровневым управлением занимается контроллер в карте паяти. Все, что вам(т.е. fatfs-у) нужно - читать и писать секторами, от 512байт до 4кб, а может и больше, все остальное сделает сама карта. Да, в случае с нандом все гораздо печальнее...

Edited by mantech

Share this post


Link to post
Share on other sites

и

On 5/16/2016 at 8:53 PM, mantech said:

 

Вся прелесть работы с картами памяти как-раз в том, что весь этот гемор тут не нужен! Ибо всем низкоуровневым управлением занимается контроллер в карте паяти. Все, что вам(т.е. fatfs-у) нужно - читать и писать секторами, от 512байт до 4кб, а может и больше, все остальное сделает сама карта. Да, в случае с нандом все гораздо печальнее...

 

 

Подниму старую тему

А как же параметр SD card preferred_erase_size

у SDHC он равен аж 4 МB

Предполагаю что контроллер карты всегда СТИРАЕТ по 4 MB , а стирание по одному сектору эмулирует виртуально, за счет перемещения блоков

а как на саммо деле?

 

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

 

Share this post


Link to post
Share on other sites
21 hours ago, AVI-crak said:

Отложенная запись. При выходе за пределы сектора - записываются те блоки, что не изменены но стёрты.

Зачем записывать сетрые блоки, ведь достаточно просто стереть?

 

При wear leveling  вообще не понятно что происходит при стирание 4мбайт?  что конкретно стирается , если все блоки уже переназначены?

Карта при выранвивание износа какими размерами блоков оперирует?  512байт, 4Мбайт или?

 

Share this post


Link to post
Share on other sites
3 минуты назад, digital сказал:

Карта при выранвивание износа какими размерами блоков оперирует?  512байт, 4Мбайт или?

Какой NAND в них стоит, такими блоками и оперирует, уж точно не 512байт, от 100Кб до неск. мегабайт...

Share this post


Link to post
Share on other sites
16 hours ago, mantech said:

Какой NAND в них стоит, такими блоками и оперирует, уж точно не 512байт, от 100Кб до неск. мегабайт...

спасибо

 

Если контроллер оперирует блоками по 4Мбайта, то если произвольно стирать писать сектора по 512 байт, то блок получаеться будет переписан аж 8192 раза (ну если все случаный записи попадут в блок)?

Блок наверное перемещаеться не всегда, а когда превысит некоторое количество раз использований.

 

 

Я правильное понимаю что при кольцевой записи, лучше не использовать файловых систем, писать по кругу и предварительно стирать большими блоками по 4мбайт, естественно выровненных по 4мбайта? тогда будет минимальный износ?

а если стирать по одному сектору (512), то будет максимальный износ?  (точнее в 8192 раза больше? )


 

 

Share this post


Link to post
Share on other sites
5 минут назад, digital сказал:

Я правильное понимаю что при кольцевой записи, лучше не использовать файловых систем, писать по кругу и предварительно стирать большими блоками по 4мбайт, естественно выровненных по 4мбайта? тогда будет минимальный износ?

Очевидно, что если не нужно ФС, то конечно лучше без них, т.к. при этом кроме собственно информации пишется еще и служебная в таблицы ФС. По размеру блоков - чем больше - тем лучше для карты и быстрее собственно запись. Конечно интерфейс карты не даст писать блоками по мегабайту и выше, да и смысла в этом нет вообще, нужен огромный буфер и при проблемах с питанием можно много чего потерять, но 4-32 Кбайта за транзакцию - вполне норм.

Edited by mantech

Share this post


Link to post
Share on other sites

 

40 minutes ago, mantech said:

Очевидно, что если не нужно ФС, то конечно лучше без них, т.к. при этом кроме собственно информации пишется еще и служебная в таблицы ФС. По размеру блоков - чем больше - тем лучше для карты и быстрее собственно запись. Конечно интерфейс карты не даст писать блоками по мегабайту и выше, да и смысла в этом нет вообще, нужен огромный буфер и при проблемах с питанием можно много чего потерять, но 4-32 Кбайта за транзакцию - вполне норм.

 

Спасибо, но вопрос больше про объем стирание, а не про запись

 

я правильно понимаю что если я стираю-записываю ОДИН сектор 512 байт, то контроллер sdcard все равно стирает весь блок 4мбайта и заново его записывает?

Share this post


Link to post
Share on other sites
1 час назад, digital сказал:

я правильно понимаю что если я стираю-записываю ОДИН сектор 512 байт, то контроллер sdcard все равно стирает весь блок 4мбайта и заново его записывает?

Нет, не совсем так. У контроллера есть буферы, через которые ведется запись данных в блоки, равные по размеру allocation unit. Т.е. когда вам нужно записать 512 байт контроллер "открывает" очередной блок, например, размером 4 МБ (читает его в буфер), далее записывает в нужное место 512 байт и ждёт что будет дальше. По таймауту или переходу к новому блоку он выбирает куда записать текущий открытый блок (наименее изношенный свободный allocation unit), стирает его, записывает в него данные, обновляет карту трансляции блоков и всё повторяется. Есть исследования, что у некоторых карт есть возможность открывать одновременно несколько блоков, чтобы более эффективно могли работать файловые системы типа FAT, для которых важно одновременно модифицировать области в начале карты и где-то в другом произвольном месте. Но это уже внутренние детали реализации и на это закладываться нельзя. Поэтому самый оптимальный режим работы для карт - это последовательная запись больших блоков данных, кратных по размеру allocation unit.

Share this post


Link to post
Share on other sites

Ошибся, при выходе за пределы блока записываются все остальные не изменённые сектора этого блока. Если выполнять запись секторов в пределах одного блока, даже если в разнобой (но один раз) - блок будет стёрт один раз.

Дорогие и быстрые флешки имеют рам память на несколько сотен блоков, что позволяет им держать открытыми для записи сразу кучу блоков. Дешевые флешки имеют рам память только на один блок (это минимум), и дико тормозят.

Share this post


Link to post
Share on other sites
3 минуты назад, AVI-crak сказал:

Дорогие и быстрые флешки имеют рам память на несколько сотен блоков

Про сотни блоков я такой информации не видел. Какой источник этих данных?

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

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.

Sign in to follow this