Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум разработчиков электроники ELECTRONIX.ru _ IDE/ATA/SATA/SAS/SCSI/CF _ Снова SD/MMC

Автор: InvisibleFed Apr 17 2008, 10:15

Подключаю карту SD к AVR. Вот вроде все, пишет, читает, регистры читает и все такое. Но вот возникли вопросы.

1. Правельно ли утверждение, что я могу писать в блок/сектор сколько угодно раз без стирания?
2. Если да, то нафига стирание (т. е. зачем сама операция)?
3. Как происходит адресация? Т. е. например в блоке/секторе 512 байт. Если я записываю 512 байт по адресу 0x00000001, то следующие 512 байт "начнуться" с адреса 0x00000001 + 0x00000200 (512) = 0x00000201 (513)?
4. Из регистра CSD судя по SDProdManual для карточек SanDisk можно вытащить информацию обо все параметрах-размерах (размер сектора/блока, их число, число байт => вычислить весь объем карточки). Справедливо ли это для карт прочих производителей? Как узнать объем вставленной карточки?
5. Часть секторов/блоков именуются как write protected. Как узнать об их распределении по адресному пространству карточки, где они расположены? Т. е. я, к примеру, пишу блок/сектор, а потом оказывается что туда нельзя писать, т. к. он защищен.

P. S. "блок/сектор" - единица информации, обычно в 512 байт. По непонятным причинам, как я понял, эти совершенно разные понятия конфликтуют в доках на карты SD (блок) и MMC (сектор).

Автор: InvisibleFed Apr 18 2008, 05:12

Неужели никто не может помочь? Наверняка кто-нить разобрался как следует...

Автор: yarunt Apr 18 2008, 05:56

Цитата(InvisibleFed @ Apr 18 2008, 08:12) *
Неужели никто не может помочь? Наверняка кто-нить разобрался как следует...

Ну,практически сами ответили на свои вопросы. На карточке действительно работа посекторная(блочная) и вычисления так и происходят Nсект*512. В бут секторе есть информация про количество секторов в кластере. Размер кластера увеличивается в прогрессии с обьемом карточки.
В пример
32мб 1сектор в кластере,
64мб 2 сектора в ластере
..........................
2гб 64сектора в кластере

Автор: InvisibleFed Apr 18 2008, 12:36

Если Вы давали ответ на 3-й вопрос, то я немного про другое спрашивал... ли не понял ответа. Есть у меня 32 разряда адреса (4 байта из 6-и в команде). Что в тих 32 битах есть что? Т. е. "географически" куда укажет адрес 0x00000001, а куда 0x00000002? Сколько между ними пространства, если иначе. И что такое бут-сектор? Я фат не пользуюсь. Ну и остальные вопросы тоже пока без ответов...

Автор: aaarrr Apr 18 2008, 12:41

Цитата(InvisibleFed @ Apr 17 2008, 14:15) *
1. Правельно ли утверждение, что я могу писать в блок/сектор сколько угодно раз без стирания?

Да.

Цитата(InvisibleFed @ Apr 17 2008, 14:15) *
2. Если да, то нафига стирание (т. е. зачем сама операция)?

Для ускорения записи.

Цитата(InvisibleFed @ Apr 17 2008, 14:15) *
3. Как происходит адресация? Т. е. например в блоке/секторе 512 байт. Если я записываю 512 байт по адресу 0x00000001, то следующие 512 байт "начнуться" с адреса 0x00000001 + 0x00000200 (512) = 0x00000201 (513)?

512 байт по адресу 0x01 никто записать не позволит. Адреса в байтах, но работать можно только блоками по 512 байт.

Цитата(InvisibleFed @ Apr 17 2008, 14:15) *
4. Из регистра CSD судя по SDProdManual для карточек SanDisk можно вытащить информацию обо все параметрах-размерах (размер сектора/блока, их число, число байт => вычислить весь объем карточки). Справедливо ли это для карт прочих производителей? Как узнать объем вставленной карточки?

CSD одинаков для всех.

Автор: galjoen Apr 18 2008, 13:35

Цитата(InvisibleFed @ Apr 17 2008, 14:15) *
5. Часть секторов/блоков именуются как write protected. Как узнать об их распределении по адресному пространству карточки, где они расположены? Т. е. я, к примеру, пишу блок/сектор, а потом оказывается что туда нельзя писать, т. к. он защищен.

Т.е. это сбойные секторы?
Я вот подумываю о том, чтоб SD/MMC карточку в качестве таблицы использовать. Т.е. только для чтения. По рассчётам получается, что мне 4 гБайта таблица нужна. И время доступа ограниченное. Если бы сбойных секторов не было, то SD/MMC хорошо подходила бы. По адресу читаешь блок и всё. А так придётся за 2 раза это делать. Сначала таблицу соответствия физических секторов логическим (аналог FAT), а затем уже сами данные.
Или я тут бред полный написал? Я работал с AT45DB642D, так у неё сбойных блоков в принципе не было.

Автор: aaarrr Apr 18 2008, 13:41

Цитата(galjoen @ Apr 18 2008, 17:35) *
Или я тут бред полный написал? Я работал с AT45DB642D, так у неё сбойных блоков в принципе не было.

Сбойные сектора у SD обрабатываются и маскируются встроенным в карту контроллером.
У AT45 это надо делать руками, Atmel гарантирует только то, что у свежих кристаллов их нет, но это не значит, что они не могут появиться в процессе работы.

Автор: galjoen Apr 18 2008, 14:01

Цитата(aaarrr @ Apr 18 2008, 17:41) *
Сбойные сектора у SD обрабатываются и маскируются встроенным в карту контроллером.

Т.е. можно читать не задумываясь о сбойных блоках. И 4 гБайта это размер уже после отбрасывания сбойных блоков? А что такое write protected блоки? Это действительно защищённые от записи? И защита программно не снимается?
Цитата(aaarrr @ Apr 18 2008, 17:41) *
У AT45 это надо делать руками, Atmel гарантирует только то, что у свежих кристаллов их нет, но это не значит, что они не могут появиться в процессе работы.

Атмел гарантирует, что сбойные блоки не появятся до 100000 перезаписей. Но для этого после 10000 перезаписей в одной странице надо перезаписать те блоки, которые не перезаписывались за эти 10000 раз. Иначе информация в них повреждена м.б. Для этого и команда специальная есть.

Автор: aaarrr Apr 18 2008, 14:11

Цитата(galjoen @ Apr 18 2008, 18:01) *
Т.е. можно читать не задумываясь о сбойных блоках. И 4 гБайта это размер уже после отбрасывания сбойных блоков? А что такое write protected блоки? Это действительно защищённые от записи? И защита программно не снимается?

Ровно 4ГБайта Вам никто не обещает. Реальный объем, конечно, будет заметно меньше.
Write protected блоки устанавливаются и снимаются программно.

Цитата(galjoen @ Apr 18 2008, 18:01) *
Атмел гарантирует, что сбойные блоки не появятся до 100000 перезаписей. Но для этого после 10000 перезаписей в одной странице надо перезаписать те блоки, которые не перезаписывались за эти 10000 раз. Иначе информация в них повреждена м.б. Для этого и команда специальная есть.

Гарантии Atmel'а - дело крайне темное. Когда-то число циклов стирания/записи не упоминалось вообще, потом были цифры 10K, 50K...

Автор: galjoen Apr 18 2008, 14:47

Цитата(aaarrr @ Apr 18 2008, 18:11) *
Ровно 4ГБайта Вам никто не обещает. Реальный объем, конечно, будет заметно меньше.

Понял. Придётся брать 8ГБайт SD.
Цитата(aaarrr @ Apr 18 2008, 18:11) *
Гарантии Atmel'а - дело крайне темное. Когда-то число циклов стирания/записи не упоминалось вообще, потом были цифры 10K, 50K...

В своё время проверил на 2х AT45DB642D. Пол-года непрерывной циклической записи выдержали. Они пишутся медленнее чем Атмел в своих pdf обещает. Не более 80 кБайт (блоков) в секунду (у AD45DB642D блок = 1 кБайт = 1056 байт если точно). За пол-года наверное 120000 записей набралось, но точно более 100000.
Потом уже сделал счётчик кол-ва записей в блок. Если блок сдохнет можно будет максимальный по всей FLASH узнать. Но пока ещё ни одна не сдохла - заказчики молчат.

А вообще 'aaarrr' большое спасибо за ответы. За счёт таблицы в SD - задача, которая раньше сложной казалась, теперь - детский сад.

Автор: InvisibleFed Apr 18 2008, 22:50

Цитата
512 байт по адресу 0x01 никто записать не позволит. Адреса в байтах, но работать можно только блоками по 512 байт.

Возвращаясь к своему примеру: Если я записываю 512 байт по адресу 0x00000000, то следующие 512 байт "начнуться" с адреса 0x00000000 + 0x00000200 (512) = 0x00000200 (512)? Верно? Странно то, что в адрес 0x00000000 я ничего записать не смог, а вот в 0x00000001 с легкостью. Хотя надо проверить код...

Цитата
Write protected блоки устанавливаются и снимаются программно.

Значит, не на все блоки я могу установить защиту от записи (WP_SET)? Потому как число этих блоков ГОРАЗДО меньше общего числа блоков. Или что-то я не догоняю? И тогда как все-таки они распределены по адресному пространству?

Автор: SALOME Apr 21 2008, 08:33

Цитата(InvisibleFed @ Apr 19 2008, 05:50) *
Возвращаясь к своему примеру: Если я записываю 512 байт по адресу 0x00000000, то следующие 512 байт "начнуться" с адреса 0x00000000 + 0x00000200 (512) = 0x00000200 (512)? Верно? Странно то, что в адрес 0x00000000 я ничего записать не смог, а вот в 0x00000001 с легкостью. Хотя надо проверить код...

Адрес следующего бока Вы расчитали верно. Однако, если длина блока 512байт (по умолчанию) то в адрес 0x00000001 запись не идет. Я специально попробовала на своей флэшке. Одрес записи должен начинаться кратно блокам, т.е.0x00000000, 0x00000200, 0x00000400 и т.д. Так ште скорее всего у Вас ошибка в формировании адреса в проге smile.gif.

Автор: InvisibleFed Apr 21 2008, 12:25

Спасибо за помощь. Ошибка действительно была в моей проге.

P. S. SALOME, если это конечно не "сценический образ", a14.gif - очень редко встретишь девушку в нашей области, да еще и...

Цитата
Я специально попробовала на своей флэшке.

Автор: wwweider Apr 22 2008, 04:04

я нашел программку на си для кодевижена которой от меня требуется только номер сектора и массив из 512 данных.
теперь вопрос как мне узнать диапазон секторов для любой вставленной флешки с которыми можно работать?

Автор: jorikdima Apr 22 2008, 06:12

прочитать документацию

Автор: wwweider Apr 22 2008, 08:07

какую?

Автор: InvisibleFed Apr 22 2008, 09:32

Например эту. Обратите снимание на регистр CSD и данные в нем.

 ProdManualSDCardv1.9.pdf ( 1.12 мегабайт ) : 294
 

Автор: SALOME Apr 22 2008, 11:00

Цитата(wwweider @ Apr 22 2008, 11:04) *
я нашел программку на си для кодевижена которой от меня требуется только номер сектора и массив из 512 данных.
теперь вопрос как мне узнать диапазон секторов для любой вставленной флешки с которыми можно работать?

Ну обычно в секторе размещается 512 байт. Поделите объем флэшки (написано на самой карте) на 512 и получите количество секторов.

Автор: zltigo Apr 22 2008, 11:12

Цитата(SALOME @ Apr 22 2008, 13:00) *
Поделите объем флэшки (написано на самой карте) на 512 и получите количество секторов.

Да уж sad.gif. Вся информация выдается самой флешкой, размер сектора можно задать в случае необходимости. Для этого просто следует ознакомиться с системой команд (CMD9 Get CSD). То, что написано на флешке к реальности отношения не имеет, да и читать этикетки прграммно сложно smile.gif.

Автор: SALOME Apr 23 2008, 02:13

Цитата(zltigo @ Apr 22 2008, 18:12) *
Да уж sad.gif. Вся информация выдается самой флешкой, размер сектора можно задать в случае необходимости. Для этого просто следует ознакомиться с системой команд (CMD9 Get CSD). То, что написано на флешке к реальности отношения не имеет, да и читать этикетки прграммно сложно smile.gif.

Вы все правильно говорите. Вся информация находится в самой флэшке. Но судя по всему у аффтора проблемы с доступом в регистр CSD, на который уже не однократно указывалось:
"я нашел программку на си для кодевижена которой от меня требуется только номер сектора и массив из 512 данных". Боюсь, что здесь не тот уровень, на котором можно получить доступ к регистру CSD найти где в нем храниться информация о размере карты и сделать правильный расчет. Хорошо бы в этой "программке си" найти процедуру определения размера карты. Это был бы лучший вариант.
А по поводу несоответствия надписи на флэшке: Вы имеете ввиду тот факт, что 1Кбайт=1024байт? или еще что-то?

Автор: zltigo Apr 23 2008, 05:42

Цитата(SALOME @ Apr 23 2008, 04:13) *
.. по поводу несоответствия надписи на флэшке: Вы имеете ввиду тот факт, что 1Кбайт=1024байт? или еще что-то?

Разумеется нет. Вот, например, гигабайтовая флешка:
Код
mount
Card:SDC[22] Size:995.656MB/512 F:25MHz(14745600) WP:[Off]

stat
FAT32. Number of FATs: 2. Bytes per Cluster: 16384
Root entries  : 512. Sectors per FAT: 243
Total Clusters: 62184. Free: 52927
FAT  start (LBA)         : 250
DIR  start (LBA, Cluster): 736
DATA start (LBA)         : 768


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

Автор: SALOME Apr 23 2008, 05:56

Цитата(zltigo @ Apr 23 2008, 12:42) *
Флешка там конечно внутри стоит гигабайтовая, но часть ее используется под служебные цели и под запас для замены битых блоков. Посему размер спрашивать только у самой флешки.

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

Автор: wwweider Apr 24 2008, 05:27

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

Автор: SALOME Apr 24 2008, 05:41

Цитата(zltigo @ Apr 23 2008, 12:42) *
Флешка там конечно внутри стоит гигабайтовая, но часть ее используется под служебные цели и под запас для замены битых блоков.

И еще такой вопрос. Если флэшка отформатирована под FAT, то по логике вещей при многократной перезаписи должны появляться битые секторы. Windows это как то отслеживает? Или битые секторы выявляются только при форматировании? Или как?

Автор: wwweider Apr 24 2008, 05:49

это всё определяет контроллер на борту самой флешки нам я так поня из мануала нестоит об этом переживать)

почему я немогу файл выложить небольшой текстовый сюда?

Автор: zltigo Apr 24 2008, 05:53

Цитата(SALOME @ Apr 23 2008, 07:56) *
Я правильно понимаю, что с ростом количества битых блоков будет уменьшаться размер памяти, выдаваемый регистром CSD?

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

Автор: SALOME Apr 24 2008, 08:57

Цитата(zltigo @ Apr 24 2008, 12:53) *
Нет. Просто пополнятся из резерва. После исчерпания резерва, битые сектора полезут наружу и будут уже маркироваться, как битые на файловой системе.

Спасибо за информацию.

Автор: galjoen Apr 24 2008, 11:35

Цитата(zltigo @ Apr 24 2008, 09:53) *
Нет. Просто пополнятся из резерва. После исчерпания резерва, битые сектора полезут наружу и будут уже маркироваться, как битые на файловой системе.

Что-то я не понял, что в CSD есть сведения о файловой системе на этой флешке? Это ведь ОС будет если захочет/сможет их маркировать как битые?
В своё время я пробовал при записи в свой самодельный MassStorage возвращать Sense Key=3, ASC=3, ASCQ=0 (WRITE FAULT) - Win зацикливалась на записи. Хотя м.б. это у меня какой-то другой глюк был. Или ОС как-то подругому узнаёт, что сектор битый?

Автор: aaarrr Apr 24 2008, 12:25

Цитата(galjoen @ Apr 24 2008, 15:35) *
Что-то я не понял, что в CSD есть сведения о файловой системе на этой флешке? Это ведь ОС будет если захочет/сможет их маркировать как битые?

Сначала маскировать будет сама карта, система об этом и не узнает.

Автор: galjoen Apr 24 2008, 13:05

Цитата(aaarrr @ Apr 24 2008, 16:25) *
Сначала маскировать будет сама карта, система об этом и не узнает.

Ну это понятно. А когда запас секторов кончится?
Я столкнулся с такой ситуацией: имеется совершенно новая флешка, она есс-но не отформатирована, и при чтении всех секторов в т.ч. 0го у неё есс-но ошибка CRC. Я и выдавал эту ошибку (Sense Key=3, ASC=0x10, ASCQ=0). Тогда Win зацикливалась на чтении 0го сектора, и отформатировать флешку я не мог. Получался замкнутый круг. Пришлось установить специальное условие - при чтении 0го сектора считать, что CRC верна. Мне показалось, что и при записи сектора в Win подобный глюк, т.к. при возврате ошибки Win зацикливается на записи в этот сектор. А такими командами, как Write and Verifu, Win вообще не пользуется. В каком-же случае Win помечает сектор как битый?

Автор: InvisibleFed May 4 2008, 05:22

Идем дальше, как говорится... Имею на руках две флешки: SanDisk TransFlash через переходник 32 мб и Kingston 1гб (SD, естественно). При записи на флешь наблюдаю странную картину. После подачи пары CRC-байт в конце посылки сектора (шлю FF, т. к. CRC не использую), шлю холостые байты в ожидании Data Response (в случае успешной записи должно быть XXX00101). Так вот SanDisk такое выдает, а Kingston - нет. Последняя вообще ничего не выдает вслед за парой CRC - один лишь вечный '0'. Хотя в обоих случаях фактическая запись происходит (потом считывал). В случае с Kingston, правда, не понятно пока с какого раза - там в программе в случае неполучения правильного Data Response производится повторная запись с самого начала команды (и так 4 раза). В чем может быть причина?
И еще вопрос. Для SanDisk после того как карта вернула XXX00101, заряжаю "пустышки" (байты с FF), пока не получу в ответ что-нибудь отличное от нуля (карта висит в Busy, как я понимаю). Так вот это время ну уж очень болшое! Команду и 512 байт информации выпуливаются у меня меньше чем за 500 мкс. А busy висит все 3000 мкс! Это ведь ненормально много?! Или я не прав?

Автор: AndreyS May 15 2008, 20:51

Добрый день.

Не хотел создавать новую тему, так как эта показалась подходящей.

Вопрос в следующем.

При поиске имени файла в области каталогов, когда можно быть уверенным что дальше искать смысла нет. Имеется в виду, следующее. Есть гарантия что при обнаружении пустой записи ( например не все 32 байта обнулены, а только первый символ = 0) за ней не будет какой-нибудь еще валидной записи??? Просто когда флешка пустая (только форматнули), область каталогов занулена. И при поиске файла (на предмет похожего имени) на 8-битнике да 1 гиговой флешке (где секторов под корень отведено много), происходит долгий поиск. Вот думаю останавливать поиск при обнаружении в имени файла первого символа = 0. Правомерно ли это???

Автор: aaarrr May 15 2008, 20:57

Цитата(AndreyS @ May 16 2008, 00:51) *
Вот думаю останавливать поиск при обнаружении в имени файла первого символа = 0. Правомерно ли это???

Правомерно: по стандарту FAT, 0x00 в первом символе имени файла является признаком конца директории.

Автор: AndreyS May 15 2008, 21:07

Цитата(aaarrr @ May 16 2008, 00:57) *
Правомерно: по стандарту FAT, 0x00 в первом символе имени файла является признаком конца директории.


Огромное спасибо за ответ.

Автор: AndreyS Sep 10 2008, 08:10

Добрый день.

Может быть я плохо искал по форуму или по документации на SD карты, но на свой вопрос ответа не нашел. Вернее что-то нашел. В частности у людей есть разброс во времени записи сектора от нескольких ms до сотен ms. В моем случае (мне необходимо при пропадании входного напряжения успеть скинуть свой промежуточный буфер в 512 байт на карту) карта за 20ms не успевает скинуть блок данных. Ток потребления и так на предельном минимуме, остается наращивать входную емкость. Вот и хочу понять какую минимально достаточную поставить (нехочу ставить банку в 1000uF smile.gif.

Сколько времени SD/MMC карты тратят максимально на запись блока в 512 байт???
Сколько минимально возможно времени тратят на запись???

В документации напоролся на фразу из которой я понял что на запись карта может потратить до 250mS времени. Ужасно много. Может есть более конкретные данные (то что я прочел оказалось где-то в середине документа, а не в таблице электрических и временных характеристик)?????

Автор: sergeeff Sep 10 2008, 10:19

С посекторной записью в SD вопрос неприятный. Мне попадались карты, куда писались данные посекторно со скоростью 7 кбайт/с, хотя другие писали 80 кбайт/с.

Автор: AndreyS Sep 10 2008, 10:54

Цитата(sergeeff @ Sep 10 2008, 14:19) *
С посекторной записью в SD вопрос неприятный. Мне попадались карты, куда писались данные посекторно со скоростью 7 кбайт/с, хотя другие писали 80 кбайт/с.


Да, но это все же больше чем 2 ms на запись куска в 512 байт. Я столкнулся с тем, что за 2 ms карточка данные на флешь не сбросила, хотя и "всосала" их в себя.

Время работы всего процесса 4 ms. За 2 ms я все выплевываю в SD, и по осцилограмме вижу еще 2.4 ms до момента пропадания питания есть у карты. Но после прочтения данных, своего куска информации в файле не обнаруживаю. Затянул процесс до сотен ms. Данные в файле получил. Но банка болшая получилась.

Автор: М430 Sep 15 2008, 14:15

Доброго дня.

Имею аналогичную проблему с MicroSD картой.

Начинаю писать на нее поток данных со скоростью примерно один сектор в 110 мс. Пишет корректно, однако один раз в 28 секунд (это я замерял, какое-то магическое числ небось) карточка держит сигнал BUSY слишком долго (до 80 мс), хотя в остальное время BUSY пропадает практически сразу после записи.
Вот уже несколько дней думаю о причинах такого поведения, но как-то ничего не придумывается. Может кто знает?

Автор: aaarrr Sep 15 2008, 20:23

28/0.11 = 254.
Ну очень похоже на 256 - размер какого-нибудь блока флеш.

Автор: М430 Sep 16 2008, 06:13

Цитата(aaarrr @ Sep 15 2008, 23:23) *
28/0.11 = 254.
Ну очень похоже на 256 - размер какого-нибудь блока флеш.

Ну в таком случае это какой-то блок из 256 секторов - но я нигде не видел упоминание об этом.
И еще - я пишу непрерывно, начиная с 66 сектора в файле на карте, а этот 66 сектор файла смещен относительно начала карточки на 95 секторов. Получаем начало в 161 секторе от начала карточки.
Отладчикм посмотрел, что длительное ожидание происходит на 373 секторе файла, т.е. на 534 секторе от начала карточки. Но ведь это явно не блок, и явно не кратно 256.
Короче, полная загадка.

Автор: М430 Sep 16 2008, 08:11

И еще интересный момент.
В вышеописанных условиях первый сбой происходит на 373 секторе, а вот следующий сбой - на 629, т.е. с интервалом 256 секторов!!!
Из любопытства уменьшил интервал записи секторов с 110 мс до 96. Получил первый сбой на 253 секторе (как-то не пропорционально с интервалом получилось), а вот следующий - на 509 - снова через 256 секторов!!!

Что за магическое число 256 секторов для SD карты и почему так происходит вообще?

Автор: jorikdima Sep 16 2008, 09:25

У меня тоже проблемы с недетерменированностью времени записи 05.gif 05.gif Пока так и не решил проблемму.

Автор: aaarrr Sep 18 2008, 08:05

Цитата(М430 @ Sep 16 2008, 12:11) *
Что за магическое число 256 секторов для SD карты и почему так происходит вообще?

На этой границе карта может выполнять стирание следующего блока, контроль целостности данных в только что записанном и т.п.
256 - магическое число только для данной конкретной карты. Контроллер SD-карты весьма сложная штука, ждать от него детерменированного времени записи нельзя, нужно буферизировать данные со своей стороны.

Автор: jorikdima Sep 18 2008, 09:31

Цитата(aaarrr @ Sep 18 2008, 12:05) *
На этой границе карта может выполнять стирание следующего блока, контроль целостности данных в только что записанном и т.п.
256 - магическое число только для данной конкретной карты. Контроллер SD-карты весьма сложная штука, ждать от него детерменированного времени записи нельзя, нужно буферизировать данные со своей стороны.

Я это безусловно и так делаю... вот только я никак не могу определить размер при котором все гарантироваано успеется записаться. Ну не мегабайт же мне выделять, при том, что я пишу пачками по 150 байт за раз и в 99% случаев он записать эти 150 байт успевает еще до того как новые 150 байт накопятся с АЦП. Весь вопрос в этом 1 % случаев... мегабайта конечно хватит, но я не готов в крохотном МСП430 выделять 1М памяти чтоб он простаивал попросту. smile.gif

Автор: LCD Oct 2 2008, 20:14

Здравствуйте.
Делаю поддержку флешек microSD на MSP430. Сначала использовал легкодоступный Sham176.zip. Все работало практически без глюков, но флешки более 512 МБ эта библиотека не видела, поэтому я решил портировать FatFs (не tiny). Взял diskio http://electronix.ru/redirect.php?http://dev.ivanov.eu/projects/msp430-4619lcd_sample/index.html, переделал, чтобы он работал на F1611 и получил кучу глюков, убив кучу времени. Один из них - карточка инициализируется строго через раз, или каждый раз, если ее вынуть-вставить. А сначала вообще инициализировалась когда хотела, обычно на 10 неудачных попыток была одна удачная. После чего она стала работать через раз - уже не помню. Конечно, можно всю инициализацию засунуть в цикл, но мне кажется, что это - "костыли".
Есть две флешки: PQI на 512 МБ и Kingston на 1 ГБ. Инициализируются обе в разных "ветках" (см. ниже). Компьютер и другие девайсы работают с ними без всяких проблем.
Спецификации читал, вроде у меня все правильно.
С чтением тоже проблемы: вместо сектора всегда получаю одни нули.

 diskio.zip ( 2.06 килобайт ) : 157
 

Автор: AndreyS Oct 3 2008, 06:23

Цитата(LCD @ Oct 3 2008, 00:14) *
Здравствуйте.
Делаю поддержку флешек microSD на MSP430.

--- кусь ---



Добрый день.

А вопрос то в чем???
Вы хотите чтобы в исходнике нашли ошибку???
Или дали бы вам свои исходники???

Автор: LCD Oct 3 2008, 07:41

Да, чтобы помогли найти ошибку или дали исходники, которые точно работают, не обязательно свои.

Все-таки помог "костыль" в процедуре инициализации: я поставил в цикл дергание CS и сброс (CMD0). Но проблема с отсутствием данных при чтении осталась.

Автор: LCD Oct 3 2008, 21:34

Все, разобрался, вопрос больше не актуален smile.gif

Автор: Cyber_RAT Oct 4 2008, 17:37

Рассказали бы другим... а то я вот собираюсь прикручивать MMC 1-2Gb - стоит ли идти по тем же граблям...

Автор: LCD Oct 7 2008, 17:27

Я выложу diskio, когда доделаю его до конца, мне не жалко. smile.gif

Автор: ISD Oct 24 2008, 11:08

Проблема с microSD Kingston 1Гб. Делаю чтение блоками в 32 байта в цикле. Карта на определенном адресе очень долго не выдает Data Token (пока до 1мс задержку докрутил) . Посмотрел по докам сандиск на SD карты - а там максимум в 100мс обозначен!!!!! Это как понимать?

Автор: aaarrr Oct 24 2008, 11:11

Так и понимать. Постоянную скорость Вам никто не обещает.

Автор: ISD Oct 24 2008, 13:46

исходя из этого параметра можно считать, что чтение блока в 512 байт по SPI в худшем случае займет 100мс + 512*8*Fclk+команда.? Чет медлено очень 07.gif

Автор: aaarrr Oct 24 2008, 13:53

Цитата(ISD @ Oct 24 2008, 17:46) *
Чет медлено очень 07.gif

Ну, не на каждом же чтении возникает такое безобразие. Буферизируйте данные, если нужна стабильная скорость.

Автор: ISD Oct 24 2008, 14:07

Если работать на 2 МГц CLK, надо буфер более 25КБ держать. Причем непонятна частота возникновения этой задержки. Как же тогда народ на АВР плееры делает? Или это только SD-карт касается? В MMC вроде меньше задержка....

Автор: LCD Oct 25 2008, 13:37

Цитата(ISD @ Oct 24 2008, 18:07) *
Если работать на 2 МГц CLK, надо буфер более 25КБ держать.

Зачем так много?

Автор: ISD Oct 27 2008, 07:19

Потому, что при 2Мгц CLK за 100мс должно прочитаться 25000 байт (это теоретически, практически -минус команда 7 байт, минус DataToken и CRC * кол-во блоков) (конечно, если надо поток постоянным держать). Непонятно, как в MP3 плеере, сначала буферизируют столько?
Еще одна особенность всплыла - карте иногда не нравятся адреса, не выровненные к размеру блока чтения. Иногда- тоже понятие одной "магической цифры", остальные невыровненные кушает без проблем.

Автор: Angelo Jul 23 2009, 17:00

На второй странице этой ветки SALOME задаёт вопрос:
Я правильно понимаю, что с ростом количества битых блоков будет уменьшаться размер памяти, выдаваемый регистром CSD?
Zltigo отвечает:
Нет. Просто пополнятся из резерва. После исчерпания резерва, битые сектора полезут наружу и будут уже маркироваться, как битые на файловой системе.

Мой вопрос.
Карта используется как большой массив памяти, данные линейно пишутся подряд, так же линейно читаются, и после прочтения все удаляются. Т.е. файловой системы нет. Как в таком случае будут выглядеть битые сектора? Т.е. предположу, что при попытке записать в битый сектор карта вернёт ошибку. Но какую именно? Как понять (по ошибке) что это именно битый сектор, и его нужно просто пропустить? Что ответит карта при прочтении битого сектора? Опять же как это понять, чтоб данные из этого сектора пропустить?

Автор: aaarrr Jul 23 2009, 18:07

Маловероятно, что при такой работе вообще вылезут битые сектора. На битом секторе карта вернет Write Error в Data Response токене при записи и Card ECC Failed в Data Error токене при чтении.

Автор: forever_student Apr 11 2010, 15:25

Всем доброго дня!
Столкнулся с таким непонятным явлением:
Инициализация SDHC карты для работы по SPI
CMD 0 - ответ 0х01
CMD 8 - ответ 0х01

ACMD 41 :
CMD 55 - ответ 0х01
/* хитрое место */
CMD 41 - ответ 0х00

Непонятно вот что :
4 карты (2шт. Transcend 8 Gb и 2 шт.Kingston 4 Gb) работают
если в хитром месте подать больше 7 клоков при неактивном CS
1 карта (Kingston 8 Gb) работает если в хитром месте подать более 255 клоков при неактивном CS
1 карта (Kingston 8 Gb) работает если в хитром месте подать более 511 клоков при неактивном CS
Наверное, можно нарваться на карту, где еще более широкое "хитрое место".
В Physical Layer Simplified Specification Version 2.00 ничего на этот счет не нашел.
Сколько клоков закладывать в хитрое место?
P.S. Инициализация идет при частоте клока ~250 кГц, карты новые.

Автор: zltigo Apr 11 2010, 15:44

Цитата(forever_student @ Apr 11 2010, 17:40) *
Сколько клоков закладывать в хитрое место?

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

Автор: forever_student Apr 11 2010, 18:21

Цитата(zltigo @ Apr 11 2010, 19:59) *
А почему это Вас сильно волнует? При наличии контроля responce после каждого байта этот "таймаут" может заложен весьма большим.

Насколько большим?
Если он будет мЕньшим, чем нужен для конкретной карты, то после ACMD 41 я получу responce 0хFF, и буду повторять ACMD 41 до бесконечности (пробовал 255 раз, результата никакого). Поэтому хочется или знать какое-то значение, при котором любая SDHC карта, поддерживающая SPI, ответит 0х00, или понять, где я чего-то неправильно сделал

Автор: zltigo Apr 11 2010, 18:54

Цитата(forever_student @ Apr 11 2010, 20:36) *
Если он будет мЕньшим, чем нужен для...

Не понимаю, что Вы там написали, но вообще бесконтрольные магические клоки на карту выдавать просто не надо. То, что перед командой, это ожидание готовности. Ожидание готовности ТОЖЕ должно быть подконтрольным и после CMD55 перед ACMD41 сначала надо дождаться готовности. Лично у меня это отсчитывает операционка, посему не с тактах sad.gif, а в ms - 750ms почему? За давностью лет не помню sad.gif все было написано лет пять назад.

Автор: forever_student Apr 11 2010, 19:14

Цитата(zltigo @ Apr 11 2010, 23:09) *
... бесконтрольные магические клоки на карту выдавать просто не надо...

Sorry, неправильно выразился. Это просто байты 0хFF(т.е. 8 клоков=1 байт), передаваемые при неактивном CS (как те, что до CMD 0).
Т.е. после CMD 55 достаточно дать паузу ~800 мС, затем CMD 41?

Автор: zltigo Apr 11 2010, 19:22

Цитата(forever_student @ Apr 11 2010, 21:29) *
неправильно выразился. Это просто байты 0хFF(

Я о том-же. Вот и КОНТРОЛИРУЙТЕ ответ-готовность при передаче этих 0xFF.
Цитата
Т.е. после CMD 55 достаточно дать паузу ~800 мС, затем CMD 41?

Разумеется нет. Пауза тут вообще ни сном ни духом CD надо тактировать. Считать при этом время или байт-такты, это уже конкретная реализация.

Автор: forever_student Apr 11 2010, 19:54

Цитата
Вот и КОНТРОЛИРУЙТЕ ответ-готовность при передаче этих 0xFF.

Чего-то я, видимо, не понимаю. Как я могу контролировать? Responce на CMD55 я уже получил. CMD 41 еще не передавал. Только что специально все ответы на посланные 64 байта (т.е. 512 клоков) сложил в RAM, после Responce на CMD 41 посмотрел - все 0хFF. Да и как карта может отвечать, если CS неактивен?

Автор: zltigo Apr 11 2010, 20:14

Цитата
все 0хFF.

Это правильная реакция карты готовой к приему команды ее и надо ждать, а вот CS должен быть активен во время всей "большой" команды ACMD.

Автор: forever_student Apr 11 2010, 20:39

Передаю CMD55, жду responce 0x01, CS оставляю активным, отправляю байты 0хFF до тех пор, пока не получу ответ 0хFF, отправляю CMD 41, жду responce 0x00, если таймаут, повторяю все сначала.
Если делаю так, то всю большую ACMD 41 повторяю от 5 до 8 раз.
Если так,как раньше (т.е. отправляю 64 байта 0хFF) то повторяю 4 раза.
Самые "медленно отвечающие" карты смогу проверить завтра.

Автор: zltigo Apr 11 2010, 21:36

Цитата(forever_student @ Apr 11 2010, 22:54) *
Передаю CMD55, жду responce 0x01, CS оставляю активным, отправляю байты 0хFF до тех пор, пока не получу ответ 0хFF, отправляю CMD 41, жду responce 0x00, если таймаут, повторяю все сначала.

Да. Теперь правильно. У меня, правда, один 0xFF сначала передается бесконтрольно. Почему уже не помню что там читал 4-5 лет назад, возможно просто как минимально необходимый.
Цитата
Если делаю так, то всю большую ACMD 41 повторяю от 5 до 8 раз.

А вот проходить все должно БЕЗ таймаута с первого раза. Начните внимательно разбираться по первоисточнику с самого начала инициализации. Или с железом проблемы. Успехов!
А, на счет с первого раза - у меня есть и повтор. Зачем? Опять не помню sad.gif. В ветка, первой версии SD, или MMC повтора нет, а для продвинутой есть.
Пора по первоисточникам освежать память....
Код
                // The card can work at vdd range of 2.7-3.6V
                do
                {   // ACMD41 with HCS bit
                    if( send_cmd_app( ACMD41_OPERATE, BIT30 ) == R1_OK )
                    {
                        if( send_cmd( CMD58_OCR, 0 ) == R1_OK )
                        {    // Check CCS bit
                            mmc_receiveblock( sd_buf, 4 );
                            if( sd_buf[0] & 0x40 )
                                Mds.ctype = (CARD_SD|CARD_V2X|CARD_BLOCK);
                             else
                                 Mds.ctype = (CARD_SD|CARD_V2X);
                        }
                    }
                }
                while( xIsTimeout( timer ) == FALSE );

Автор: forever_student Apr 12 2010, 05:31

Цитата(zltigo @ Apr 12 2010, 01:51) *
А вот проходить все должно БЕЗ таймаута с первого раза.

Всем доброго дня.
Проверил "медленноотвечающие" карты.
Обе 8 Gb карты не работают sad.gif После >100 повторений большой ACMD 41 - таймаут.(~1 сек.)
В железе, я думаю, проблем нет - при тупой передаче 64 байт все работает
То же самое по инициализации( если по предыдущим командам получены правильные responce, значит все в норме?)
Буду разбираться...

Автор: stepper88 Sep 12 2012, 07:27

Дабы не плодить темы, пишу сюда.
Есть в наличии плата на LPC2378. Карта памяти подключена к модулю MCI по схеме, которую прилагаю к посту.
Модуль MCI инициализирую следующим образом:

Код
void MCI_init (void)
{
    unsigned char i=0;

    //процедура инициализации карты памяти
    PCONP |=(1<<28);                    //Включаем тактирование модуля MCI
    //На время инициализации запрещаем все прерывания
    MCI_MASK0=0;
    MCI_MASK1=MCI_MASK0;
    //PINSEL1=0x2280;                        //Активируем выводы контроллера карт памяти
    PINSEL1=0x00002A80;
    PINSEL4=0x0A800000;
    //Задаем режим тактирования по-умолчанию, сбрасываем требуемые регистры
    MCI_COMMAND=0;
    MCI_DATA_CTRL=0;
    MCI_CLEAR=0x7FF;                    //Сбрасываем все отложенные прерывания
    MCI_POWER=0x02;                        //Подаем напряжение на карту
    while (!(MCI_POWER & 0x02));  
    for (i=0;i<100;i++);
    //Во время идентификации тактовая частота не должна превышать 400 кГц.
    //После прохождения этой фазы частота тактового сигнала может быть установлена
    //25 МГц для SD и 20 МГц для MMC
    SetMCIClock(SLOW_RATE);
    MCI_POWER |=0x01;
}

Далее следует инициализация карты памяти
Код
unsigned char init_card (void)
{
    unsigned int i=0;

    if (!(MCI_Go_Idle_State()))                        //Переход в неактивное состояние
        return    0;                                        //Карта неизвестна
    else
    {
        if (MCI_Check_Ver())                                        //Проверка версии по команде CMD8
        {
            send_string2("SD v2\r\n");
            if (MCI_Send_ACMD_OP_Cond(OCR_INDEX_V2))
                return 2;
            else
                return 0;
        }
        else
        {
            if (!(MCI_Go_Idle_State()))
                return 0;
            else
            {
                send_string2("SD v1\r\n");
                MCI_Go_Idle_State();
                MCI_POWER |= (1 << 6 );        // Set Open Drain output control for MMC
                for ( i=0; i<0x3000; i++ );

                                //Посылаем команду CMD1 - если карта MCC - она инициализируется
                if ( MCI_Send_OP_Cond())
                    return 1;
                else
                                //В противном случае посылаем команду ACMD41 с параметром OCR_INDEX
                    if (MCI_Send_ACMD_OP_Cond(OCR_INDEX))
                        return 2;
                    else
                        return 0;
            }
        }
    }
}

Команда ACMD41 реализуется, как CMD55+ACMD41
Функция отправки CMD55
Код
unsigned char MCI_Send_ACMD( void )
{
    unsigned int i=0, t=0;
    unsigned long Argument=0;
    unsigned long Status=0;
    unsigned long Data[4];
    char buf[8];

    if (CardType==2)
    {
        Argument = CardRCA;                            
//Используется адрес из команду установки относительного адреса        
    }
    else                                                
    {
        Argument = 0x00000000;                        //Для ММС используется аргумент 0
    }
    for (t=0; t<0x200; t++)
    {
         MCI_SendCmd(CMD55, Argument, SHORT_RESP, 0 );
        Status=MCI_GetCmdResp(CMD55, SHORT_RESP, (unsigned long*)&Data[0]);
        if ((!(Status)) && (Data[0] & CARD_STATUS_ACMD_ENABLE))
        {
            send_string2("CMD55 good\r\n");
            return 1;
        }
        for (i=0; i<0x50; i++);    
    }
    memcpy(buf,&Status,4);
    send_mas2(buf,4);
    send_string2("CMD55 error\r\n");
    return 0;
}

Функция отправки ACMD41. В процессе своей работы вызывает предыдущую функцию
Код
unsigned char MCI_Send_ACMD_OP_Cond (unsigned long Argument)
{
    unsigned int t=0;                                //Счетчик попыток
    unsigned int i=0;                                //Счетчик задержек
    unsigned long Status=0;                            //Статус
    unsigned long Data[4];                            //Данные, возвращаемые при запросе
    //Если процедура Send_Op_Cond вылетела по таймауту (вставлена не карта ММС),
    //пробуем Send_ACMD_OP_Cond
    MCI_POWER &= ~(1 << 6 );    /* Clear Open Drain output control for SD */
    for ( i = 0; i < 0x3000; i++ );
    for (t=0; t<0x200; t++)
    {
        if (!(MCI_Send_ACMD()))
        {
            continue;
        }
        else
        {
            MCI_SendCmd( ACMD41, Argument, SHORT_RESP, 0 );
            Status=MCI_GetCmdResp(ACMD41, SHORT_RESP, (unsigned long *)&Data[0]);
            //Нулевой и второй бит должны быть в нуле иначе ошибка CRC или таймаут
            if (!(Status&MCI_CMD_TIMEOUT) && (Data[0] & 0x80000000))
            {
                return 1;
            }
            for ( i=0; i<0x20; i++);                     //Таймаут для следующей попытки
        }
    }
    return 0;
}

Карта Tranced 2Гб нормально опознается, как карта SD V2 и проходит инициализацию нормально. Карты же Tranced 256 Мб и Tranced 1 Гб опознаются, как SD V1, но при отправке CMD55 после первой попытки в регистре статуса устанавливаются флаги Command response timeout и Command sent (no response required) - биты 3 и 8 соответственно, при последующих попытках только флаг Command response timeout. Если строки в функции MCI_Send_ACMD()
Код
         MCI_SendCmd(CMD55, Argument, SHORT_RESP, 0 );
        Status=MCI_GetCmdResp(CMD55, SHORT_RESP, (unsigned long*)&Data[0]);

заменяю на

Код
         MCI_SendCmd(CMD55, Argument, NO_RESP, 0 );
        Status=MCI_GetCmdResp(CMD55, NO_RESP, (unsigned long*)&Data[0]);

в регистре статуса не устанавливается ни одного флага, но и в переменной Data тоже нули. Подскажите пожалуйста, как правильно в таком случае поступить? Можно будет при втором варианте отправки CMD55 просто проверить регистр статуса (что ни один из флагов не выставлен) и сразу переходить к отправке самой ACMD41? Или обязательно нужно получить ответ?
P.S. Использую среду Keil, функции отправки комманд, а также чтения ответа на команду и статуса взял из примера к LPC23xx для проверки модуля MCI.

 

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)