Перейти к содержанию
    

STM32F103 + MicroSD + USB = Mass Storage

Здравствуйте!

Я успешно адаптировал пример с сайта 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.

STM32_USB_FS_Device_Lib_V4.0.0.7z

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте!

Я успешно адаптировал пример с сайта ST USB MassStorage на своей плате (использовал F103VCT6).

Однако, измеренная скорость чтения оказалась 200, а записи - 36 кБайт/с.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то там у вас не так ... :)

Вот я и пытаюсь понять, что не так.

Кстати, FS = 12 Мбит/с , т.е. 1.5 МБ/с максимум.

Девайс FullSpeed

Изменено пользователем IanPo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Девайс FullSpeed

Флэшки на FS дают в среднем 1.2 мегабайта в секунду.

Вы, кстати, случайно не переключили МК в режим LS (если для вашего МК такое возможно) ? А так - не вы первый, кто запускает этот пример. Работать он должен. Пусть не совсем оптимально, но должен ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Флэшки на FS дают в среднем 1.2 мегабайта в секунду.

Вы, кстати, случайно не переключили МК в режим LS (если для вашего МК такое возможно) ? А так - не вы первый, кто запускает этот пример. Работать он должен. Пусть не совсем оптимально, но должен ...

USB DP подтягивается к "1" на ноге контроллера через резистор.

Схему прилагаю.

На флешках 4ГБ скорость чтения 500 кБайт/с, а записи - около 100.

Это явно не LS.

 

Кстати, в примере от ST функции типа WaitReadOperation виснут. Пришлось делать через опрос флага TransferComplete TC4.

Попробую завтра померять время записи сектора, посмотрю, где задержки.

post-60152-1418502191_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На флешках 4ГБ скорость чтения 500 кБайт/с, а записи - около 100.

500 - это, как говорят медики, "вариант нормы". Я делал такой же проект на ARM9, и у меня без оптимизации получалось по 600 килобайт в обе стороны (было это давно, и карточка была древняя, на 256 МБайт). У вас 500. С записью - да, хуже. Совет. Попробуйте подправить проект таким образом, чтобы читать и писать не на карточку, а в ОЗУ микроконтроллера, или даже просто "глотать" (читай: отбрасывать данные от хоста, но сообщать ему, что все в порядке) данные при записи и выдавать хосту произвольные байты при чтении. Проблема решится ? Я почти уверен, что все станет заметно лучше ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я уже это делал - убирал из функции WriteMultiBlocks цикл задержки - скорость записи увеличивалась до 1 МБайт/с, но на карточку в файл писались нули :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но на карточку в файл писались нули :)

Еще раз. Никуда и ничего не пишите. Вообще. Просто отбрасывайте данные от хоста, но сообщайте ему, что они записаны успешно. Вам сейчас нужно выяснить, где проблема - в USB или в карточке ...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще раз. Никуда и ничего не пишите. Вообще. Просто отбрасывайте данные от хоста, но сообщайте ему, что они записаны успешно. Вам сейчас нужно выяснить, где проблема - в 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 МБ/с.

Т.е. почти на порядок выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ничего не пишется теперь. Скорость записи средняя 667 КБ/с, местами до 1 МБ/с.

Т.е. почти на порядок выше.

Вот, отсюда и пляшите. Примите за аксиому (пока), что со всеми оптимизациями вам удастся удвоить это число. Но пока оставьте его, как есть, и отложите оптимизации на потом.

А теперь начинаем писать, а не отбрасывать. Для начала - в ОЗУ МК. Что при этом поменялось ?

P.S. Какой частотой тактируется карточка ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если я правильно понял, то вместо 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поправил функции ReadBlock и WriteBlock, как в примерах ST - получаю 285 кБ/с чтение и 111 - запись. Уныло как-то.

С наскока задача не решится, не надейтесь. МК сложен, его USB - движок тоже очень непрост, примеры трудноразбираемы. Я просто через это проходил, но давно, деталей не помню. Но разобрался. Ушло на это около месяца. А вы хотите за пару дней разобраться. Нет, ну, конечно, способности у всех разные. Но я вас хочу сразу настроить на то, что задача у вас достаточно сложная. И придется погружаться в этот проект "с головой" ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Красные победили - чтение 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) код я пока не адаптировал, но, вроде, не должно быть проблем. Будем посмотреть.

 

Проект прилагаю.

STM32_USB_FS_Device_Lib_V4.0.0.7z

Изменено пользователем IanPo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чтение 667, запись 333 кБайт/с

Чтение - гуд, запись можно раза в два ускорить. В идеале можно ускорить чтение в два раза и запись - в четыре, или около того.

А вообще, поздравляю, вы молодец :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...