Понимание и декодирование стандартных USB-команд до конечной точки ноль?

Я пытаюсь написать процедуру инициализации USB для 8-битного RISC MCU. Ссылка на лист данных приведена ниже.

Моя цель - написать код прототипа устройства, который позволит хосту успешно перечислять мое устройство и отправлять / получать данные.

В SDK этого IC есть статическая библиотека UFI без источников, которая имеет только несколько функций, определенных в заголовочном файле:

//
// Command/Data/Status Protocol
//
typedef struct _CBW // Command Block Wrapper
{
    unsigned char dSignature[4];    // 43425355h (little endian)
    unsigned char dTag[4];
    unsigned char dDataTransferLength[4];
    unsigned char bmFlags;          // Bit 7    0 = Data-Out from host to the device.
                                    //          1 = Data-In from the device to host.
                                    // Bit 6    Obsolete
    unsigned char bLUN;
    unsigned char bCBLength;
    unsigned char CB[0x10];         // offset: (15 + bCBLength - 1)
} CBW;
typedef struct _CSW // Command Status Wrapper
{
    unsigned char dSignature[4];    // 53425355h (little endian)
    unsigned char dTag[4];
    unsigned char dDataResidue[4];
    unsigned char bStatus;          // 00h  Command Passed ("good status")
                                    // 01h  Command Failed
                                    // 02h  Phase Error
                                    // 03h and 04h  Reserved (Obsolete)
} CSW;

#define COMMAND_PASSED 0x00
#define COMMAND_FAILED 0x01
#define PHASE_ERROR    0x02

enum
{
UFI_MODE_TIMESYNC = 1,
UFI_MODE_DOWNSTART,
UFI_MODE_DOWNFINISH,
UFI_MODE_IGNORE,
UFI_MODE_NORMAL
};

//
// UFI Command
//
#define INQUIRY                      0x12
#define READ_FORMAT_CAPACITIES       0x23
#define READ_CAPACITY                0x25
#define READ_10                      0x28
#define REQUEST_SENSE                0x03
#define TEST_UNIT_READY              0x00
#define PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
#define WRITE_10                     0x2a
#define VERIFY                       0x2f

typedef struct
{
    UCHAR memType; // 0:eflash 1:s-flash
    ULONG tgtAddr; // Target address to write
    ULONG totSize; // Total size of data
    ULONG curSize; // Downloaded size of data
}stUfiDwnStatus;

UFI_EXT CBW g_cbw;
UFI_EXT CSW g_csw;
UFI_EXT unsigned char g_bUfiWriteMode;
UFI_EXT unsigned char g_bUfiWriteMode_post;
UFI_EXT stUfiDwnStatus g_ufiDwnStaus;



void UFI_proc(void);
void UFI_InitMem(UCHAR *buf, UCHAR *name);  // Buffer size must be larger than 0x200
void UFI_InitFuncEFlash(void (*funcSectorErase)(UCHAR AddH, UCHAR AddM, UCHAR AddL),
                        void (*funcPageProgram)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer),
                        void (*funcRead)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer) );
void UFI_InitFuncSFlash(void (*funcBlockErase)(UCHAR AddH, UCHAR AddM, UCHAR AddL),
                        void (*funcPageProgram)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer),
                        void (*funcRead)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer) );

Каким-то образом мне нужно использовать эту библиотеку, чтобы установить мое устройство в качестве запоминающего устройства, чтобы избежать работы с пользовательскими драйверами хост-устройств.

Проблема в том, что я не знаю с чего начать. Особенно я не понимаю, как настроить EP0? Список возможностей USB упоминает

Understanding and decoding of standard USB commands to endpoint zero

Что именно это значит? Документация действительно скудная, и я не знаю, какую логику придерживаться, чтобы инициализировать USB-устройство хотя бы на стороне устройства. Обычно я читаю об USB, но не могу связать эти знания с тем, как я должен конструировать свой код... Я выполнил кодирование всех периферийных устройств на этой микросхеме, кроме USB.

Любая идея будет высоко оценена.

https://www.dropbox.com/s/qd9d25oxxvh23ia/BMC51A_UM_REV1.0.pdf

2 ответа

Решение

"Стандартные команды USB для конечной точки ноль" описаны в главе 9 спецификации USB. Я обычно ссылаюсь на ревизию 2.0, которую вы можете найти здесь:

http://www.usb.org/developers/docs/usb20_docs/

Просто скачайте ZIP-файл, найдите usb_20.pdfи перейдите к Главе 9. В этой главе определяются передачи управления на нулевой конечной точке, которые используются USB-хостом для получения дескрипторов и настройки устройства. Спецификация USB составляет около 600 страниц, но она очень удобочитаема, и вы сможете многому научиться на ней.

Чтобы ваше устройство работало как запоминающее устройство, вам необходимо реализовать некоторые дополнительные функции, описанные в документах класса устройств USB-IF в категории запоминающее устройство:

http://www.usb.org/developers/docs/devclass_docs/

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

Выложенный вами код не похож на стандартные команды USB. Это может быть связано с классом MSD или, может быть, это какой-то специальный протокол.

"Конечная точка ноль" - это "передача управления" в USB.

Для обмена данными существуют "массовые передачи" (массовая передача и массовая передача, с разными конечными точками).

Я советую сначала написать простой драйвер USB на компьютере, чтобы узнать, как работает USB.

Вы можете прослушивать usb-пакеты в linux с помощью "tcpdump" (используя интерфейс usbmon0, usbmon1 и т. Д. После "modprobe usbmon"). Используйте wireshark для просмотра пакетов.

Вы можете легко получить доступ к USB из пользовательского пространства с помощью libusb.

Другие вопросы по тегам