|
|
  |
STM32F103 + MicroSD + USB = Mass Storage, низкая скорость чтения - записи -- нужна оптимизация |
|
|
|
Dec 13 2014, 12:44
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 14-10-10
Пользователь №: 60 152

|
Здравствуйте! Я успешно адаптировал пример с сайта 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.
|
|
|
|
|
Dec 13 2014, 13:24
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(IanPo @ Dec 13 2014, 15:44)  Здравствуйте! Я успешно адаптировал пример с сайта ST USB MassStorage на своей плате (использовал F103VCT6). Однако, измеренная скорость чтения оказалась 200, а записи - 36 кБайт/с. Не может быть такой скорости, у меня с их примером (MCU = STM32F207, PHY = USB3300, плата самодельная) на HS выходило по паре мегабайт в обе стороны без всяких оптимизаций. FS не пробовал, но думаю, что в этом случае без оптимизации должно выйти килобайт по 600. Вы что, на LS запустили Mass-Storage ? Что-то там у вас не так ...
|
|
|
|
|
Dec 13 2014, 14:39
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 14-10-10
Пользователь №: 60 152

|
Цитата(kovigor @ Dec 13 2014, 16:24)  Что-то там у вас не так ...  Вот я и пытаюсь понять, что не так. Кстати, FS = 12 Мбит/с , т.е. 1.5 МБ/с максимум. Девайс FullSpeed
Сообщение отредактировал IanPo - Dec 13 2014, 14:40
|
|
|
|
|
Dec 13 2014, 20:29
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 14-10-10
Пользователь №: 60 152

|
Цитата(kovigor @ Dec 13 2014, 21:56)  Флэшки на FS дают в среднем 1.2 мегабайта в секунду. Вы, кстати, случайно не переключили МК в режим LS (если для вашего МК такое возможно) ? А так - не вы первый, кто запускает этот пример. Работать он должен. Пусть не совсем оптимально, но должен ... USB DP подтягивается к "1" на ноге контроллера через резистор. Схему прилагаю. На флешках 4ГБ скорость чтения 500 кБайт/с, а записи - около 100. Это явно не LS. Кстати, в примере от ST функции типа WaitReadOperation виснут. Пришлось делать через опрос флага TransferComplete TC4. Попробую завтра померять время записи сектора, посмотрю, где задержки.
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 13 2014, 21:12
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(IanPo @ Dec 13 2014, 23:29)  На флешках 4ГБ скорость чтения 500 кБайт/с, а записи - около 100. 500 - это, как говорят медики, "вариант нормы". Я делал такой же проект на ARM9, и у меня без оптимизации получалось по 600 килобайт в обе стороны (было это давно, и карточка была древняя, на 256 МБайт). У вас 500. С записью - да, хуже. Совет. Попробуйте подправить проект таким образом, чтобы читать и писать не на карточку, а в ОЗУ микроконтроллера, или даже просто "глотать" (читай: отбрасывать данные от хоста, но сообщать ему, что все в порядке) данные при записи и выдавать хосту произвольные байты при чтении. Проблема решится ? Я почти уверен, что все станет заметно лучше ...
|
|
|
|
|
Dec 14 2014, 11:45
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 14-10-10
Пользователь №: 60 152

|
Цитата(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 МБ/с. Т.е. почти на порядок выше.
|
|
|
|
|
Dec 14 2014, 12:41
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 14-10-10
Пользователь №: 60 152

|
Если я правильно понял, то вместо 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 - запись. Уныло как-то.
Сообщение отредактировал IanPo - Dec 14 2014, 16:21
|
|
|
|
|
Dec 14 2014, 19:19
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(IanPo @ Dec 14 2014, 16:41)  Поправил функции ReadBlock и WriteBlock, как в примерах ST - получаю 285 кБ/с чтение и 111 - запись. Уныло как-то. С наскока задача не решится, не надейтесь. МК сложен, его USB - движок тоже очень непрост, примеры трудноразбираемы. Я просто через это проходил, но давно, деталей не помню. Но разобрался. Ушло на это около месяца. А вы хотите за пару дней разобраться. Нет, ну, конечно, способности у всех разные. Но я вас хочу сразу настроить на то, что задача у вас достаточно сложная. И придется погружаться в этот проект "с головой" ...
|
|
|
|
|
Dec 21 2014, 19:13
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 14-10-10
Пользователь №: 60 152

|
Красные победили - чтение 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) код я пока не адаптировал, но, вроде, не должно быть проблем. Будем посмотреть. Проект прилагаю.
Сообщение отредактировал IanPo - Dec 21 2014, 19:14
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|