sim/usb: add sim usb device
Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
parent
699c930987
commit
c61c694a77
@ -605,4 +605,34 @@ config SIM_UART3_NAME
|
||||
|
||||
endmenu
|
||||
|
||||
config SIM_USB_DEV
|
||||
bool "Linux USB Device"
|
||||
select USBDEV
|
||||
---help---
|
||||
Build in support for simulated usb device
|
||||
|
||||
if SIM_USB_DEV
|
||||
|
||||
config SIM_USB_RAW_GADGET
|
||||
bool "Simulated USB Raw Gadget Dev"
|
||||
default n
|
||||
depends on HOST_LINUX
|
||||
---help---
|
||||
Use USB Raw Gadget and Dummy HCD/UDC to set up virtual
|
||||
USB Device and Host controller that connected to each
|
||||
other inside the kernel.
|
||||
|
||||
Get Raw Gadget:
|
||||
Get Raw Gadget code at https://github.com/xairy/raw-gadget.
|
||||
|
||||
Make Raw Gadget:
|
||||
Run make in the raw_gadget and dummy_hcd directory. If raw_gadget
|
||||
build fail, you need to check which register interface meets your
|
||||
kenel version, usb_gadget_probe_driver or usb_gadget_register_driver.
|
||||
|
||||
Install Raw Gadget:
|
||||
Run ./insmod.sh in the raw_gadget and dummy_hcd directory.
|
||||
|
||||
endif
|
||||
|
||||
endif # ARCH_SIM
|
||||
|
@ -198,6 +198,13 @@ ifeq ($(CONFIG_SIM_SPI_LINUX),y)
|
||||
HOSTSRCS += sim_linuxspi.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_USB_DEV),y)
|
||||
CSRCS += sim_usbdev.c
|
||||
ifeq ($(CONFIG_SIM_USB_RAW_GADGET),y)
|
||||
HOSTSRCS += sim_rawgadget.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RPTUN),y)
|
||||
CSRCS += sim_rptun.c
|
||||
endif
|
||||
|
903
arch/sim/src/sim/posix/sim_rawgadget.c
Normal file
903
arch/sim/src/sim/posix/sim_rawgadget.c
Normal file
@ -0,0 +1,903 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/posix/sim_rawgadget.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
|
||||
#include "sim_internal.h"
|
||||
#include "sim_usbdev.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ERROR(fmt, ...) \
|
||||
syslog(LOG_ERR, "sim_rawgadget: " fmt "\n", ##__VA_ARGS__)
|
||||
#define INFO(fmt, ...) \
|
||||
syslog(LOG_INFO, "sim_rawgadget: " fmt "\n", ##__VA_ARGS__)
|
||||
#define DEBUG(fmt, ...)
|
||||
|
||||
#define USB_RAW_IOCTL_INIT _IOW('U', 0, struct usb_raw_init_s)
|
||||
#define USB_RAW_IOCTL_RUN _IO('U', 1)
|
||||
#define USB_RAW_IOCTL_EVENT_FETCH _IOR('U', 2, struct usb_raw_event_s)
|
||||
#define USB_RAW_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_raw_ep_io_s)
|
||||
#define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io_s)
|
||||
#define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor)
|
||||
#define USB_RAW_IOCTL_EP_DISABLE _IOW('U', 6, __u32)
|
||||
#define USB_RAW_IOCTL_EP_WRITE _IOW('U', 7, struct usb_raw_ep_io_s)
|
||||
#define USB_RAW_IOCTL_EP_READ _IOWR('U', 8, struct usb_raw_ep_io_s)
|
||||
#define USB_RAW_IOCTL_CONFIGURE _IO('U', 9)
|
||||
#define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32)
|
||||
#define USB_RAW_IOCTL_EPS_INFO _IOR('U', 11, struct usb_raw_eps_info_s)
|
||||
#define USB_RAW_IOCTL_EP0_STALL _IO('U', 12)
|
||||
#define USB_RAW_IOCTL_EP_SET_HALT _IOW('U', 13, __u32)
|
||||
#define USB_RAW_IOCTL_EP_CLEAR_HALT _IOW('U', 14, __u32)
|
||||
#define USB_RAW_IOCTL_EP_SET_WEDGE _IOW('U', 15, __u32)
|
||||
|
||||
#define USB_RAW_EP_NUM(addr) ((addr) & USB_ENDPOINT_NUMBER_MASK)
|
||||
#define USB_RAW_EP_DIR(addr) ((addr) & USB_ENDPOINT_DIR_MASK)
|
||||
|
||||
#define USB_RAW_EPS_NUM_MAX 30
|
||||
#define USB_RAW_EP_NAME_MAX 16
|
||||
#define USB_RAW_EP_ADDR_ANY 0xff
|
||||
|
||||
#define UDC_NAME_LENGTH_MAX 128
|
||||
|
||||
#define USB_RAW_EP0_MAX_LEN 256
|
||||
#define USB_RAW_EP_MAX_LEN 1024
|
||||
|
||||
#define USB_RAW_RX_BUF_NUM 8
|
||||
|
||||
#define USB_RAW_DEVICE "dummy_udc.0"
|
||||
#define USB_RAW_DRIVER "dummy_udc"
|
||||
|
||||
#define USB_RAW_FIFO_USED(fifo) ((fifo)->write - (fifo)->read)
|
||||
#define USB_RAW_FIFO_UNUSED(fifo) ((fifo)->elem_num - USB_RAW_FIFO_USED(fifo))
|
||||
#define USB_RAW_FIFO_MASK(fifo) ((fifo)->elem_num - 1)
|
||||
#define USB_RAW_FIFO_PUSH(fifo) ((fifo)->write++)
|
||||
#define USB_RAW_FIFO_POP(fifo) ((fifo)->read++)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
enum usb_raw_event_type_e
|
||||
{
|
||||
USB_RAW_EVENT_INVALID,
|
||||
USB_RAW_EVENT_CONNECT,
|
||||
USB_RAW_EVENT_CONTROL,
|
||||
};
|
||||
|
||||
struct usb_raw_init_s
|
||||
{
|
||||
uint8_t driver_name[UDC_NAME_LENGTH_MAX];
|
||||
uint8_t device_name[UDC_NAME_LENGTH_MAX];
|
||||
uint8_t speed;
|
||||
};
|
||||
|
||||
struct usb_raw_event_s
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t length;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
struct usb_raw_ep_io_s
|
||||
{
|
||||
uint16_t ep;
|
||||
uint16_t flags;
|
||||
uint32_t length;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
struct usb_raw_control_io_s
|
||||
{
|
||||
struct usb_raw_ep_io_s inner;
|
||||
uint8_t data[USB_RAW_EP0_MAX_LEN];
|
||||
};
|
||||
|
||||
struct usb_raw_data_io_s
|
||||
{
|
||||
struct usb_raw_ep_io_s inner;
|
||||
uint8_t data[USB_RAW_EP_MAX_LEN];
|
||||
};
|
||||
|
||||
struct usb_raw_ep_caps_s
|
||||
{
|
||||
uint32_t type_control : 1;
|
||||
uint32_t type_iso : 1;
|
||||
uint32_t type_bulk : 1;
|
||||
uint32_t type_int : 1;
|
||||
uint32_t dir_in : 1;
|
||||
uint32_t dir_out : 1;
|
||||
};
|
||||
|
||||
struct usb_raw_ep_limits_s
|
||||
{
|
||||
uint16_t maxpacket_limit;
|
||||
uint16_t max_streams;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct usb_raw_ep_info_s
|
||||
{
|
||||
uint8_t name[USB_RAW_EP_NAME_MAX];
|
||||
uint32_t addr;
|
||||
struct usb_raw_ep_caps_s caps;
|
||||
struct usb_raw_ep_limits_s limits;
|
||||
};
|
||||
|
||||
struct usb_raw_eps_info_s
|
||||
{
|
||||
struct usb_raw_ep_info_s eps[USB_RAW_EPS_NUM_MAX];
|
||||
};
|
||||
|
||||
struct usb_raw_control_event_s
|
||||
{
|
||||
struct usb_raw_event_s inner;
|
||||
struct usb_ctrlrequest ctrl;
|
||||
};
|
||||
|
||||
struct usb_raw_fifo_s
|
||||
{
|
||||
uint16_t read;
|
||||
uint16_t write;
|
||||
uint16_t elem_size;
|
||||
uint16_t elem_num;
|
||||
uint8_t *elems;
|
||||
};
|
||||
|
||||
struct usb_raw_ep_entry_s
|
||||
{
|
||||
bool halted;
|
||||
uint16_t addr;
|
||||
uint16_t raw_epaddr;
|
||||
uint16_t raw_epid;
|
||||
struct usb_raw_fifo_s fifo;
|
||||
pthread_t ep_thread;
|
||||
};
|
||||
|
||||
struct usb_raw_gadget_dev_t
|
||||
{
|
||||
int fd;
|
||||
uint16_t eps_num;
|
||||
pthread_t ep0_thread;
|
||||
struct usb_raw_control_io_s ep0_ctrl;
|
||||
struct usb_raw_ep_entry_s eps_entry[USB_RAW_EPS_NUM_MAX];
|
||||
struct usb_raw_eps_info_s eps_info;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct usb_raw_gadget_dev_t g_raw_gadget_dev =
|
||||
{
|
||||
.fd = -1,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void host_raw_fifocreate(struct usb_raw_fifo_s *fifo,
|
||||
uint16_t elem_size, uint16_t elem_num)
|
||||
{
|
||||
if (elem_num & (elem_num - 1))
|
||||
{
|
||||
ERROR("USB raw fifo num error");
|
||||
return;
|
||||
}
|
||||
|
||||
fifo->write = 0;
|
||||
fifo->read = 0;
|
||||
fifo->elem_size = elem_size;
|
||||
fifo->elem_num = elem_num;
|
||||
fifo->elems = (uint8_t *)malloc(elem_size * elem_num);
|
||||
}
|
||||
|
||||
static void host_raw_fifodelete(struct usb_raw_fifo_s *fifo)
|
||||
{
|
||||
fifo->write = 0;
|
||||
fifo->read = 0;
|
||||
free(fifo->elems);
|
||||
}
|
||||
|
||||
static uint8_t *host_raw_fiforead(struct usb_raw_fifo_s *fifo)
|
||||
{
|
||||
uint16_t r_idx;
|
||||
|
||||
if (USB_RAW_FIFO_USED(fifo) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_idx = fifo->read & USB_RAW_FIFO_MASK(fifo);
|
||||
return &fifo->elems[fifo->elem_size * r_idx];
|
||||
}
|
||||
|
||||
static uint8_t *host_raw_fifoalloc(struct usb_raw_fifo_s *fifo)
|
||||
{
|
||||
uint16_t w_idx;
|
||||
|
||||
if (USB_RAW_FIFO_UNUSED(fifo) == 0)
|
||||
{
|
||||
ERROR("USB raw get fifo fail");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w_idx = fifo->write & USB_RAW_FIFO_MASK(fifo);
|
||||
return &fifo->elems[fifo->elem_size * w_idx];
|
||||
}
|
||||
|
||||
static int host_raw_open(void)
|
||||
{
|
||||
int fd = open("/dev/raw-gadget", O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
ERROR("open fail");
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void host_raw_close(int fd)
|
||||
{
|
||||
if (fd >= 0)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void host_raw_init(int fd, enum usb_device_speed speed,
|
||||
const char *driver, const char *device)
|
||||
{
|
||||
struct usb_raw_init_s arg;
|
||||
strcpy((char *)&arg.driver_name[0], driver);
|
||||
strcpy((char *)&arg.device_name[0], device);
|
||||
arg.speed = speed;
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_INIT, &arg);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_INIT) fail");
|
||||
}
|
||||
}
|
||||
|
||||
static int host_raw_run(int fd)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_RUN, 0);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_RUN) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_eventfetch(int fd, struct usb_raw_event_s *event)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EVENT_FETCH, event);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EVENT_FETCH) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_ep0read(int fd, struct usb_raw_ep_io_s *io)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP0_READ, io);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP0_READ)");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_ep0write(int fd, struct usb_raw_ep_io_s *io)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP0_WRITE, io);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP0_WRITE) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_epenable(int fd, struct usb_endpoint_descriptor *desc)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP_ENABLE, desc);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP_ENABLE) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_epdisable(int fd, uint8_t epno)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP_DISABLE, epno);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP_DISABLE) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_epread(int fd, struct usb_raw_ep_io_s *io)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP_READ, io);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP_READ) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_epwrite(int fd, struct usb_raw_ep_io_s *io)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP_WRITE, io);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP_WRITE) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void host_raw_configure(int fd)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_CONFIGURE, 0);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_CONFIGURED) fail");
|
||||
}
|
||||
}
|
||||
|
||||
static void host_raw_vbusdraw(int fd, uint32_t power)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_VBUS_DRAW, power);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_VBUS_DRAW) fail");
|
||||
}
|
||||
}
|
||||
|
||||
static int host_raw_epsinfo(int fd, struct usb_raw_eps_info_s *info)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EPS_INFO, info);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EPS_INFO) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_ep0stall(int fd)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP0_STALL, 0);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP0_STALL) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_epsethalt(int fd, int ep)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP_SET_HALT, ep);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP_SET_HALT) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int host_raw_epclearhalt(int fd, int ep)
|
||||
{
|
||||
int rv = ioctl(fd, USB_RAW_IOCTL_EP_CLEAR_HALT, ep);
|
||||
if (rv < 0)
|
||||
{
|
||||
ERROR("ioctl(USB_RAW_IOCTL_EP_CLEAR_HALT) fail");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
host_raw_setctrlreq(struct host_usb_ctrlreq_s *host_req,
|
||||
const struct usb_ctrlrequest *raw_req)
|
||||
{
|
||||
host_req->type = raw_req->bRequestType;
|
||||
host_req->req = raw_req->bRequest;
|
||||
host_req->value = raw_req->wValue;
|
||||
host_req->index = raw_req->wIndex;
|
||||
host_req->len = raw_req->wLength;
|
||||
}
|
||||
|
||||
static void
|
||||
host_raw_getepdesc(struct usb_endpoint_descriptor *raw_epdesc,
|
||||
const struct host_usb_epdesc_s *host_epdesc)
|
||||
{
|
||||
raw_epdesc->bLength = host_epdesc->len;
|
||||
raw_epdesc->bDescriptorType = host_epdesc->type;
|
||||
raw_epdesc->bEndpointAddress = host_epdesc->addr;
|
||||
raw_epdesc->bmAttributes = host_epdesc->attr;
|
||||
raw_epdesc->wMaxPacketSize = host_epdesc->mxpacketsize;
|
||||
raw_epdesc->bInterval = host_epdesc->interval;
|
||||
}
|
||||
|
||||
static int host_raw_connecthandle(struct usb_raw_gadget_dev_t *dev)
|
||||
{
|
||||
struct usb_raw_eps_info_s *info = &dev->eps_info;
|
||||
int i;
|
||||
|
||||
memset(info, 0, sizeof(struct usb_raw_eps_info_s));
|
||||
|
||||
dev->eps_num = host_raw_epsinfo(dev->fd, info);
|
||||
for (i = 0; i < dev->eps_num; i++)
|
||||
{
|
||||
INFO("ep #%d:", i);
|
||||
INFO(" name: %s", &info->eps[i].name[0]);
|
||||
INFO(" addr: %u", info->eps[i].addr);
|
||||
INFO(" type: %s %s %s",
|
||||
info->eps[i].caps.type_iso ? "iso" : "___",
|
||||
info->eps[i].caps.type_bulk ? "blk" : "___",
|
||||
info->eps[i].caps.type_int ? "int" : "___");
|
||||
INFO(" dir : %s %s",
|
||||
info->eps[i].caps.dir_in ? "in " : "___",
|
||||
info->eps[i].caps.dir_out ? "out" : "___");
|
||||
INFO(" maxpacket_limit: %u",
|
||||
info->eps[i].limits.maxpacket_limit);
|
||||
INFO(" max_streams: %u", info->eps[i].limits.max_streams);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
host_raw_check_epaddress(struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
struct usb_raw_eps_info_s *eps_info = &dev->eps_info;
|
||||
uint16_t ep_cnt;
|
||||
|
||||
for (ep_cnt = 0; ep_cnt < dev->eps_num; ep_cnt++)
|
||||
{
|
||||
struct usb_raw_ep_info_s *ep = &eps_info->eps[ep_cnt];
|
||||
|
||||
if (ep->addr != USB_RAW_EP_NUM(epd->bEndpointAddress) &&
|
||||
ep->addr != USB_RAW_EP_ADDR_ANY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((usb_endpoint_dir_in(epd) && !ep->caps.dir_in) ||
|
||||
(usb_endpoint_dir_out(epd) && !ep->caps.dir_out))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((usb_endpoint_type(epd) == USB_ENDPOINT_XFER_BULK &&
|
||||
!ep->caps.type_bulk) ||
|
||||
(usb_endpoint_type(epd) == USB_ENDPOINT_XFER_INT &&
|
||||
!ep->caps.type_int) ||
|
||||
(usb_endpoint_type(epd) == USB_ENDPOINT_XFER_ISOC &&
|
||||
!ep->caps.type_iso))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int host_raw_ctrlhandle(struct usb_raw_gadget_dev_t *dev,
|
||||
struct usb_raw_control_event_s *event)
|
||||
{
|
||||
struct usb_raw_ep_entry_s *entry = &dev->eps_entry[0];
|
||||
struct usb_raw_ep_io_s *io = &dev->ep0_ctrl.inner;
|
||||
struct host_usb_ctrlreq_s *host_ctrl_req;
|
||||
int ret = -1;
|
||||
|
||||
host_ctrl_req = (struct host_usb_ctrlreq_s *)
|
||||
host_raw_fifoalloc(&entry->fifo);
|
||||
|
||||
if (!host_ctrl_req)
|
||||
{
|
||||
ERROR("EP0 get raw fifo error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
host_raw_setctrlreq(host_ctrl_req, &event->ctrl);
|
||||
|
||||
if (!(event->ctrl.bRequestType & USB_DIR_IN))
|
||||
{
|
||||
io->ep = 0;
|
||||
io->flags = 0;
|
||||
io->length = USB_RAW_EP0_MAX_LEN;
|
||||
|
||||
ret = host_raw_ep0read(dev->fd, io);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("EP0 read out data error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(host_ctrl_req->data, io->data, ret);
|
||||
}
|
||||
|
||||
USB_RAW_FIFO_PUSH(&entry->fifo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *host_raw_ep0handle(void *arg)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
struct usb_raw_ep_entry_s *entry = &dev->eps_entry[0];
|
||||
struct usb_raw_control_event_s event;
|
||||
|
||||
while (dev->fd >= 0)
|
||||
{
|
||||
event.inner.type = 0;
|
||||
event.inner.length = sizeof(event.ctrl);
|
||||
if (host_raw_eventfetch(dev->fd, &event.inner) < 0)
|
||||
{
|
||||
ERROR("EP0 event fetch fail.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event.inner.type == USB_RAW_EVENT_CONNECT)
|
||||
{
|
||||
host_raw_connecthandle(dev);
|
||||
}
|
||||
else if (event.inner.type == USB_RAW_EVENT_CONTROL)
|
||||
{
|
||||
host_raw_ctrlhandle(dev, &event);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR("EP0 receive wrong event.");
|
||||
}
|
||||
}
|
||||
|
||||
host_raw_fifodelete(&entry->fifo);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *host_raw_ephandle(void *arg)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
struct usb_raw_ep_entry_s *entry = arg;
|
||||
struct usb_raw_data_io_s *io;
|
||||
|
||||
while (dev->fd >= 0)
|
||||
{
|
||||
io = (struct usb_raw_data_io_s *)
|
||||
host_raw_fifoalloc(&entry->fifo);
|
||||
|
||||
if (io)
|
||||
{
|
||||
if (entry->halted)
|
||||
{
|
||||
host_raw_epclearhalt(dev->fd, entry->raw_epid);
|
||||
entry->halted = false;
|
||||
}
|
||||
|
||||
io->inner.ep = entry->raw_epid;
|
||||
io->inner.flags = 0;
|
||||
io->inner.length = USB_RAW_EP_MAX_LEN;
|
||||
io->inner.length = host_raw_epread(dev->fd, &io->inner);
|
||||
USB_RAW_FIFO_PUSH(&entry->fifo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!entry->halted)
|
||||
{
|
||||
host_raw_epsethalt(dev->fd, entry->raw_epid);
|
||||
entry->halted = true;
|
||||
}
|
||||
|
||||
usleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
host_raw_fifodelete(&entry->fifo);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int host_usbdev_init(uint32_t speed)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
const char *device = USB_RAW_DEVICE;
|
||||
const char *driver = USB_RAW_DRIVER;
|
||||
int fd;
|
||||
|
||||
fd = host_raw_open();
|
||||
if (fd < 0)
|
||||
{
|
||||
ERROR("USB raw open error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
host_raw_init(fd, speed, driver, device);
|
||||
host_raw_run(fd);
|
||||
host_raw_vbusdraw(fd, 0x32);
|
||||
host_raw_configure(fd);
|
||||
dev->fd = fd;
|
||||
|
||||
host_raw_fifocreate(&dev->eps_entry[0].fifo,
|
||||
(sizeof(struct host_usb_ctrlreq_s)
|
||||
+ USB_RAW_EP0_MAX_LEN),
|
||||
USB_RAW_RX_BUF_NUM);
|
||||
|
||||
return pthread_create(&dev->ep0_thread, NULL,
|
||||
host_raw_ep0handle, NULL);
|
||||
}
|
||||
|
||||
int host_usbdev_deinit(void)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
host_raw_close(dev->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int host_usbdev_epconfig(uint8_t epno,
|
||||
const struct host_usb_epdesc_s *epdesc)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
struct usb_endpoint_descriptor raw_epdesc;
|
||||
struct usb_raw_ep_entry_s *entry;
|
||||
int ret = -1;
|
||||
|
||||
if (dev->fd < 0)
|
||||
{
|
||||
ERROR("USB raw not enable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (epno > USB_RAW_EPS_NUM_MAX)
|
||||
{
|
||||
ERROR("USB raw ep num error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (epdesc->mxpacketsize > USB_RAW_EP_MAX_LEN)
|
||||
{
|
||||
ERROR("USB raw ep max packet size error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
host_raw_getepdesc(&raw_epdesc, epdesc);
|
||||
|
||||
if (!host_raw_check_epaddress(&raw_epdesc))
|
||||
{
|
||||
ERROR("USB raw check ep address fail");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = host_raw_epenable(dev->fd, &raw_epdesc);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("USB raw ep enable fail");
|
||||
return ret;
|
||||
}
|
||||
|
||||
entry = &dev->eps_entry[epno];
|
||||
entry->addr = epdesc->addr;
|
||||
entry->raw_epaddr = raw_epdesc.bEndpointAddress;
|
||||
entry->raw_epid = ret;
|
||||
entry->halted = false;
|
||||
|
||||
if (USB_RAW_EP_DIR(epdesc->addr) == USB_DIR_OUT)
|
||||
{
|
||||
host_raw_fifocreate(&entry->fifo,
|
||||
sizeof(struct usb_raw_data_io_s),
|
||||
USB_RAW_RX_BUF_NUM);
|
||||
|
||||
ret = pthread_create(&entry->ep_thread, NULL,
|
||||
host_raw_ephandle,
|
||||
(void *)entry);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int host_usbdev_epdisable(uint8_t epno)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
int ret = -1;
|
||||
|
||||
if (dev->fd >= 0)
|
||||
{
|
||||
struct usb_raw_ep_entry_s *entry = &dev->eps_entry[epno];
|
||||
ret = host_raw_epdisable(dev->fd, entry->raw_epid);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int host_usbdev_pullup(bool enable)
|
||||
{
|
||||
/* not support */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int host_usbdev_epstall(uint8_t epno, bool resume)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
int ret = -1;
|
||||
|
||||
if (dev->fd >= 0)
|
||||
{
|
||||
if (!resume && epno == 0)
|
||||
{
|
||||
ret = host_raw_ep0stall(dev->fd);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int host_usbdev_epcancel(uint8_t epno)
|
||||
{
|
||||
/* not support */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int host_usbdev_epwrite(uint8_t epno, uint8_t flags,
|
||||
uint8_t *data, uint16_t len)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
struct usb_raw_ep_entry_s *entry;
|
||||
struct usb_raw_ep_io_s *io;
|
||||
int ret = -1;
|
||||
|
||||
if (dev->fd < 0)
|
||||
{
|
||||
ERROR("USB raw not enable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (epno > USB_RAW_EPS_NUM_MAX)
|
||||
{
|
||||
ERROR("USB raw ep num error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
entry = &dev->eps_entry[epno];
|
||||
|
||||
io = malloc(sizeof(struct usb_raw_ep_io_s) + len);
|
||||
if (!io)
|
||||
{
|
||||
ERROR("Host usb malloc ep write io fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
io->flags = flags;
|
||||
io->length = len;
|
||||
io->ep = entry->raw_epid;
|
||||
memcpy(io->data, data, len);
|
||||
|
||||
if (epno == 0)
|
||||
{
|
||||
ret = host_raw_ep0write(dev->fd, io);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = host_raw_epwrite(dev->fd, io);
|
||||
}
|
||||
|
||||
free(io);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t *host_usbdev_epread(uint8_t epno, uint16_t *len)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
struct usb_raw_ep_entry_s *entry;
|
||||
struct usb_raw_ep_io_s *io;
|
||||
|
||||
if (dev->fd < 0)
|
||||
{
|
||||
ERROR("USB raw not enable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (epno > USB_RAW_EPS_NUM_MAX)
|
||||
{
|
||||
ERROR("USB raw ep num error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = &dev->eps_entry[epno];
|
||||
|
||||
io = (struct usb_raw_ep_io_s *)
|
||||
host_raw_fiforead(&entry->fifo);
|
||||
if (io)
|
||||
{
|
||||
*len = io->length;
|
||||
return io->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct host_usb_ctrlreq_s *host_usbdev_ep0read(void)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
|
||||
if (dev->fd < 0)
|
||||
{
|
||||
ERROR("USB raw not enable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct host_usb_ctrlreq_s *)
|
||||
host_raw_fiforead(&dev->eps_entry[0].fifo);
|
||||
}
|
||||
|
||||
void host_usbdev_epread_end(uint8_t epno)
|
||||
{
|
||||
struct usb_raw_gadget_dev_t *dev = &g_raw_gadget_dev;
|
||||
USB_RAW_FIFO_POP(&dev->eps_entry[epno].fifo);
|
||||
}
|
@ -203,6 +203,10 @@ static int sim_loop_task(int argc, char **argv)
|
||||
sim_video_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_USB_DEV
|
||||
sim_usbdev_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MOTOR_FOC_DUMMY
|
||||
/* Update simulated FOC device */
|
||||
|
||||
@ -289,6 +293,10 @@ void up_initialize(void)
|
||||
audio_register("pcm1c", sim_audio_initialize(false, true));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_USB_DEV
|
||||
sim_usbdev_initialize();
|
||||
#endif
|
||||
|
||||
kthread_create("loop_task", SCHED_PRIORITY_MAX,
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE,
|
||||
sim_loop_task, NULL);
|
||||
|
@ -383,6 +383,13 @@ int sim_video_initialize(void);
|
||||
void sim_video_loop(void);
|
||||
#endif
|
||||
|
||||
/* sim_usbdev.c *************************************************************/
|
||||
|
||||
#ifdef CONFIG_SIM_USB_DEV
|
||||
void sim_usbdev_initialize(void);
|
||||
int sim_usbdev_loop(void);
|
||||
#endif
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
|
1154
arch/sim/src/sim/sim_usbdev.c
Normal file
1154
arch/sim/src/sim/sim_usbdev.c
Normal file
File diff suppressed because it is too large
Load Diff
87
arch/sim/src/sim/sim_usbdev.h
Normal file
87
arch/sim/src/sim/sim_usbdev.h
Normal file
@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/sim_usbdev.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_SIM_SRC_SIM_USB_DEV_H
|
||||
#define __ARCH_SIM_SRC_SIM_USB_DEV_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __SIM__
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* NuttX Endpoint descriptor */
|
||||
|
||||
struct host_usb_epdesc_s
|
||||
{
|
||||
uint8_t len; /* Descriptor length */
|
||||
uint8_t type; /* Descriptor type */
|
||||
uint8_t addr; /* Endpoint address */
|
||||
uint8_t attr; /* Endpoint attributes */
|
||||
uint16_t mxpacketsize; /* Maximum packet size */
|
||||
uint8_t interval; /* Interval */
|
||||
};
|
||||
|
||||
/* This structure is used to send control requests to a USB device. */
|
||||
|
||||
struct host_usb_ctrlreq_s
|
||||
{
|
||||
uint8_t type; /* Matches request type */
|
||||
uint8_t req; /* Matches request field */
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Host USB Interface */
|
||||
|
||||
int host_usbdev_init(uint32_t speed);
|
||||
int host_usbdev_deinit(void);
|
||||
int host_usbdev_pullup(bool enable);
|
||||
int host_usbdev_epconfig(uint8_t epno,
|
||||
const struct host_usb_epdesc_s *epdesc);
|
||||
int host_usbdev_epdisable(uint8_t epno);
|
||||
int host_usbdev_epstall(uint8_t epno, bool resume);
|
||||
int host_usbdev_epcancel(uint8_t epno);
|
||||
int host_usbdev_epwrite(uint8_t epno, uint8_t flags,
|
||||
uint8_t *data, uint16_t len);
|
||||
struct host_usb_ctrlreq_s *host_usbdev_ep0read(void);
|
||||
uint8_t *host_usbdev_epread(uint8_t epno, uint16_t *len);
|
||||
void host_usbdev_epread_end(uint8_t epno);
|
||||
|
||||
#endif /* __ARCH_SIM_SRC_SIM_USB_DEV_H */
|
@ -59,4 +59,13 @@ config SIM_WTGAHRS2_UARTN
|
||||
We can select the number according to which SIM_UARTX_NAME is used to sensor.
|
||||
This range is 0-4.
|
||||
|
||||
config SIM_RNDIS_MACADDR
|
||||
hex "RNDIS MAC address"
|
||||
default 0xfadedeadbeef
|
||||
depends on RNDIS
|
||||
---help---
|
||||
If the hardware has no built-in MAC address then the fixed,
|
||||
software-assigned MAC address MAC address must provided
|
||||
with this selection.
|
||||
|
||||
endif
|
||||
|
@ -1435,3 +1435,117 @@ wamr
|
||||
[0]crcfinal : 0xa14c
|
||||
Correct operation validated. See README.md for run and reporting rules.
|
||||
CoreMark 1.0 : 5.000000 / Clang 15.0.7 Using NuttX compilation options / Defined by the NuttX configuration
|
||||
|
||||
usbdev
|
||||
|
||||
This is a configuration with sim usbdev support.
|
||||
|
||||
1. Raw Gadget setup
|
||||
|
||||
Get Raw Gadget:
|
||||
Get Raw Gadget code at https://github.com/xairy/raw-gadget.
|
||||
|
||||
Make Raw Gadget:
|
||||
Run make in the raw_gadget and dummy_hcd directory. If raw_gadget build
|
||||
fail, you need to check which register interface meets your kenel version,
|
||||
usb_gadget_probe_driver or usb_gadget_register_driver.
|
||||
|
||||
Install Raw Gadget:
|
||||
Run ./insmod.sh in the raw_gadget and dummy_hcd directory.
|
||||
|
||||
2. Configuration
|
||||
|
||||
sim:usbdev contains two different sets of composite devices:
|
||||
conn0: adb & rndis
|
||||
conn1: cdcacm & cdcecm
|
||||
|
||||
You can use the sim:usbdev configuration:
|
||||
./tools/configure.sh sim:usbdev
|
||||
|
||||
3. How to run
|
||||
|
||||
Run nuttx with root mode, then you can use it as the following:
|
||||
|
||||
1> Run ADB:
|
||||
|
||||
NuttX enter command:
|
||||
$ conn 0
|
||||
$ adbd &
|
||||
|
||||
Host PC enter the ADB command:
|
||||
$ adb kill-server
|
||||
$ adb devices
|
||||
List of devices attached
|
||||
* daemon not running; starting now at tcp:5037
|
||||
* daemon started successfully
|
||||
0101 device
|
||||
|
||||
If ADB connection fails, make sure the udev rule is added correctly.
|
||||
Edit /etc/udev/rules.d/51-android.rules file and add the following to it:
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="1630", ATTR{idProduct}=="0042", MODE="0666", GROUP="plugdev"
|
||||
|
||||
Then you can use commands such as adb shell, adb push, adb pull as normal.
|
||||
|
||||
2> Run RNDIS:
|
||||
|
||||
NuttX enter command:
|
||||
$ conn 0
|
||||
$ ifconfig
|
||||
eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at UP
|
||||
inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0
|
||||
$ dhcpd_start eth0
|
||||
eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at UP
|
||||
inet addr:10.0.0.1 DRaddr:10.0.0.1 Mask:255.255.255.0
|
||||
|
||||
Host PC, you can see the network device named usb0:
|
||||
$ ifconfig
|
||||
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 602
|
||||
inet 10.0.0.4 netmask 255.255.255.0 broadcast 10.0.0.255
|
||||
ether 36:50:3d:62:b5:80 txqueuelen 1000 (以太网)
|
||||
RX packets 0 bytes 0 (0.0 B)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 43 bytes 8544 (8.5 KB)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
|
||||
Then you can test the network connection using the ping command or telnet.
|
||||
|
||||
3> Run CDCACM:
|
||||
|
||||
NuttX enter command:
|
||||
$ conn 1
|
||||
|
||||
If the connection is successful, you can see /dev/ttyACM devices on both NuttX
|
||||
and host PC.
|
||||
|
||||
Then you can use echo and cat command to test:
|
||||
|
||||
NuttX:
|
||||
nsh> echo hello > /dev/ttyACM0
|
||||
|
||||
Host PC:
|
||||
$ cat /dev/ttyACM0
|
||||
hello
|
||||
|
||||
3> Run CDCECM:
|
||||
|
||||
NuttX enter command:
|
||||
$ conn 1
|
||||
$ ifconfig
|
||||
eth0 Link encap:Ethernet HWaddr 00:e0:de:ad:be:ef at UP
|
||||
inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0
|
||||
$ dhcpd_start eth0
|
||||
$ ifconfig
|
||||
eth0 Link encap:Ethernet HWaddr 00:e0:de:ad:be:ef at UP
|
||||
inet addr:10.0.0.1 DRaddr:10.0.0.1 Mask:255.255.255.0
|
||||
|
||||
Host PC, you can see the network device named enx020000112233:
|
||||
$ ifconfig
|
||||
enx020000112233: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 576
|
||||
inet 10.0.0.4 netmask 255.255.255.0 broadcast 10.0.0.255
|
||||
ether 02:00:00:11:22:33 txqueuelen 1000 (以太网)
|
||||
RX packets 0 bytes 0 (0.0 B)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 58 bytes 9143 (9.1 KB)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
|
||||
Then you can test the network connection using the ping command or telnet.
|
||||
|
82
boards/sim/sim/sim/configs/usbdev/defconfig
Normal file
82
boards/sim/sim/sim/configs/usbdev/defconfig
Normal file
@ -0,0 +1,82 @@
|
||||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_SIM_UART_DMA is not set
|
||||
CONFIG_ADBD_FILE_SERVICE=y
|
||||
CONFIG_ADBD_FILE_SYMLINK=y
|
||||
CONFIG_ADBD_SHELL_SERVICE=y
|
||||
CONFIG_ADBD_USB_SERVER=y
|
||||
CONFIG_ARCH="sim"
|
||||
CONFIG_ARCH_BOARD="sim"
|
||||
CONFIG_ARCH_BOARD_SIM=y
|
||||
CONFIG_ARCH_CHIP="sim"
|
||||
CONFIG_ARCH_SIM=y
|
||||
CONFIG_BOARDCTL_POWEROFF=y
|
||||
CONFIG_BOARD_LATE_INITIALIZE=y
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CDCACM=y
|
||||
CONFIG_CDCACM_COMPOSITE=y
|
||||
CONFIG_CDCECM_COMPOSITE=y
|
||||
CONFIG_COMPOSITE_IAD=y
|
||||
CONFIG_COMPOSITE_PRODUCTID=0x0042
|
||||
CONFIG_COMPOSITE_VENDORID=0x1630
|
||||
CONFIG_DEBUG_ERROR=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_SCHED=y
|
||||
CONFIG_DEBUG_SCHED_ERROR=y
|
||||
CONFIG_DEBUG_SCHED_WARN=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEBUG_USB=y
|
||||
CONFIG_DEBUG_USB_ERROR=y
|
||||
CONFIG_DEBUG_USB_INFO=y
|
||||
CONFIG_DEBUG_USB_WARN=y
|
||||
CONFIG_DEBUG_WARN=y
|
||||
CONFIG_EXAMPLES_DHCPD=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_TMPFS=y
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_LIBC_DLFCN=y
|
||||
CONFIG_LIBUV=y
|
||||
CONFIG_NETUTILS_DHCPD=y
|
||||
CONFIG_NETUTILS_TELNETC=y
|
||||
CONFIG_NETUTILS_TELNETD=y
|
||||
CONFIG_NET_BROADCAST=y
|
||||
CONFIG_NET_CDCECM=y
|
||||
CONFIG_NET_ICMP=y
|
||||
CONFIG_NET_ICMP_SOCKET=y
|
||||
CONFIG_NET_LL_GUARDSIZE=50
|
||||
CONFIG_NET_SOCKOPTS=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_NET_UDP=y
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_PSEUDOFS_SOFTLINKS=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_READLINE_TABCOMPLETION=y
|
||||
CONFIG_RNDIS=y
|
||||
CONFIG_RNDIS_COMPOSITE=y
|
||||
CONFIG_SCHED_CHILD_STATUS=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SIM_USB_DEV=y
|
||||
CONFIG_SIM_USB_RAW_GADGET=y
|
||||
CONFIG_SYSLOG_CHARDEV=y
|
||||
CONFIG_SYSLOG_MAX_CHANNELS=2
|
||||
CONFIG_SYSTEM_ADBD=y
|
||||
CONFIG_SYSTEM_CLE=y
|
||||
CONFIG_SYSTEM_COMPOSITE=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_PING=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_TLS_TASK_NELEM=4
|
||||
CONFIG_USBADB=y
|
||||
CONFIG_USBADB_COMPOSITE=y
|
||||
CONFIG_USBDEV_COMPOSITE=y
|
||||
CONFIG_USBDEV_DUALSPEED=y
|
@ -67,4 +67,8 @@ ifeq ($(CONFIG_MOTOR_FOC_DUMMY),y)
|
||||
CSRCS += sim_foc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
|
||||
CSRCS += sim_composite.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include <nuttx/wireless/bluetooth/bt_null.h>
|
||||
#include <nuttx/wireless/bluetooth/bt_uart_shim.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_loopback.h>
|
||||
#include <nuttx/usb/adb.h>
|
||||
#include <nuttx/usb/rndis.h>
|
||||
|
||||
#ifdef CONFIG_LCD_DEV
|
||||
#include <nuttx/lcd/lcd_dev.h>
|
||||
@ -496,5 +498,22 @@ int sim_bringup(void)
|
||||
rc_dummy_initialize(0);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USBADB) && !defined(CONFIG_USBADB_COMPOSITE)
|
||||
usbdev_adb_initialize();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RNDIS) && !defined(CONFIG_RNDIS_COMPOSITE)
|
||||
/* Set up a MAC address for the RNDIS device. */
|
||||
|
||||
uint8_t mac[6];
|
||||
mac[0] = (CONFIG_SIM_RNDIS_MACADDR >> (8 * 5)) & 0xff;
|
||||
mac[1] = (CONFIG_SIM_RNDIS_MACADDR >> (8 * 4)) & 0xff;
|
||||
mac[2] = (CONFIG_SIM_RNDIS_MACADDR >> (8 * 3)) & 0xff;
|
||||
mac[3] = (CONFIG_SIM_RNDIS_MACADDR >> (8 * 2)) & 0xff;
|
||||
mac[4] = (CONFIG_SIM_RNDIS_MACADDR >> (8 * 1)) & 0xff;
|
||||
mac[5] = (CONFIG_SIM_RNDIS_MACADDR >> (8 * 0)) & 0xff;
|
||||
usbdev_rndis_initialize(mac);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
260
boards/sim/sim/sim/src/sim_composite.c
Normal file
260
boards/sim/sim/sim/src/sim_composite.c
Normal file
@ -0,0 +1,260 @@
|
||||
/****************************************************************************
|
||||
* boards/sim/sim/sim/src/sim_composite.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/adb.h>
|
||||
#include <nuttx/usb/rndis.h>
|
||||
#include <nuttx/usb/cdcacm.h>
|
||||
#include <nuttx/usb/cdcecm.h>
|
||||
#include <nuttx/usb/composite.h>
|
||||
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite0_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 0.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void *board_composite0_connect(int port)
|
||||
{
|
||||
struct composite_devdesc_s dev[2];
|
||||
int ifnobase = 0;
|
||||
int strbase = COMPOSITE_NSTRIDS - 1;
|
||||
int dev_idx = 0;
|
||||
|
||||
#ifdef CONFIG_RNDIS
|
||||
/* Configure the RNDIS USB device */
|
||||
|
||||
usbdev_rndis_get_composite_devdesc(&dev[dev_idx]);
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[dev_idx].devinfo.ifnobase = ifnobase;
|
||||
dev[dev_idx].minor = 0;
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[dev_idx].devinfo.strbase = strbase;
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[dev_idx].devinfo.epno[RNDIS_EP_BULKIN_IDX] = 1;
|
||||
dev[dev_idx].devinfo.epno[RNDIS_EP_BULKOUT_IDX] = 2;
|
||||
dev[dev_idx].devinfo.epno[RNDIS_EP_INTIN_IDX] = 5;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[dev_idx].devinfo.ninterfaces;
|
||||
strbase += dev[dev_idx].devinfo.nstrings;
|
||||
|
||||
dev_idx += 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBADB
|
||||
/* Configure the ADB USB device */
|
||||
|
||||
usbdev_adb_get_composite_devdesc(&dev[dev_idx]);
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[dev_idx].devinfo.ifnobase = ifnobase;
|
||||
dev[dev_idx].minor = 0;
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[dev_idx].devinfo.strbase = strbase;
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[dev_idx].devinfo.epno[USBADB_EP_BULKIN_IDX] = 6;
|
||||
dev[dev_idx].devinfo.epno[USBADB_EP_BULKOUT_IDX] = 7;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[dev_idx].devinfo.ninterfaces;
|
||||
strbase += dev[dev_idx].devinfo.nstrings;
|
||||
|
||||
dev_idx += 1;
|
||||
#endif
|
||||
|
||||
return composite_initialize(dev_idx, dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite1_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 1.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void *board_composite1_connect(int port)
|
||||
{
|
||||
struct composite_devdesc_s dev[2];
|
||||
int ifnobase = 0;
|
||||
int strbase = COMPOSITE_NSTRIDS - 1;
|
||||
int dev_idx = 0;
|
||||
|
||||
#ifdef CONFIG_CDCACM
|
||||
/* Configure the CDC/ACM device */
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[dev_idx]);
|
||||
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[dev_idx].classobject = cdcacm_classobject;
|
||||
dev[dev_idx].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[dev_idx].devinfo.ifnobase = ifnobase;
|
||||
dev[dev_idx].minor = 0;
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[dev_idx].devinfo.strbase = strbase;
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[dev_idx].devinfo.epno[CDCACM_EP_INTIN_IDX] = 5;
|
||||
dev[dev_idx].devinfo.epno[CDCACM_EP_BULKIN_IDX] = 6;
|
||||
dev[dev_idx].devinfo.epno[CDCACM_EP_BULKOUT_IDX] = 7;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[dev_idx].devinfo.ninterfaces;
|
||||
strbase += dev[dev_idx].devinfo.nstrings;
|
||||
|
||||
dev_idx += 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_CDCECM
|
||||
/* Configure the CDC/ECM device */
|
||||
|
||||
cdcecm_get_composite_devdesc(&dev[dev_idx]);
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[dev_idx].devinfo.ifnobase = ifnobase;
|
||||
dev[dev_idx].minor = 0;
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[dev_idx].devinfo.strbase = strbase;
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[dev_idx].devinfo.epno[CDCECM_EP_INTIN_IDX] = 10;
|
||||
dev[dev_idx].devinfo.epno[CDCECM_EP_BULKIN_IDX] = 11;
|
||||
dev[dev_idx].devinfo.epno[CDCECM_EP_BULKOUT_IDX] = 12;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[dev_idx].devinfo.ninterfaces;
|
||||
strbase += dev[dev_idx].devinfo.nstrings;
|
||||
|
||||
dev_idx += 1;
|
||||
#endif
|
||||
|
||||
return composite_initialize(dev_idx, dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_initialize
|
||||
*
|
||||
* Description:
|
||||
* Perform architecture specific initialization of a composite USB device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int board_composite_initialize(int port)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void *board_composite_connect(int port, int configid)
|
||||
{
|
||||
if (configid == 0)
|
||||
{
|
||||
return board_composite0_connect(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
return board_composite1_connect(port);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
@ -505,6 +505,22 @@ static const char *g_white_list[] =
|
||||
|
||||
"NimMain",
|
||||
|
||||
/* Ref:
|
||||
* sim/posix/sim_rawgadget.c
|
||||
*/
|
||||
|
||||
"bRequestType",
|
||||
"bRequest",
|
||||
"wValue",
|
||||
"wIndex",
|
||||
"wLength",
|
||||
"bLength",
|
||||
"bDescriptorType",
|
||||
"bEndpointAddress",
|
||||
"bmAttributes",
|
||||
"wMaxPacketSize",
|
||||
"bInterval",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user