Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странности (или ошибки) примера USB Mass Storage от Keil
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
sonycman
Осваиваю тут пример USB MSC для STM32, скачанный с сайта Кейл. Впрочем, практически такие-же примеры существуют и для LPC на этом-же сайте.
Вот архив, если кому интересно:
Нажмите для просмотра прикрепленного файла
Так вот, в некоторых местах кода озадачила обработка нештатных ситуаций и ошибок при проверке данных на уровне класса MSC.
К примеру, часто встречающаяся последовательность:
Код
    USB_SetStallEP(MSC_EP_IN);
    USB_SetStallEP(MSC_EP_OUT);
    CSW.bStatus = CSW_PHASE_ERROR;
    MSC_SetCSW();

то есть устанавливаются флаги STALL для обоих конечных точек bulk, а затем подготавливаются данные статуса CSW для последующей отправки хосту. Вроде всё правильно.
Но! Функция MSC_SetCSW() вызывает WriteEP, которая копирует данные в SRAM буфер конечной точки и затем перезаписывает её статус как VALID, то есть записанный перед этим STALL совершенно затирается!

Ну не бред ли??

В результате получится вместо STALL обычный ACK, данные статуса CSW уйдут как обычный пакет данных... что будет дальше, можно уже не разбираться - просто хаос...

В основном код написан вроде бы правильно, с верной обработкой протокола, но вот это место ставит меня в тупик - может быть я тут что-то недопонимаю?
Всё таки первый раз имею дело с USB и MSC...


Ещё хотел спросить - каким образом хост определяет конец фазы передачи данных в режиме Mass Storage?
Если последний пакет данных будет меньше максимально допустимого для данной конечной точки?
Или как-то по другому?

А то сижу сейчас и думаю, как мне обрабатывать неподдерживаемые моим девайсом SCSI команды.
К примеру, приходит CBW с какой нибудь SCSI_MODE_SELECT10, по идее я должен обработать фазу передачи данных для этой команды (если она есть), и уже затем отправить CSW с флагом CSW_CMD_FAILED.
То есть, если фаза данных будет состоять из 1000 байт, будет ли хост слать IN пакеты, пока не будут переданы все 1000 байт, или передача прекратится на первом же пакете нулевой (или любой другой, меньшей MAX_PACKET_SIZE) длины?
sonycman
И ещё вопрос - а стоит ли реализовывать команду SCSI_VERIFY10?
Что-то не вижу я в ней никакого смысла, флэшку проверять... не флоппик же, в конце концов laughing.gif
Только время терять, ведь скорость передачи данных упадёт...

Что, если на запрос хоста по SCSI_VERIFY10 послать его куда подальше (то есть ответить CSW_CMD_FAILED)?
Глядишь, не буде больше фигней заниматься?
smile.gif

2moderators: может, перенести эту тему в интерфейсы?
А то народ стесняется что-то общаться... laughing.gif
bob05
Почему CSW_CMD_FAILED ? Я немного разбирался с киеловским экзамплом потом пришлось перейти на ИАР.
В принципе там везде будет слать до число < MAX_PACKET_SIZE . к сожалению....
Опять же в Киеловском примере мы пишем в RAM а не во флэш...
С уважением, Борис. laughing.gif
sonycman
Цитата(bob05 @ Jun 30 2009, 12:34) *
Почему CSW_CMD_FAILED ?

Потому что ответом на неподдерживаемую команду является сталлинг конечных точек, установка статуса CSW_CMD_FAILED, и указание причины для последующего запроса SCSI_REQUEST_SENSE как INVALID_COMMAND_OPERATION_CODE.

Цитата(bob05 @ Jun 30 2009, 12:34) *
В принципе там везде будет слать до число < MAX_PACKET_SIZE . к сожалению....

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

Вообще я пока нашёл две проблемы в этом примере, и они касаются обработки ошибочных ситуаций:
1. Не устанавливается статус STALL, хотя в коде это есть, но сделано с ошибкой.
2. Не сбрасываются биты синхронизации Data Toggle после снятия статуса STALL с bulk конечных точек.

В остальном, вроде, там всё нормально.

На данный момент мой Mass Storage Device прекрасно работает с картой памяти в качестве носителя.
Теперь вот оптимизирую чтение\запись, и надо бы прикрутить двойную буферизацию для конечных точек.
vitaMAX
Здравствуйте.
Есть два проекта от Keil: USBMem (Memory) и FlashFS.
Первый проект организует USB mass storage на 16Kb в оперативной памяти проца. Второй - файловую систему на карте MMC.
Пытаюсь сделать USB mass storage на MMC + файловая система на mmc.
По логике нужно только "заменить" функции чтения и записи в проекте USBMem на ф-ции чтения/записи из FlashFS. Но вот тут и появляется загвоздка. После корректировки ф-ции чтения (а ее достаточно, чтобы при открытии флешки отображалось содержимое mmc, а не ОП проца), винда видит флешку, но говорит, что она не отформатирована и отформатировать сама естессн не может.


CODE

...
BYTE Memory[MSC_MemorySize]; /* MSC RAM */
BYTE Mem_[MSC_MAX_PACKET];
...
...
void MSC_MemoryRead (void) {
DWORD n;

if (Length > MSC_MAX_PACKET) {
n = MSC_MAX_PACKET;
} else {
n = Length;
}

if ((Offset + n) > MSC_MemorySize) {
n = MSC_MemorySize - Offset;
BulkStage = MSC_BS_DATA_IN_LAST_STALL;
}

fs_spi_ReadData (Offset, n, (U8*)&Mem_[0]); // попытка чтения с MMC блока размером n

USB_WriteEP(MSC_EP_IN, &Mem_[0], n); // отпрявляем на "вывод" то, что прочитали с mmc
//USB_WriteEP(MSC_EP_IN, &Memory[Offset], n); // отправляет на "вывод" содержимое ОП проца
Offset += n;
Length -= n;
CSW.dDataResidue -= n;

if (Length == 0) {
BulkStage = MSC_BS_DATA_IN_LAST;
}

if (BulkStage != MSC_BS_DATA_IN) {
FIO2CLR = LED_RD; /* Turn Off Read LED */
CSW.bStatus = CSW_CMD_PASSED;
}
}


На этом форуме были люди, которые реализовывали эту задачу, но к сожалению они вымерли еще в 2006 году... 1111493779.gif до них достучаться не смог.
Если кто сталкивался с данной задачей, помогите советом или исходником, если не считаете это мегапроектом smile.gif
Костян
Перепешите след. функцию
Код
void MSC_Inquiry (void)
{

if (!DataInFormat()) return;

BulkBuf[ 0] = 0x00; /* Direct Access Device */
BulkBuf[ 1] = 0x80; /* RMB = 1: Removable Medium */
BulkBuf[ 2] = 5;//0x00; /* Version: No conformance claim to standard */
BulkBuf[ 3] = 0x02;//0x01;
.........................
}

Должно все наладится.

А форматирование делайте не при помощи винды , а на борту MCU
vitaMAX
Цитата(Костян @ Oct 19 2009, 10:03) *
Перепешите след. функцию

Должно все наладится.

А форматирование делайте не при помощи винды , а на борту MCU
не всё наладилось..) флешка так и определяется неотформатированной, хотя она отформатирована через плату.
Кажется, у меня всё же косяк здесь:

Код
fs_spi_ReadData (Offset, n, (U8*)&Mem_); //  чтение с MMC блока размером n   == MSC_MAX_PACKET == 64
  USB_WriteEP(MSC_EP_IN, &Mem_[0], n); // отпрявляем на "вывод" то, что прочитали с mmc
  //USB_WriteEP(MSC_EP_IN, &Memory[Offset], n); // отправляет на "вывод" содержимое ОП проца

Да, блок читается, но тот ли..) здесь берутся по очереди блоки с ммс размером 64 байта и отправляются в TX_DATA. Как-то не так значит я читаю инфу, или совсем не ту инфу.
Напомню, в проекте Memory флешка создавалась на 16Kb. Сейчас хочу сделать флешку на mmc пока что такого же размера. т.е. размеры всех блоков оставил как в проекте Memory.
vitaMAX
Цитата(sonycman @ Jun 30 2009, 13:15) *
Потому что ответом на неподдерживаемую команду является сталлинг конечных точек, установка статуса CSW_CMD_FAILED, и указание причины для последующего запроса SCSI_REQUEST_SENSE как INVALID_COMMAND_OPERATION_CODE.


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

Вообще я пока нашёл две проблемы в этом примере, и они касаются обработки ошибочных ситуаций:
1. Не устанавливается статус STALL, хотя в коде это есть, но сделано с ошибкой.
2. Не сбрасываются биты синхронизации Data Toggle после снятия статуса STALL с bulk конечных точек.

В остальном, вроде, там всё нормально.

На данный момент мой Mass Storage Device прекрасно работает с картой памяти в качестве носителя.
Теперь вот оптимизирую чтение\запись, и надо бы прикрутить двойную буферизацию для конечных точек.

если не сложно, хотелось бы посмотреть на рабочий проект Mass Storage Device на mmc.
Уже достаточно долго бьюсь над этой затеей, но пока что только smile3046.gif
vitaMAX
В проекте Memory при старте массив const unsigned char DiskImage[MSC_ImageSize] записывается в RAM.
Затем, в ф-ции void MSC_MemoryRead (void) считывается поблочно вся память на RAM.
Возникает вопрос, а если флешка была бы не на 16Kb, а на 2Гб - сколько бы времени ушло на пробег по всей памяти? здесь явно нужен другой подход для реализации usb mass storage на mmc.
И второй вопрос. чтобы винда не говорила, что флешка не отформатирована, ей нужно дать заголовочный сектор с флешки-mmc карты.
Я использовал ф-цию чтения с карты int fs_spi_ReadData (U32 adr, U32 sz, U8 *buf), но безрезультатно. Да, блоки считываются, но в них явно не та инфа.
Помогите советом, как заставить винду видеть mmc-card как usb mass storage
Nixon
Вот вам как раз скрещенный usbmem и flаshfs от кейла
vitaMAX
Цитата(Nixon @ Oct 20 2009, 09:55) *
Вот вам как раз скрещенный usbmem и flаshfs от кейла

старый немного проект.. используется RTLFS.lib. Новая либа FS_ARM_L.lib немного отличается от старой.
В выложенном проекте не увидел инициализацию USB. Если не сложно, выложите RTLFS.lib

Вот мои первые шаги. пока только просто объединил два проекта. Получается USB mass storage на RAM и FS на mmc card.
работаю на LPC2378
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.