Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F103 + MicroSD + USB = Mass Storage
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
IanPo
Здравствуйте!
Я успешно адаптировал пример с сайта ST USB MassStorage на своей плате (использовал F103VCT6).
Однако, измеренная скорость чтения оказалась 200, а записи - 36 кБайт/с.
На карточку ( TRANSCEND 2 G MicroSD ) с ПК пишутся файлы по 2МБайт, поэтому надо побыстрее.
Как я понял, в обмене задействован блок 512 байт, равный сектору ( 8 блоков по 64=MAX_BULK_SIZE).
Функция WriteMultiBLocks у меня работает около 12 мс (из-за встроенного цикла задержки, без которого
пишет быстро, почти 1 МБ/с, но только в файлах одни нули потом ), отсюда 512/0.012 = 42 кБ/с, минус
накладные расходы, получаем 36 кБайт. Замена на WriteBlock (пишется все равно 1 сектор) и ReadBlock
дала прирост до 280 при чтении и 70 кБайт/с при записи соответственно. Все равно, этого мало.
Мне нужны советы по оптимизации модуля sdio_stm32f1 или увеличения блока с 512 Б до 16КБ, например,
тогда можно было бы поднять скорость обмена и использовать Write- и ReadMultiBlocks, время выполнения
будет примерно те же 12 мс (замерял на блоках 12КБ).
Проект прилагаю (основан на примере ST и STM32Primer2_GPS_Tracker-master от Nemui Trinomius.
Ссылки на рабочие проекты приветствуются, особенно gcc и iar.
kovigor
Цитата(IanPo @ Dec 13 2014, 15:44) *
Здравствуйте!
Я успешно адаптировал пример с сайта ST USB MassStorage на своей плате (использовал F103VCT6).
Однако, измеренная скорость чтения оказалась 200, а записи - 36 кБайт/с.

Не может быть такой скорости, у меня с их примером (MCU = STM32F207, PHY = USB3300, плата самодельная) на HS выходило по паре мегабайт в обе стороны без всяких оптимизаций. FS не пробовал, но думаю, что в этом случае без оптимизации должно выйти килобайт по 600. Вы что, на LS запустили Mass-Storage ? Что-то там у вас не так ... sm.gif
IanPo
Цитата(kovigor @ Dec 13 2014, 16:24) *
Что-то там у вас не так ... sm.gif

Вот я и пытаюсь понять, что не так.
Кстати, FS = 12 Мбит/с , т.е. 1.5 МБ/с максимум.
Девайс FullSpeed
kovigor
Цитата(IanPo @ Dec 13 2014, 17:39) *
Девайс FullSpeed

Флэшки на FS дают в среднем 1.2 мегабайта в секунду.
Вы, кстати, случайно не переключили МК в режим LS (если для вашего МК такое возможно) ? А так - не вы первый, кто запускает этот пример. Работать он должен. Пусть не совсем оптимально, но должен ...
IanPo
Цитата(kovigor @ Dec 13 2014, 21:56) *
Флэшки на FS дают в среднем 1.2 мегабайта в секунду.
Вы, кстати, случайно не переключили МК в режим LS (если для вашего МК такое возможно) ? А так - не вы первый, кто запускает этот пример. Работать он должен. Пусть не совсем оптимально, но должен ...

USB DP подтягивается к "1" на ноге контроллера через резистор.
Схему прилагаю.
На флешках 4ГБ скорость чтения 500 кБайт/с, а записи - около 100.
Это явно не LS.

Кстати, в примере от ST функции типа WaitReadOperation виснут. Пришлось делать через опрос флага TransferComplete TC4.
Попробую завтра померять время записи сектора, посмотрю, где задержки.
kovigor
Цитата(IanPo @ Dec 13 2014, 23:29) *
На флешках 4ГБ скорость чтения 500 кБайт/с, а записи - около 100.

500 - это, как говорят медики, "вариант нормы". Я делал такой же проект на ARM9, и у меня без оптимизации получалось по 600 килобайт в обе стороны (было это давно, и карточка была древняя, на 256 МБайт). У вас 500. С записью - да, хуже. Совет. Попробуйте подправить проект таким образом, чтобы читать и писать не на карточку, а в ОЗУ микроконтроллера, или даже просто "глотать" (читай: отбрасывать данные от хоста, но сообщать ему, что все в порядке) данные при записи и выдавать хосту произвольные байты при чтении. Проблема решится ? Я почти уверен, что все станет заметно лучше ...
IanPo
Я уже это делал - убирал из функции WriteMultiBlocks цикл задержки - скорость записи увеличивалась до 1 МБайт/с, но на карточку в файл писались нули sm.gif
kovigor
Цитата(IanPo @ Dec 14 2014, 01:34) *
но на карточку в файл писались нули sm.gif

Еще раз. Никуда и ничего не пишите. Вообще. Просто отбрасывайте данные от хоста, но сообщайте ему, что они записаны успешно. Вам сейчас нужно выяснить, где проблема - в USB или в карточке ...
IanPo
Цитата(kovigor @ Dec 14 2014, 00:38) *
Еще раз. Никуда и ничего не пишите. Вообще. Просто отбрасывайте данные от хоста, но сообщайте ему, что они записаны успешно. Вам сейчас нужно выяснить, где проблема - в USB или в карточке ...

Сделал вот так:
Код
uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
{
    switch (lun)
    {
        case 0:
            Status = SD_OK;
            //SD_WriteBlock( (uint8_t*)Writebuff, Memory_Offset, Transfer_Length );
            if ( Status != SD_OK )
            {
            return MAL_FAIL;
            }
            break;
        default:
            return MAL_FAIL;
    }
    return MAL_OK;
}

Ничего не пишется теперь. Скорость записи средняя 667 КБ/с, местами до 1 МБ/с.
Т.е. почти на порядок выше.
kovigor
Цитата(IanPo @ Dec 14 2014, 15:45) *
Ничего не пишется теперь. Скорость записи средняя 667 КБ/с, местами до 1 МБ/с.
Т.е. почти на порядок выше.

Вот, отсюда и пляшите. Примите за аксиому (пока), что со всеми оптимизациями вам удастся удвоить это число. Но пока оставьте его, как есть, и отложите оптимизации на потом.
А теперь начинаем писать, а не отбрасывать. Для начала - в ОЗУ МК. Что при этом поменялось ?
P.S. Какой частотой тактируется карточка ?
IanPo
Если я правильно понял, то вместо WriteBlock я делаю копирование memcpy( myDestBuffer, (uint8_t*)Writebuff, TransferLength ) ?
uint8_t myDestBuffer[512];

Код
#define SD_DMA_MODE
//#define SD_POLLING_MODE

#if defined(SD_POLLING_MODE)
#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x6)
#else
#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x1)
#endif

Соответственно, 48/(1+2)=16. Менял на 4 и 6 - скорости чтения-записи заметно не изменились.

С копированием в ОЗУ скорость ровно такая же - 667 кБ/с.
Код
            Status = SD_OK;
            memcpy( myDestBuffer, (uint8_t*)Writebuff, Transfer_Length );
            //SD_WriteBlock( (uint8_t*)Writebuff, Memory_Offset, Transfer_Length );

---------------------------------------------------------------------------------------------------------------
Поправил функции ReadBlock и WriteBlock, как в примерах ST - получаю 285 кБ/с чтение и 111 - запись. Уныло как-то.
kovigor
Цитата(IanPo @ Dec 14 2014, 16:41) *
Поправил функции ReadBlock и WriteBlock, как в примерах ST - получаю 285 кБ/с чтение и 111 - запись. Уныло как-то.

С наскока задача не решится, не надейтесь. МК сложен, его USB - движок тоже очень непрост, примеры трудноразбираемы. Я просто через это проходил, но давно, деталей не помню. Но разобрался. Ушло на это около месяца. А вы хотите за пару дней разобраться. Нет, ну, конечно, способности у всех разные. Но я вас хочу сразу настроить на то, что задача у вас достаточно сложная. И придется погружаться в этот проект "с головой" ...
IanPo
Красные победили - чтение 667, запись 333 кБайт/с на Transcend 2 Гб (на 8 Гб SanDisk чтение ~700/500, на Kingston 4Гб ~700/400).
Основная суть переделки в memory.c - расширен буфер с 512 байт до 8 кБ.

Замечания:
1. Код Nemui Trinomius, похоже, негодный - работает только как низкоскоростной, после расширения буфера часть карт стала запарываться на записи.
2. Код от STM для 3210E-EVAL - хороший, протестирован на разных картах, все карты на выс.скорости работают нормально (файлы stm3210e_eval_sdio_sd.c и .h подойдут для 103 серии, вероятно, для 10х даже).
3. Сделаны кое-какие мелкие поправки (карта вставлена/нет и какой вывод это проверяет).
4. В свой основной проект (на Em::Blocks) код я пока не адаптировал, но, вроде, не должно быть проблем. Будем посмотреть.

Проект прилагаю.
kovigor
Цитата(IanPo @ Dec 21 2014, 23:13) *
чтение 667, запись 333 кБайт/с

Чтение - гуд, запись можно раза в два ускорить. В идеале можно ускорить чтение в два раза и запись - в четыре, или около того.
А вообще, поздравляю, вы молодец sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.