|
Время записи в SD-card, Почему разное время записи |
|
|
|
Apr 28 2011, 19:09
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Всем привет. Столкнулся с такой проблемой: время записи данных в SD-card разное. Опишу все по порядку:
ядро: AT91SAM3U4E SD-card: SanDisk 2GB
Данные пишет ARM3 в SD-card, используя библиотеку от Чена. Размер буфера для записи 16кБ. Перед функцией записи ножку ARMа устанавливаю в "1" после сбразываю в "0", тем самым определяю время записи. Запуск записи ручной в железе от кнопки (не в дебагере). С 1 по 31 итерацию время записи 3 мС, 32 итерация длится 40 мС, далее цикл повторяется. Вот такая засада.
Кто сталкивался или знает, что происходит во время 32 итерации записи? Первое, что приходит в голову - это размер буфера в SD-card, примечательно, что 16*32=512, и вполне возможно буфер в SD-card равен 512 кБ. Когда он заполняется, то контроллер, который стоит в SD-card, переписывает его в память. Конечно, сильно притянуто за уши, тем более, что запись во флеш идет постраничная, а размер станиц равный 512кБ я нигде не встречал.
|
|
|
|
|
 |
Ответов
|
Apr 29 2011, 06:02
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Цитата Проблемой такое поведение не является, и средняя скорость у вас получилась вполне на уровне. Да как сказать! Мне приходиться писать каждые 100mC 32кБ, с учетом того, есть еще подготовительные операции, то на запись в SD-card отводится 25mC(max), поэтому для меня это проблема. Цитата задержки при записи могут быть достаточно случайными. Целый вечер вчера тестил, задержка появлялась только после 512кБ, в моем случае на 32 итерации. У меня достаточно старая SD, 2 года ей где-то, может быть современные ведут себя по другому? И второй вопрос: Программно, существует способ перераспределить время записи?
|
|
|
|
|
Apr 29 2011, 13:33
|

embarrassed systems engineer
    
Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038

|
Цитата(*rust* @ Apr 29 2011, 09:02)  Да как сказать! Мне приходиться писать каждые 100mC 32кБ, с учетом того, есть еще подготовительные операции, то на запись в SD-card отводится 25mC(max), поэтому для меня это проблема. Я недавно занимался тестированием SD-карт, в том числе измерял время записи сектора при массированной последовательной записи блоков различной длины. Поделюсь результатами и своей теорией. Тест 1 - пишем последовательно в сектор записи по 16 байт, сектор закончился - берем следующий, с номером на единичку большим. Результат - типовое время записи порядка 1 мс (несколько зависит от типа карты и класса), но каждые примерно N записей - провал с некоторым типовым значением. Это значение составляет от 30 мс у самой быстрой новейшей SD 3.0 карты (30Мбайт/сек) до 300 мс у нестарой и заявленной как класс 4 SDHC. Карты 4-5 летней давности уложились в пределы 60-150мс. Тест 2 - карта предварительно стерта командой SET_LOCK_UNLOCK. Пишем последовательно по целому сектору - типовое время записи сектора осталось то же самое, периодические 'выбросы' тоже есть, но они сократились очень значительно - ну раза в полтора-два больше чем типовое время записи. То есть карта в худшем случае 'думает' всего 2..5мс. Eще был ряд тестов с привлечением команд стирания, я уже деталей полностью не помню. Выводы у меня такие - карта, ее внутренний контроллер и его прошивка это черный ящик, но - 99% что основной массив флеш памяти "исповедует" принципы NAND - можно писать страницами (под размер сектора) и стирать только блоками (группами страниц). Отсюда следует основа алгоритма записи - заводится внутри некоторый пул свободных стертых страниц (размер пула равен периоду 'выбросов' времени записи), когда он заканчивается - информация переносится в основное хранилище - или ремаппингом (изменением индексов в базе) или тупо перезаписыванием. Также есть сильное подозрение что если есть возможность записывать сектор сразу на постоянное место (пишущийся сектор в основном массиве "стерт") то пишется на постоянное место. Итого - если нужный набор секторов стереть (командами стирания) и писать каждый сектор не более одного раза - то такие 'спорадические' увеличения времени записи можно в большинстве случаев купировать. Эксперимент это подтверждает, проверено около 10 карт SD/SDHC разного возраста, объема и производителей. Выявился еще интересный результат тестов - если в момент 'долгой записи' с карты снять питание (или просто стабилизатор не вытянет броска тока - жрать в этот момент карта начинает ой-ей) или подать команду сброса (так что тайм-ауты корректно все обрабатываем - это карта 'задумалась', а не умерла  ), то на некоторых картах приходит пушной зверь - могут разрушиться данные, которые вообще не имели отношения к записываемому сектору - я думаю, что разрушается внутренняя индексная база.
|
|
|
|
|
May 17 2011, 08:16
|
Группа: Новичок
Сообщений: 5
Регистрация: 25-08-09
Пользователь №: 52 030

|
[quote name='VslavX' date='Apr 29 2011, 20:03' post='922688'] Доброого времени суток. У меня та же проблема с SD картами. Среднюю скорость записи на карту без проблем достигаю 4-6 Мбайт/с. Пишу по кусками по 32 кБайт при помощи CMD25. И мне ужасно мешают жить эти большие задержки по 30-150 мс !!! На проце уже нет свободной ОЗУ, чтобы буфферизировать данные в течение этого времени. Максимум могу делать буфферизацию в течение 25 мс. Использование команды Pre-erase существенного выигрыша не дает. При предварительном стирании больших кусков памяти при помощи команды CMD38 также не увидел пропадания этих больших задержак при WRITE_MULTIPLY_BLOCK. Поэтому крайне интересно то, что написал "VslavX" Цитирую: "Тест 2 - карта предварительно стерта командой SET_LOCK_UNLOCK. Пишем последовательно по целому сектору - типовое время записи сектора осталось то же самое, периодические 'выбросы' тоже есть, но они сократились очень значительно - ну раза в полтора-два больше чем типовое время записи. То есть карта в худшем случае 'думает' всего 2..5мс. " Так вот у меня возник вопрос к "VslavX" !!! Что это за команда такая предварительного стирания SET_LOCK_UNLOCK, которой Вы пользовались и которая Вам так облегчила жизнь ????? Можете написать ее номер ??? Вроде как в спецификации на карту оговорены только команды для стирания CMD38 (ERASE) и ACMD23(Pre-erase). Спасибо
|
|
|
|
|
May 17 2011, 10:01
|
Группа: Новичок
Сообщений: 5
Регистрация: 25-08-09
Пользователь №: 52 030

|
Цитата(VslavX @ May 17 2011, 15:33)  CMD42, с установленным флажком ERASE. По идее - команда обычного стирания (CMD38) тоже должна помочь, но ее я не пробовал. Возможно у Вас в один и тот же сектор пишется несколько раз после стирания (если там файловая система типа FAT, то такое вполне может быть) - поэтому задержки не устранились. Спасибо за ответ, но: 1. Команда CMD42, если я все правильно понимаю, предназначена для блокирования/разблокирования карты. Установка в этой команде флажка ERASE приведет к тому, что в дальнейшем картой будут блокироваться запросы на стирание. 2. На данном этапе я просто тестирую карты и еще не использую файловую систему. Результатом тестирования является гисторграмма распределения длительности записи. Запись в моем тесте идет последовательно и адреса наращиваются тоже последовательно. Так вот, тест показал, что при записи 80000 кусков данных (каждый кусок - это 64 блока по 512 байт) или что тоже самое 2.5 Гбайт на SDHC время записи у, примерно, 5-15 кусков превышает 50 мс. в то время как у оставшихся 7995-7985 кусков оно не превышает и 6 мс!!! 3. Использование команды CMD38 не помогло устранить этой проблемы. 'VslavX' возможно ли как то хотя бы взглянуть на Ваши условия тестирования и полученные результаты ??? Еще что интересно, так это то, что и на зарубежных сайтах не дают четкого ответа откуда возникают это большое "busy time" при мультиблоковой записи и как с ним бороться!!! Тогда как работают, например, видеокамер, которые используют SD карты ??? неужели у них такой большой внутренний буфер (ОЗУ), что его хватает аж на 250 мс видеопотока (250 мс вроде как заявлено в спецификации). Еще раз спасибо 'VslavX' за ответ
|
|
|
|
|
May 17 2011, 10:40
|

embarrassed systems engineer
    
Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038

|
Цитата(shishka @ May 17 2011, 13:01)  1. Команда CMD42, если я все правильно понимаю, предназначена для блокирования/разблокирования карты. Да, для блокирования-разблокирования. Но, допустим, у Вас есть карта с установленным паролем, и Вы его забыли. Что делать? Выкидывать всю карту? Ж-а-а-а-лко  Вот поэтому и есть опция ERASE - снимается пароль, а перед этим стираются все данные которые были этим паролем защищены, так сказать карта приводится "к печке" - в некоторое начальное состояние. Кстати, я использовал в тестах стирание через команду CMD42 не потому что "что-то знал", а просто у меня был готовый код и лень было писать процедуры с использованием CMD38. Цитата(shishka @ May 17 2011, 13:01)  Установка в этой команде флажка ERASE приведет к тому, что в дальнейшем картой будут блокироваться запросы на стирание. Хм, а почему Вы так думаете? Я что-то пропустил/недопонял в стандарте? Цитата(shishka @ May 17 2011, 13:01)  возможно ли как то хотя бы взглянуть на Ваши условия тестирования и полученные результаты ???  Взглянуть можно на функцию теста - она очень простая. Варьируя число в цикле j<128 я пробовал разное количество записей в один и тот же сектор, и выводил к консоль время выполнения операций которые длились более 10мс. Снаружи еще была функция стирания по CMD42 - все эти тестовые функции можно было запускать по клавишам в консоли в произвольном порядке. Точных результатов, к сожалению, не помню, и этот-то кусочек кода случайно сохранился. Сначала я выводил информацию о времени всех операций в файл - получил представление о среднем времени записи и о спорадических задержках. Потом выполнил CMD42 и увидел что ситуация намного улучшилась если одна запись в один сектор. Ну а потом уже поставил лимит time<10000 - и игрался наблюдая только задержки. CODE static void io_test_mmc_wsecbytes(void) { IO_STATUS io_status; DWORD size, i, j, time, n;
n = 0; size = io_mmc_size(); if (size != 0) { for(i=0; i<size; i++) { tst_printf("\r\nSector: %08X\f", i);
hal_memset(mmc_udma, 0xFF, sizeof(mmc_udma)); for(j=0; j<128; j++) { DWORD old;
mmc_udma[j] = i + j;
tn_task_raise_priority(TN_UPPER_APP_PRIORITY, &old); time = hal_profiler_counter(); io_status = io_mmc_write(i, 1, mmc_udma); time = hal_profiler_elapsed_us(time); tn_task_lower_priority(old);
if (io_status != IOERR_SUCCESS) { tst_printf("\r\nWrite %08X sector error: %d", i, io_status); return; } if (time > 10000) { tst_printf("\r\n %06d: %d\f", n, time); } n++; tn_task_sleep(MS_TO_TICKS(10)); if (hal_inkey() != 0) { return; } io_status = io_mmc_read(i, 1, mmc_ndma); if (io_status != IOERR_SUCCESS) { tst_printf("\r\nRead %08X sector error : %d", io_status); return; } if (hal_memcmp(mmc_ndma, mmc_ndma, IO_MMC_BLOCK_SIZE)) { tst_printf("\r\nRead data back are wrong"); return; } } } } }
Upd: я тут еще заметил что у меня пауза между операциями в 10 мс стоит, надо бы повторить тест без нее - а то не совсем чисто получается. Upd2: только что попробовал старую SD-micro карту на 512Мбайт - так она и по 128 записей на сектор и без предварительного стирания всегда в 10 мс укладывается. Я примерно час буду занят - потом попробую более тостые карты и без задержки 10 мс - отпишусь.
|
|
|
|
Сообщений в этой теме
*rust* Время записи в SD-card Apr 28 2011, 19:09 aaarrr Цитата(*rust* @ Apr 28 2011, 23:09) Кто с... Apr 28 2011, 20:55 _3m Цитата(*rust* @ Apr 29 2011, 10:02) Да ка... Apr 29 2011, 07:20     aaarrr Цитата(shishka @ May 17 2011, 14:01) Еще ... May 17 2011, 10:44      shishka Спасибо за ответы.
Для VslavX: По поводу команды ... May 17 2011, 11:53       VslavX В-общем, проделал я такие тесты:
CODE
Карта Transc... May 17 2011, 14:33        shishka Ну вот - теперь у Вас почти совсем как и у меня May 20 2011, 07:48 *rust* ЦитатаБуферизируйте.
Это как???
Сейчас полазил п... Apr 29 2011, 07:47 AlexandrY Цитата(*rust* @ Apr 29 2011, 10:40) Это к... Apr 29 2011, 07:49 klen Цитата(*rust* @ Apr 29 2011, 11:47) Сейча... Apr 29 2011, 08:08 *rust* ЦитатаЧто-то непонятна ваша проблема. Вы вообще с ... Apr 29 2011, 10:11 aaarrr Цитата(*rust* @ Apr 29 2011, 14:11) Далее... Apr 29 2011, 10:28 *rust* Понятно, смысл ясен. Спасибо всем участникам обсуж... May 2 2011, 15:16 *rust* У AT91SAM3U есть поддержка MMC Specification V4.3,... May 5 2011, 11:58 aaarrr Цитата(*rust* @ May 5 2011, 15:58) У AT91... May 5 2011, 17:38 *rust* Понял Вас, спасибо. May 6 2011, 11:12 *rust* В очередной раз убедился, что абсолютно новая карт... Jun 27 2011, 10:54 _3m Цитата(*rust* @ Jun 27 2011, 14:54) Как п... Jun 27 2011, 14:14 *rust* ЦитатаРасчитывайте буфер на указанное в документац... Jun 27 2011, 17:59 scifi Цитата(*rust* @ Jun 27 2011, 21:59) Нет в... Jun 27 2011, 21:53 bels Цитата(*rust* @ Jun 27 2011, 21:59) Нет в... Aug 31 2011, 11:49  Lotor Цитата(bels @ Aug 31 2011, 15:49) и очень... Sep 1 2011, 05:06   bels Цитата(Lotor @ Sep 1 2011, 09:06) Из собс... Sep 1 2011, 15:37    Lotor Цитата(bels @ Sep 1 2011, 18:37) А каков ... Sep 1 2011, 20:01    aaarrr Цитата(bels @ Sep 1 2011, 19:37) А каков ... Sep 2 2011, 11:24     bels Я понимаю что по спецификации задержка может дости... Sep 2 2011, 16:27      aaarrr Цитата(bels @ Sep 2 2011, 20:27) А ни у к... Sep 2 2011, 17:35 Alex11 Есть еще некоторые карточки, которые (даже полност... Jun 27 2011, 21:43 Lotor Класс карточки не влияет на озвученную задержку (д... Sep 5 2011, 10:47 toretto С какого адреса можно начинать чтение данных с SD-... Oct 11 2011, 13:48 Lotor Цитата(toretto @ Oct 11 2011, 17:48) С ка... Oct 11 2011, 13:52 toretto а каким образом я могу узнать способ адрессации ка... Oct 12 2011, 08:56 Lotor Цитата(toretto @ Oct 12 2011, 12:56) а ка... Oct 12 2011, 09:42 toretto спасибо, попробую. если мне действтельно удастся ч... Oct 12 2011, 10:49 Lotor Цитата(toretto @ Oct 12 2011, 14:49) если... Oct 12 2011, 10:53 toretto хех.. значит читать можно только целыми секторами... Oct 12 2011, 11:26 Lotor Цитата(toretto @ Oct 12 2011, 15:26) хех.... Oct 12 2011, 12:33 *rust* По задержкам.
Я перепробовал огромное количество ... Oct 13 2011, 11:26
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|