⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbtarget.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    return result;}/*}}}*//*{{{  Enumeration data                                         */// ----------------------------------------------------------------------------// The enumeration data.//// For simplicity this configuration involves just a single interface.// The target has to list all the endpoints, or the Linux kernel will// not allow application code to access them. Hence the information// provided by the device drivers has to be turned into endpoint descriptors.usb_configuration_descriptor usb_configuration = {    length:             USB_CONFIGURATION_DESCRIPTOR_LENGTH,    type:               USB_CONFIGURATION_DESCRIPTOR_TYPE,    total_length_lo:    USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_LO(1, 0),    total_length_hi:    USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_HI(1, 0),    number_interfaces:  1,    configuration_id:   1,      // id 0 is special according to the spec    configuration_str:  0,    attributes:         USB_CONFIGURATION_DESCRIPTOR_ATTR_REQUIRED |                        USB_CONFIGURATION_DESCRIPTOR_ATTR_SELF_POWERED,    max_power:          50};usb_interface_descriptor usb_interface = {    length:             USB_INTERFACE_DESCRIPTOR_LENGTH,    type:               USB_INTERFACE_DESCRIPTOR_TYPE,    interface_id:       0,    alternate_setting:  0,    number_endpoints:   0,    interface_class:    USB_INTERFACE_DESCRIPTOR_CLASS_VENDOR,    interface_subclass: USB_INTERFACE_DESCRIPTOR_SUBCLASS_VENDOR,    interface_protocol: USB_INTERFACE_DESCRIPTOR_PROTOCOL_VENDOR,    interface_str:      0};usb_endpoint_descriptor usb_endpoints[USBTEST_MAX_ENDPOINTS];                               const unsigned char* usb_strings[] = {    "\004\003\011\004",    "\020\003R\000e\000d\000 \000H\000a\000t\000",    "\054\003R\000e\000d\000 \000H\000a\000t\000 \000e\000C\000o\000s\000 \000"    "U\000S\000B\000 \000t\000e\000s\000t\000"};usbs_enumeration_data usb_enum_data = {    {        length:                 USB_DEVICE_DESCRIPTOR_LENGTH,        type:                   USB_DEVICE_DESCRIPTOR_TYPE,        usb_spec_lo:            USB_DEVICE_DESCRIPTOR_USB11_LO,        usb_spec_hi:            USB_DEVICE_DESCRIPTOR_USB11_HI,        device_class:           USB_DEVICE_DESCRIPTOR_CLASS_VENDOR,        device_subclass:        USB_DEVICE_DESCRIPTOR_SUBCLASS_VENDOR,        device_protocol:        USB_DEVICE_DESCRIPTOR_PROTOCOL_VENDOR,        max_packet_size:        8,        vendor_lo:              0x42,   // Note: this is not an allocated vendor id        vendor_hi:              0x42,        product_lo:             0x00,        product_hi:             0x01,        device_lo:              0x00,        device_hi:              0x01,        manufacturer_str:       1,        product_str:            2,        serial_number_str:      0,        number_configurations:  1    },    total_number_interfaces:    1,    total_number_endpoints:     0,    total_number_strings:       3,    configurations:             &usb_configuration,    interfaces:                 &usb_interface,    endpoints:                  usb_endpoints,    strings:                    usb_strings};static voidprovide_endpoint_enumeration_data(void){    int enum_endpoint_count = 0;    int i;    for (i = 0; !USBS_TESTING_ENDPOINTS_IS_TERMINATOR(usbs_testing_endpoints[i]); i++) {        // The control endpoint need not appear in the enumeration data.        if (USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL == usbs_testing_endpoints[i].endpoint_type) {            continue;        }        usb_endpoints[enum_endpoint_count].length          = USB_ENDPOINT_DESCRIPTOR_LENGTH;        usb_endpoints[enum_endpoint_count].type            = USB_ENDPOINT_DESCRIPTOR_TYPE;        usb_endpoints[enum_endpoint_count].endpoint        = usbs_testing_endpoints[i].endpoint_number |                                                             usbs_testing_endpoints[i].endpoint_direction;        switch (usbs_testing_endpoints[i].endpoint_type) {          case USB_ENDPOINT_DESCRIPTOR_ATTR_BULK:            usb_endpoints[enum_endpoint_count].attributes      = USB_ENDPOINT_DESCRIPTOR_ATTR_BULK;            usb_endpoints[enum_endpoint_count].max_packet_lo   = 64;            usb_endpoints[enum_endpoint_count].max_packet_hi   = 0;            usb_endpoints[enum_endpoint_count].interval        = 0;            break;                      case USB_ENDPOINT_DESCRIPTOR_ATTR_ISOCHRONOUS:            usb_endpoints[enum_endpoint_count].attributes      = USB_ENDPOINT_DESCRIPTOR_ATTR_ISOCHRONOUS;            usb_endpoints[enum_endpoint_count].max_packet_lo   = usbs_testing_endpoints[i].max_size & 0x0FF;            usb_endpoints[enum_endpoint_count].max_packet_hi   = (usbs_testing_endpoints[i].max_size >> 8) & 0x0FF;            usb_endpoints[enum_endpoint_count].interval        = 1;            break;                      case USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT:            usb_endpoints[enum_endpoint_count].attributes      = USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT;            usb_endpoints[enum_endpoint_count].max_packet_lo   = (unsigned char) usbs_testing_endpoints[i].max_size;            usb_endpoints[enum_endpoint_count].max_packet_hi   = 0;            usb_endpoints[enum_endpoint_count].interval        = 1;    // NOTE: possibly incorrect            break;        }        enum_endpoint_count++;    }    usb_interface.number_endpoints          = enum_endpoint_count;    usb_enum_data.total_number_endpoints    = enum_endpoint_count;    usb_configuration.total_length_lo       = USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_LO(1, enum_endpoint_count);    usb_configuration.total_length_hi       = USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_HI(1, enum_endpoint_count);}/*}}}*//*{{{  Host/target common code                                  */#define TARGET#include "common.c"/*}}}*//*{{{  The tests                                                *//*{{{  UsbTest structure                                        */// ----------------------------------------------------------------------------// All the information associated with a particular testcase. Much of this// is identical to the equivalent host-side structure, but some additional// information is needed so the structure and associated routines are not// shared.typedef struct UsbTest {    // A unique identifier to make verbose output easier to understand    int                 id;        // Which test should be run    usbtest             which_test;    // Test-specific details.    union {        UsbTest_Bulk        bulk;        UsbTest_ControlIn   control_in;    } test_params;    // How to recover from any problems. Specifically, what kind of message    // could the target send or receive that would unlock the thread on this    // side.    UsbTest_Recovery    recovery;    // The test result, to be collected and passed back to the host.    int                 result_pass;    char                result_message[USBTEST_MAX_MESSAGE];    // Support for synchronization. This allows the UsbTest structure to be    // used as the callback data for low-level USB calls.    cyg_sem_t           sem;    int                 transferred;    // Some tests may need extra cancellation support    void                (*cancel_fn)(struct UsbTest*);    unsigned char       buffer[USBTEST_MAX_BULK_DATA + USBTEST_MAX_BULK_DATA_EXTRA];} UsbTest;// Reset the information in a given test. This is used by the pool allocation// code. The data union is left alone, filling in the appropriate union// member is left to other code.static voidreset_usbtest(UsbTest* test){    static int next_id = 1;    test->id                    = next_id++;    test->which_test            = usbtest_invalid;    usbtest_recovery_reset(&(test->recovery));    test->result_pass           = 0;    test->result_message[0]     = '\0';    cyg_semaphore_init(&(test->sem), 0);    test->transferred           = 0;    test->cancel_fn             = (void (*)(UsbTest*)) 0;}// Forward declaration. The pool code depends on run_test(), setting up a test requires the pool.static UsbTest* pool_allocate(void);/*}}}*//*{{{  Bulk transfers                                           *//*{{{  handle_test_bulk()                                       */// Prepare for a bulk transfer test. This means allocating a thread to do// the work, and extracting the test parameters from the current buffer.// The thread allocation code does not require any locking since all worker// threads should be idle when starting a new thread, so the work can be// done entirely at DSR level and no synch is required.static usbs_control_returnhandle_test_bulk(usb_devreq* req){    UsbTest*    test;    int         index   = 0;    test = pool_allocate();    unpack_usbtest_bulk(&(test->test_params.bulk), class_request, &index);    test->which_test = (USB_DEVREQ_DIRECTION_IN == (test->test_params.bulk.endpoint & USB_DEVREQ_DIRECTION_MASK)) ?        usbtest_bulk_in : usbtest_bulk_out;    VERBOSE(3, "Preparing USB bulk test on endpoint %d, direction %s, for %d packets\n", \            test->test_params.bulk.endpoint & ~USB_DEVREQ_DIRECTION_MASK,                \            (usbtest_bulk_in == test->which_test) ? "IN" : "OUT",                           \            test->test_params.bulk.number_packets);    VERBOSE(3, "  I/O mechanism is %s\n", \            (usb_io_mechanism_usb == test->test_params.bulk.io_mechanism) ? "low-level USB" : \            (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism) ? "devtab" : "<invalid>");    VERBOSE(3, "  Data format %s, data1 %d, data* %d, data+ %d, data1* %d, data1+ %d, data** %d, data*+ %d, data+* %d, data++ %d\n",\            (usbtestdata_none     == test->test_params.bulk.data.format) ? "none" :     \            (usbtestdata_bytefill == test->test_params.bulk.data.format) ? "bytefill" : \            (usbtestdata_wordfill == test->test_params.bulk.data.format) ? "wordfill" : \            (usbtestdata_byteseq  == test->test_params.bulk.data.format) ? "byteseq"  : \            (usbtestdata_wordseq  == test->test_params.bulk.data.format) ? "wordseq"  : "<invalid>", \            test->test_params.bulk.data.seed,                            \            test->test_params.bulk.data.multiplier,                      \            test->test_params.bulk.data.increment,                       \            test->test_params.bulk.data.transfer_seed_multiplier,        \            test->test_params.bulk.data.transfer_seed_increment,         \            test->test_params.bulk.data.transfer_multiplier_multiplier,  \            test->test_params.bulk.data.transfer_multiplier_increment,   \            test->test_params.bulk.data.transfer_increment_multiplier,   \            test->test_params.bulk.data.transfer_increment_increment);    VERBOSE(3, "  txsize1 %d, txsize>= %d, txsize<= %d, txsize* %d, txsize/ %d, txsize+ %d\n", \            test->test_params.bulk.tx_size,         test->test_params.bulk.tx_size_min,        \            test->test_params.bulk.tx_size_max,     test->test_params.bulk.tx_size_multiplier, \            test->test_params.bulk.tx_size_divisor, test->test_params.bulk.tx_size_increment);    VERBOSE(3, "  rxsize1 %d, rxsize>= %d, rxsize<= %d, rxsize* %d, rxsize/ %d, rxsize+ %d\n", \            test->test_params.bulk.rx_size,         test->test_params.bulk.rx_size_min,        \            test->test_params.bulk.rx_size_max,     test->test_params.bulk.rx_size_multiplier, \            test->test_params.bulk.rx_size_divisor, test->test_params.bulk.rx_size_increment);    VERBOSE(3, "  txdelay1 %d, txdelay>= %d, txdelay<= %d, txdelay* %d, txdelay/ %d, txdelay+ %d\n", \            test->test_params.bulk.tx_delay,         test->test_params.bulk.tx_delay_min,            \            test->test_params.bulk.tx_delay_max,     test->test_params.bulk.tx_delay_multiplier,     \            test->test_params.bulk.tx_delay_divisor, test->test_params.bulk.tx_delay_increment);    VERBOSE(3, "  rxdelay1 %d, rxdelay>= %d, rxdelay<= %d, rxdelay* %d, rxdelay/ %d, rxdelay+ %d\n", \            test->test_params.bulk.rx_delay,         test->test_params.bulk.rx_delay_min,            \            test->test_params.bulk.rx_delay_max,     test->test_params.bulk.rx_delay_multiplier,     \            test->test_params.bulk.rx_delay_divisor, test->test_params.bulk.rx_delay_increment);        return USBS_CONTROL_RETURN_HANDLED;}/*}}}*//*{{{  run_test_bulk_out()                                      */// The same callback can be used for IN and OUT transfers. Note that// starting the next transfer is left to the thread, it is not done// at DSR level.static voidrun_test_bulk_in_out_callback(void* callback_arg, int transferred){    UsbTest*    test    = (UsbTest*) callback_arg;    test->transferred   = transferred;    cyg_semaphore_post(&(test->sem));}// OUT transfers, i.e. the host will be sending some number of// packets. The I/O can happen in a number of different ways, e.g. via// the low-level USB API or via devtab routines.static voidrun_test_bulk_out(UsbTest* test){    unsigned char*      buf;    int                 endpoint_number = test->test_params.bulk.endpoint & ~USB_DEVREQ_DIRECTION_MASK;    int                 ep_index;    usbs_rx_endpoint*   endpoint        = 0;    cyg_io_handle_t     io_handle       = (cyg_io_handle_t)0;    int                 alignment;    int                 transferred;    int                 i;    VERBOSE(1, "Starting test %d, bulk out on endpoint %d\n", test->id, endpoint_number);    ep_index = lookup_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT, USB_ENDPOINT_DESCRIPTOR_ATTR_BULK);    if (ep_index == -1) {            test->result_pass   = 0;            snprintf(test->result_message, USBTEST_MAX_MESSAGE,                     "Target, bulk OUT transfer on endpoint %d: no such bulk endpoint", endpoint_number);            return;    }    endpoint    = (usbs_rx_endpoint*) usbs_testing_endpoints[ep_index].endpoint;    alignment   = usbs_testing_endpoints[ep_index].alignment;    if (0 != alignment) {        buf         = (unsigned char*) ((((cyg_uint32)test->buffer) + alignment - 1) & ~(alignment - 1));    } else {        buf = test->buffer;    }        CYG_ASSERTC((usb_io_mechanism_usb == test->test_params.bulk.io_mechanism) || \                (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism));    if (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism) {        if (((const char*)0 == usbs_testing_endpoints[ep_index].devtab_entry) ||            (0 != cyg_io_lookup(usbs_testing_endpoints[ep_index].devtab_entry, &io_handle))) {                        test->result_pass   = 0;            snprintf(test->result_message, USBTEST_MAX_MESSAGE,                     "Target, bulk OUT transfer on endpoint %d: no devtab entry", endpoint_number);            return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -