Coder Social home page Coder Social logo

cherry-embedded / cherryusb Goto Github PK

View Code? Open in Web Editor NEW
1.0K 33.0 218.0 55.85 MB

CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP

Home Page: https://cherryusb.readthedocs.io/

License: Apache License 2.0

C 98.77% Python 0.60% CMake 0.63%
usb-host usb-device usb cdc hid uvc uac dfu ehci hub rndis musb dwc2 xhci cherryusb cdns2 cdns3 ohci

cherryusb's Introduction

CherryUSB

中文版

CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP.

CherryUSB

Why choose

Easy to study USB

In order to make it easier for users to learn USB basics, enumeration, driver loading and IP drivers, the code has been written with the following advantages:

  • Lean code, simple logic, no complex C syntax
  • Tree-based programming with cascading code
  • Class-drivers and porting-drivers are templating and simplification
  • Clear API classification (slave: initialisation, registration api, command callback api, data sending and receiving api; host: initialisation, lookup api, data sending and receiving api)

Easy to use USB

In order to facilitate the use of the USB interface and to take into account the fact that users have learned about uart and dma, the following advantages have been designed for the data sending and receiving class of interface:

  • Equivalent to using uart tx dma/uart rx dma
  • There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does the packetization process)

Easy to bring out USB performance

Taking into account USB performance issues and trying to achieve the theoretical bandwidth of the USB hardware, the design of the data transceiver class interface has the following advantages:

  • Porting drivers directly to registers, no abstraction layer encapsulation
  • Memory zero copy
  • If IP has DMA then uses DMA mode (DMA with hardware packetization)
  • Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
  • Subcontracting function is handled in interrupt

Directoy Structure

.
├── class
├── common
├── core
├── demo
├── docs
├── osal
├── packet capture
└── port
└── tools

Directory Description
class usb class driver
common usb spec macros and utils
core usb core implementation
demo different chips demo
osal os wrapper
docs doc for guiding
port usb dcd and hcd porting
tools tool url

Device Stack Overview

CherryUSB Device Stack provides a unified framework of functions for standard device requests, CLASS requests, VENDOR requests and custom special requests. The object-oriented and chained approach allows the user to quickly get started with composite devices without having to worry about the underlying logic. At the same time, a standard dcd porting interface has been standardised for adapting different USB IPs to achieve ip-oriented programming.

CherryUSB Device Stack has the following functions:

  • Support USB2.0 full and high speed, USB3.0 super speed
  • Support endpoint irq callback register by users, let users do whatever they wants in endpoint irq callback.
  • Support Composite Device
  • Support Communication Device Class (CDC_ACM, CDC_ECM)
  • Support Human Interface Device (HID)
  • Support Mass Storage Class (MSC)
  • Support USB VIDEO CLASS (UVC1.0、UVC1.5)
  • Support USB AUDIO CLASS (UAC1.0、UAC2.0)
  • Support Device Firmware Upgrade CLASS (DFU)
  • Support USB MIDI CLASS (MIDI)
  • Support Remote NDIS (RNDIS)
  • Support WINUSB1.0、WINUSB2.0(with BOS)
  • Support Vendor class
  • Support multi device with the same USB IP

CherryUSB Device Stack resource usage (GCC 10.2 with -O2):

file FLASH (Byte) No Cache RAM (Byte) RAM (Byte) Heap (Byte)
usbd_core.c 3516 256(default) + 320 0 0
usbd_cdc.c 392 0 0 0
usbd_msc.c 2839 128 + 512(default) 16 0
usbd_hid.c 364 0 0 0
usbd_audio.c 1455 0 0 0
usbd_video.c 2494 0 84 0
usbd_rndis.c 2109 3340 76 0

Host Stack Overview

The CherryUSB Host Stack has a standard enumeration implementation for devices mounted on roothubs and external hubs, and a standard interface for different Classes to indicate what the Class driver needs to do after enumeration and after disconnection. A standard hcd porting interface has also been standardised for adapting different USB IPs for IP-oriented programming. Finally, the host stack is managed using os, and provides osal to make a adaptation for different os.

CherryUSB Host Stack has the following functions:

  • Automatic loading of supported Class drivers
  • Support blocking transfers and asynchronous transfers
  • Support Composite Device
  • Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2 and ehci now)
  • Support Communication Device Class (CDC_ACM, CDC_ECM)
  • Support Human Interface Device (HID)
  • Support Mass Storage Class (MSC)
  • Support USB Video CLASS (commercial charge)
  • Support USB Audio CLASS (commercial charge)
  • Support Remote NDIS (RNDIS)
  • Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support CLASS:0xE0 or vendor class like cdc acm)
  • Support Vendor class
  • Support USB modeswitch
  • Support multi host with the same USB IP

The CherryUSB Host stack also provides the lsusb function, which allows you to view information about all mounted devices, including those on external hubs, with the help of a shell plugin.

CherryUSB Host Stack resource usage (GCC 10.2 with -O2):

file FLASH (Byte) No Cache RAM (Byte) RAM (Byte) Heap (Byte)
usbh_core.c ~7700 512 + 8 * (1+x) *n 28 0
usbh_hub.c ~5600 32 + 4* (1+x) 12 + sizeof(struct usbh_hub) * (1+x) 0
usbh_cdc_acm.c ~1200 7 4 + sizeof(struct usbh_cdc_acm) * x 0
usbh_msc.c ~2500 32 4 + sizeof(struct usbh_msc) * x 0
usbh_hid.c ~1000 128 4 + sizeof(struct usbh_hid) * x 0
usbh_video.c ~3700 128 4 + sizeof(struct usbh_video) * x 0
usbh_audio.c ~3100 128 4 + sizeof(struct usbh_audio) * x 0
usbh_rndis.c ~3900 4096 + 2 * 2048 sizeof(struct usbh_rndis) * 1 0
usbh_cdc_ecm.c ~2500 2 * 1514 sizeof(struct usbh_cdc_ecm) * 1 0
usbh_bluetooth.c ~2300 2 * 2048(default) sizeof(struct usbh_bluetooth) * 1 0

Among them, sizeof(struct usbh_hub) and sizeof(struct usbh_hubport) are affected by the following macros:

#define CONFIG_USBHOST_MAX_EXTHUBS          1
#define CONFIG_USBHOST_MAX_EHPORTS          4
#define CONFIG_USBHOST_MAX_INTERFACES       8
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
#define CONFIG_USBHOST_MAX_ENDPOINTS        4

x is affected by the following macros:

#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
#define CONFIG_USBHOST_MAX_HID_CLASS     4
#define CONFIG_USBHOST_MAX_MSC_CLASS     2
#define CONFIG_USBHOST_MAX_AUDIO_CLASS   1
#define CONFIG_USBHOST_MAX_VIDEO_CLASS   1

USB IP Support

Only standard and commercial USB IP are listed.

IP device host Support status
OHCI(intel) none OHCI ×
EHCI(intel) none EHCI
XHCI(intel) none XHCI
UHCI(intel) none UHCI ×
DWC2(synopsys) DWC2 DWC2
MUSB(mentor) MUSB MUSB
FOTG210(faraday) FOTG210 EHCI
CDNS2(cadence) CDNS2 CDNS2
CDNS3(cadence) CDNS3 XHCI ×
DWC3(synopsys) DWC3 XHCI ×

Documentation Tutorial

Quickly start, USB basic concepts, API manual, Class basic concepts and examples, see CherryUSB Documentation Tutorial

Video Tutorial

USB basic concepts and how the CherryUSB Device stack is implemented, see CherryUSB Device Stack Tutorial.

Graphical Config Tool

chryusb_configurator is written in electron + vite2 + ts framework,currently used to automate the generation of descriptor arrays, with additional functionality to be added later.

Demo Repo

Manufacturer CHIP or Series USB IP Repo Url Support version Support status
Bouffalolab BL702/BL616/BL808 bouffalolab/ehci bouffalo_sdk <= latest Long-term
ST STM32F1x fsdev stm32_repo <= latest Long-term
ST STM32F4/STM32H7 dwc2 stm32_repo <= latest Long-term
HPMicro HPM6750 hpm/ehci hpm_sdk <= latest Long-term
Essemi ES32F36xx musb es32f369_repo <= latest Long-term
Phytium e2000 pusb2/xhci phytium_repo v0.10.2 Long-term
artinchip d12x/d13x/d21x dwc2/ehci/ohci luban-lite <= latest Long-term
Espressif esp32s2/esp32s3 dwc2 esp32_repo <= latest the same with ST
AllwinnerTech F1C100S/F1C200S musb cherryusb_rtt_f1c100s <= latest the same with Essemi
WCH CH32V307/ch58x ch32_usbfs/ch32_usbhs/ch58x wch_repo <= v0.10.2 TBD
Nordicsemi Nrf52840 nrf5x nrf5x_repo <= v0.10.2 No more updated
Raspberry pi rp2040 rp2040 pico-examples <= v0.10.2 No more updated

Contact

CherryUSB discord: https://discord.com/invite/wFfvrSAey8.

Company Support

Thanks to the following companies for their support (in no particular order).

cherryusb's People

Contributors

aozima avatar candyaria avatar chenzhihong007 avatar egahp avatar fanhuacloud avatar geniusgogo avatar gragiu avatar haimianbbao avatar helloeagleyang avatar heyuanjie87 avatar huckies avatar liuhy-2020 avatar myxiaonia avatar rcsn avatar rrrrrrobot avatar saisesai avatar sakumisu avatar sakumisue avatar ttnwosay avatar xiaoxiaohuixxh avatar xmaowu avatar zhaofx1234 avatar zhugengyu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cherryusb's Issues

v0.5.0 Preview(mainly for dcd)

  • Refactor dcd api, only use async functions to match for os.
  • Refactor dcd out callback from out data irq to out data transfer done irq(like uart recv irq to uart rx dma irq)
  • Add nbytes para that means number of bytes correctly transferred for ep callback

[E/USB] ep:86 clear halt

stm32f103c8t6
demo\cdc_acm_hid_msc_template.c
need modify usb_dc_fsdev.c USB_RAM_SIZE to 1024

#ifndef USB_RAM_SIZE
#define USB_RAM_SIZE 512
#endif

and hid endpoint get errors
USB_REQUEST_CLEAR_FEATURE:
[E/USB] ep:86 clear halt

导致hid设备出现感叹号,这个应该如何解决

USB Host多个HID设备该如何处理?

查看USB Host的示例代码 看起来每个类型的设备是支持了一个设备 如果想要支持多个相同类型的设备该如何处理呢? 我看usbx和tinyusb都是自动枚举 然后根据地址回调的

usb hub 多次枚举导致 No memory to alloc hub class

测试STM32F407的USB主机模式的时候使用USB延长线连接hub,导致usb线非常的长,如果先将hid接入到hub再接入控制器中,不会有问题;如果先将hub接入控制器,再将hid接入hub,则会出现
image
跟踪调试之后发现,在后一种情况下,hid接入hub时,再中断函数中检查 USB_OTG_HPRT 寄存器值为 0x00021008,之后唤醒 usb-hub线程进行事件处理,在 usb-hub 线程中再次读取 USB_OTG_HPRT 寄存器值为 0x00021401,状态再次变成上电,导致hub设备在没有调用 CLASS_DISCONNECT 的情况下再次调用 CLASS_CONNECT,引发 No memory to alloc hub class 错误,并且再次拔插USB也无法恢复,必须重启stm32

USB HID device stays in infinite loop when key pressed, when there is no USB support...

...when plugged in to powered off computer (or restarting from working both computer and USB stack). After computer startup, stack initialises at BIOS USB and repetitive key pressing causes:

while (hid_state == HID_STATE_BUSY) {
}

in hid_keyboard_template.c to loop to infinity and beyond when key pressed between BIOS and OS loading, where is no USB host.
Changing it to:

void send_report(uint8_t rep_id, uint8_t modifier, uint8_t key_code)
{
   uint8_t sendbuffer[9] = {rep_id, modifier, 0x00, key_code, 0x00, 0x00, 0x00, 0x00, 0x00};
   int ret = usbd_ep_start_write(HID_INT_EP, sendbuffer, 9);
   if (ret < 0) {
      return;
   }
   hid_state = HID_STATE_BUSY;
   // enough is enough - max time to proceed
   uint64_t start;
   uint64_t duration = 0;
   start = time_us_64();
   while (hid_state == HID_STATE_BUSY && duration < 100000) {
      duration = time_us_64() - start;
   }
}

solves the issue. And it happens on Pico or Pico W.

ch32v307 cdc aсm

Tried your cdc acm example for my ch32v307 chip. On Linux, there are problems with registering a usb device:

[597460.594304] usb 1-6: new high-speed USB device number 68 using xhci_hcd
[597460.722349] usb 1-6: device descriptor read/64, error 18
[597460.958271] usb 1-6: device descriptor read/64, error 18
[597461.198248] usb 1-6: new high-speed USB device number 69 using xhci_hcd
[597461.326338] usb 1-6: device descriptor read/64, error 18
[597461.562305] usb 1-6: device descriptor read/64, error 18
[597461.670409] usb usb1-port6: attempt power cycle
[597462.086277] usb 1-6: new high-speed USB device number 70 using xhci_hcd
[597462.110555] usb 1-6: device descriptor read/8, error -61
[597462.242559] usb 1-6: device descriptor read/8, error -61

If you use CherryUSB from this old repository, then everything works:

[597604.323505] usb 1-6: new high-speed USB device number 72 using xhci_hcd
[597604.471899] usb 1-6: New USB device found, idVendor=ffff, idProduct=ffff, bcdDevice= 1.00
[597604.471905] usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[597604.471909] usb 1-6: Product: CherryUSB CDC DEMO
[597604.471912] usb 1-6: Manufacturer: CherryUSB
[597604.471915] usb 1-6: SerialNumber: 2022123456
[597604.477337] cdc_acm 1-6:1.0: ttyACM1: USB ACM device

Why is this happening?

Multi port support

v0.10.0 版本将会是最后一个单port的版本,后续将会支持多port,每个port可以ip一样也可以不一样。

v0.10.0 will be the last single port release, and later multiple ports will be supported, each with the same or different ips.

Can you please point me to a BL702 Host example [HID]?

HI,

I'm interested in using this library in order to utilise a USB keyboard with a BL702 acting as the host, with a view to outputting keystrokes over uart as ascii - is there an example of such functionality that already exists that you might please point me to? Thanks!

Endpoint index is not validated in some port functions

The endpoint index passed into some of the port functions is not validated. The most important example of this would be when handling a standard endpoint request, as the endpoint can be specified by the wIndex field of the usb_setup_packet. This is then passed directly to usbd_ep_set_stall and usbd_ep_clear_stall implementation which can result in accessing unintended memory.

As an example I've listed below the usbd_std_endpoint_req_handler from usbd_core.c and the usbd_ep_clear_stall usbd_ep_set_stall implementations from usb_dc_dwc2.c. This seems to be a common issue throughout various ports though and is not specific to the dwc2 port.

static bool usbd_std_endpoint_req_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
{
    uint8_t ep = (uint8_t)setup->wIndex;
    bool ret = true;

    /* Only when device is configured, then endpoint requests can be valid. */
    if (!is_device_configured()) {
        return false;
    }

    switch (setup->bRequest) {
        case USB_REQUEST_GET_STATUS:
            (*data)[0] = 0x00;
            (*data)[1] = 0x00;
            *len = 2;
            break;
        case USB_REQUEST_CLEAR_FEATURE:
            if (setup->wValue == USB_FEATURE_ENDPOINT_HALT) {
                USB_LOG_ERR("ep:%02x clear halt\r\n", ep);

                usbd_ep_clear_stall(ep);                                                            // [1] Passes setup->wIndex to port implementation
                break;
            } else {
                ret = false;
            }
            *len = 0;
            break;
        case USB_REQUEST_SET_FEATURE:
            if (setup->wValue == USB_FEATURE_ENDPOINT_HALT) {
                USB_LOG_ERR("ep:%02x set halt\r\n", ep);

                usbd_ep_set_stall(ep);                                                            // [2] Passes setup->wIndex to port implementation
            } else {
                ret = false;
            }
            *len = 0;
            break;

        case USB_REQUEST_SYNCH_FRAME:
            ret = false;
            break;
        default:
            ret = false;
            break;
    }

    return ret;
}

// in the below implementations ep is not verified against the actual number of endpoints before being used.

int usbd_ep_clear_stall(const uint8_t ep)
{
    uint8_t ep_idx = USB_EP_GET_IDX(ep);
    if (USB_EP_DIR_IS_OUT(ep)) {
        USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
        if ((g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
            (g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
            USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
        }
    } else {
        USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
        if ((g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
            (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
            USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
        }
    }
    return 0;
}

int usbd_ep_set_stall(const uint8_t ep)
{
    uint8_t ep_idx = USB_EP_GET_IDX(ep);

    if (USB_EP_DIR_IS_OUT(ep)) {
        if (((USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
            USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
        }
        USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
    } else {
        if (((USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
            USB_OTG_INEP(ep_idx)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
        }
        USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
    }
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
    if (ep_idx == 0) {
        dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
    }
#endif
    return 0;
}

关于USB转换芯片MAX3421E的协议栈移植问题

由于使用的芯片没有USB主机功能,增加了一个美信的MAX3421E芯片,将SPI转USB,但是该芯片不提供协议栈,只有基础的驱动程序。MAX3421E的寄存器和通常的MCU USB IP寄存器不一样,不知道能否移植这个协议栈使用?
看了下这个协议栈的移植例程,似乎是需要自己实现usb_dc_xxx层的驱动,为usbh_core.c提供接口函数,那么是否可以在usb_dc_xxx中直接对MAX3421E驱动的USB传输函数进行二次封装,而不实现寄存器映射表?
如果能提供一些建议,将不胜感激!

usb_hc_dwc2.c 文件中出现异常时没有释放锁导致死锁

在 usb_hc_dwc2.c 文件下的 usbh_submit_urb函数中
`
int usbh_submit_urb(struct usbh_urb *urb)
{
struct dwc2_pipe *chan;
size_t flags;
int ret = 0;

if (!urb) {
    return -EINVAL;
}

chan = urb->pipe;

if (!chan) {
    return -EINVAL;
}

/* dma addr must be aligned 4 bytes */
if ((((uint32_t)urb->setup) & 0x03) || (((uint32_t)urb->transfer_buffer) & 0x03)) {
    return -EINVAL;
}

flags = usb_osal_enter_critical_section();

if (!chan->hport->connected) {
    return -ENODEV;
}

if (chan->urb) {
    return -EBUSY;
}

chan->waiter = false;
chan->xfrd = 0;
chan->urb = urb;
urb->errorcode = -EBUSY;
urb->actual_length = 0;

if (urb->timeout > 0) {
    chan->waiter = true;
}
usb_osal_leave_critical_section(flags);

switch (chan->ep_type) {
    case USB_ENDPOINT_TYPE_CONTROL:
        chan->ep0_state = DWC2_EP0_STATE_SETUP;
        dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
        break;
    case USB_ENDPOINT_TYPE_BULK:
    case USB_ENDPOINT_TYPE_INTERRUPT:
        dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
        break;
    case USB_ENDPOINT_TYPE_ISOCHRONOUS:
        chan->iso_frame_idx = 0;
        dwc2_iso_pipe_init(chan, &urb->iso_packet[chan->iso_frame_idx]);
        break;
    default:
        break;
}
if (urb->timeout > 0) {
    /* wait until timeout or sem give */
    ret = usb_osal_sem_take(chan->waitsem, urb->timeout);
    if (ret < 0) {
        goto errout_timeout;
    }

    ret = urb->errorcode;
}
return ret;

errout_timeout:
chan->waiter = false;
usbh_kill_urb(urb);
return ret;
}
`
if (!chan->hport->connected) 和 if (urb->timeout > 0)条件下不会调用 usb_osal_leave_critical_section(flags); ,导致在某些异常情况下死锁

Porting copyright issue

@sakumisu 您好,
如果移植CherryUSB到一个SDK中,请问作者对license和copyright有什么要求吗?我看readme也没有特别提及。

望回复,谢谢!

控制传输暂停后,之后的控制传输将一直错误

使用PC与STM32H7通信,PC使用libusb,在设置上打个断点,然后启动PC控制传输,等待PC报错返回,然后放开断点,设备全速运行,之后PC再次进行控制请求,PC显示无法正确请求数据,多次尝试都是如此。批量传输无此问题

v0.2.0 beta Preview

  • Repo name change,from usb_stack to CherryUSB
  • Add usb host stack
  • Add ehci and synopsys hcd support.
  • Add CherryUSB configurator.

RT Thread + LwIP + RNDIS 例程

请问作者有RT Thread + LwIP + RNDIS 的例程吗

我在RT Thread Studio建了CH32V307工程,使能了LWIP+CherryUSB CDC RNDIS
Ram, Flash 改成 128KB 192KB
然后用cdc_rndis_template.c
可是运行后没有反应,按暂停时停在hardfault

Class 的注册方式能使用数组吗?

Class的注册使用编译进内存的方式在不同编译器下移植起来太麻烦了,对编译原理和内存分区理解不够,能有一个分支用数组的方式实现吗?将Class的句柄加进数组就是注册。
我尝试改了一下,但是似乎哪里出了点问题。

STM32f401. Failed to get device descriptor,errorcode:-116

I'm trying to make usb host on the stm32f401ccu6. This error occurs when connecting a usb device. I'm using CubeIDE. My code is copied from the stm32f429igt6 example. I followed the steps according to the guide.
That's all I did.

sakumisu, thanks for the great work! I hope the issue can be resolved

stm32f107 dwc2 rndis device

I tried to run rndis with lwip on stm32f107. The device is detected, windows receives an ip address and a gateway via dhcp, but network manager freezes and it is impossible to turn on the network interface.
What am I doing wrong?

  • Im defined:
#define CONFIG_USBDEV_RNDIS_USING_LWIP
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256

#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128
#endif

#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1536
#endif

#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
#endif

#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
#endif
  • Wrote initialization functions:
static struct usbd_interface intf0;
static struct usbd_interface intf1;
static uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

void cdc_rndis_init(void)
{
    usbd_desc_register(cdc_descriptor);
    usbd_add_interface(usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
    usbd_add_interface(usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
    usbd_initialize();
}

void usb_dc_low_level_init(void)
{
	 __HAL_RCC_GPIOA_CLK_ENABLE();
	  GPIO_InitTypeDef GPIO_InitStruct = {0};
		
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
   __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
	 
   HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
}

void usb_dc_low_level_deinit(void)
{
	 __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
   HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
}
  • And lwip initialization:
static struct netif rndis_netif; //network interface

static const ip_addr_t ipaddr  = IPADDR4_INIT_BYTES(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
static const ip_addr_t netmask = IPADDR4_INIT_BYTES(NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
static const ip_addr_t gateway = IPADDR4_INIT_BYTES(GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);

err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *ipaddr)
{
    return etharp_output(netif, p, ipaddr);
}

err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
{
	static int ret;
	ret = usbd_rndis_eth_tx(p);
	
	if(ret == 0)
		return ERR_OK;
	else
		return ERR_BUF;
}

err_t rndisif_init(struct netif *netif)
{
    LWIP_ASSERT("netif != NULL", (netif != NULL));
    netif->mtu = 1500;
    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
    netif->state = NULL;
    netif->name[0] = IFNAME0;
    netif->name[1] = IFNAME1;
    netif->output = output_fn;
    netif->linkoutput = linkoutput_fn;
    return ERR_OK;
}

err_t rndisif_input(struct netif *netif)
{
	static err_t err;
	static struct pbuf *p;
	p = usbd_rndis_eth_rx();
	if(p != NULL)
	{
		err = netif->input(p, netif);
		if(err != ERR_OK)
		{
			pbuf_free(p);
		}
	}
	else
	{
		return ERR_BUF;
	}
  return err;
}

#define NUM_DHCP_ENTRY 3

static dhcp_entry_t entries[NUM_DHCP_ENTRY] =
{
    /* mac    ip address        subnet mask        lease time */
    { {0}, {192, 168, 17, 2}, {255, 255, 255, 0}, 24 * 60 * 60 },
    { {0}, {192, 168, 17, 3}, {255, 255, 255, 0}, 24 * 60 * 60 },
    { {0}, {192, 168, 17, 4}, {255, 255, 255, 0}, 24 * 60 * 60 }
};

static dhcp_config_t dhcp_config =
{
    {192, 168, 17, 1}, 67, /* server address, port */
    {192, 168, 17, 1},     /* dns server */
    "stm",                /* dns suffix */
    NUM_DHCP_ENTRY,       /* num entry */
    entries               /* entries */
};

uint32_t dns_query_proc(const char *name, ip_addr_t *addr)
{
    if (strcmp(name, "run.stm") == 0 || strcmp(name, "www.run.stm") == 0)
    {
        addr->addr = ipaddr.addr;
        return 1;
    }
    return 0;
}

void LwIP_Init(void)
{
    struct netif  *netif = &rndis_netif;

    lwip_init();

    netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, rndisif_init, ethernet_input);
    netif_set_default(netif);
	dhserv_init(&dhcp_config);
	dnserv_init(&ipaddr, PORT_DNS, dns_query_proc);
}

/**
* @brief  Called when a frame is received
* @param  None
* @retval None
*/
void LwIP_Pkt_Handle(void)
{
  /* Read a received packet from the buffers and send it to the lwIP for handling */
  rndisif_input(&rndis_netif);
	//netif_is_up(&rndis_netif);
}

I call the LwIP_Pkt_Handle function in the while loop.

GD32 dwc2驱动的GCCFG_NOVBUSSENS寄存器兼容性和stm32存在区别

虽然dwc2的文档里面写的支持GD32F30X_CL, 但在GD32305R-START(GD32F30X_CL)的开发板上测试的时候连电脑识别失败

和gd32的官方的代码对比了下, 发现不开CONFIG_DWC2_VBUS_SENSING_ENABLE的时候, gd32即使设置了USB_OTG_GCCFG_NOVBUSSENS, 也必须设置USB_OTG_GCCFG_VBUSASEN/_VBUSBSEN才能正常工作(gd32官方驱动这里就和stm32的有区别, gd32官方设置的是两个都设置了, 实测设置至少其一就能工作, 不知道a和b啥区别, stm32是两个都取消了)
(另参考http://www.elmagnifico.tech/2021/06/21/CUBEMX-GD32F450-USB/#usbfs_gccfg)

https://github.com/sakumisu/CherryUSB/blob/f1a5345f26c645e2e1d30dbccb0eee19490e0619/port/dwc2/usb_dc_dwc2.c#L574-L580
虽然没用但怀疑usb_hc_dwc2也是一样的
这里希望能加个宏定义或者在USB IP 勘误文档中给个说明

    #ifdef CONFIG_DWC2_GD32
    USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_VBUSASEN | USB_OTG_GCCFG_VBUSBSEN;
    #else
    USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
    USB_OTG_GLB->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
    #endif

stm32f0系列单片机枚举失败

尝试在stm32f072上测试,发现以下问题:
需要实现int usb_dc_attach(void);
同时在头文件中追加相关函数。
在做了上面的修改之后电脑可以发现usb设备,
但是枚举失败,提示获取不了设备描述符

lsusb -v cdc device

Every time I do this on Linux:
lsusb -v

Then a log appears on my device:

[E/USB] descriptor <type:6,index:0> not found!
[E/USB] standard request error
[E/USB] standard request error

On Linux, this is the output of my device:

Bus 001 Device 061: ID 1a86:fe0c QinHeng Electronics Validator
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x1a86 QinHeng Electronics
  idProduct          0xfe0c 
  bcdDevice            1.00
  iManufacturer           1 TTT
  iProduct                2 TTTTTTTTT
  iSerial                 3 E339E33917A5383B2662B908
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x004b
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       1 AT-commands (v.25ter)
      iFunction               0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              2 Validator
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x00
        bDataInterface          1
      CDC ACM:
        bmCapabilities       0x02
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              16
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0000
  (Bus Powered)

The project has a device qualifier descriptor and define CONFIG_USB_HS:

#ifdef CONFIG_USB_HS
    ///////////////////////////////////////
    /// device qualifier descriptor
    ///////////////////////////////////////
    0x0a,
    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
    0x00,
    0x02,
    0x02,
    0x02,
    0x01,
    0x40,
    0x01,
    0x00,
#endif
    0x00

In fact, I did not change anything in the descriptor, except for: vid, pid and 3 string . The sizes of string correctly counted

USB-MTP(Media Transfer Protocol)

是否考虑增加 MTP?

设备需要通过USB与PC进行文件传输,目前有两种方案
1、使用大容量存储(MSC)
使用MSC需要配合FAT文件系统, 由于FAT没有擦写均衡以及掉电保护,不适合用于设备中。

2、使用MTP
可以兼顾文件系统的性能以及与PC交互的便捷性,目前看一些USB协议栈好像都没支持这种class,不知道是难度太大还是需求太少。

Register GCCFG in synopsys ip has confused in ST, if you have problems in enumeration, read this.

Bit21 in GCCFG register is not the same in some chips of stm32, they both indicate the same purpose: disable vbus sensing, but some chips should clear this bit and some otherwise, so fixed it with #if 1 or #if 0 in commit 6180db5d, codes are as follows:

#if 1 /* To fix vbus sensing disable*/
    /* Deactivate VBUS Sensing B */
    USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;

    /* B-peripheral session valid override enable */
    USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
    USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
#else
    USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
    USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
    USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
#endif

枚举异常后,再拔出设备,内存释放异常

cherryusb做host,枚举设备,当设备内裤失败,退出,会调用CLASS DISCONNECT,此时,再拔出设备,依然会调用CLASS DISCONNECT,目前很多设备的disconnect函数,如果被调用多次,并且是同一个interface,会出现同一块内存多次释放的问题,建议在设备disconnect中,释放内存后,设置NULL,避免重复释放,或者内裤失败,不调用disconnect?

cmsis-dap_v2.1_tempate.c

我正在stm32f103cb上制作一个daplink, 然后希望之后能平滑移植到其他mcu平台
我已经完成了cdc的功能, 已经可以连接msh
但是使用了cmsis-dap_v2.1_tempate.c之后出了一些问题
比如初始化的时候:
[I/USB] Setup: bmRequestType 0x80, bRequest 0x06, wValue 0x0600, wIndex 0x0000, wLength 0x000a
[I/USB] Open endpoint:0x81 type:2 mps:64
[I/USB] Open endpoint:0x2 type:2 mps:64
[I/USB] Open endpoint:0x85 type:3 mps:8
[E/USB] Ep addr 133 overflow
[I/USB] Open endpoint:0x4 type:2 mps:64
[E/USB] Ep addr 4 overflow
[I/USB] Open endpoint:0x83 type:2 mps:64
[I/USB] get Compat ID
[I/USB] get Compat ID
cdc我在使用cdc_acm_template.c时调试通过, 但是在使用daplink的cdc时,一旦pc连接串口,就会不停的上报错误:
[E/USB] ep:85 clear halt
[E/USB] ep:85 clear halt
[E/USB] ep:85 clear halt
[E/USB] ep:85 clear haltt
断开串口的连接错误终止, 不知道是我哪里的使用有问题?
https://cherryusb.readthedocs.io/zh_CN/latest/index.html 在文档中也没有找到相关的介绍内容

Synopsys/EHCI/OHCI support

@sakumisu 您好,有几个问题请教一下:
1)CherryUSB软件包是否是独立于RT-Thread原生自带的USB驱动框架,即单独打开软件包即可使用,不需要打开RT-Thread的components/drivers/usb?
2)CherryUSB中所支持的Synopsys IP,是DesignWare HS OTG Controller吗?若是,是否已支持高速host和高速device?(我目前在跑Linux,用的是原生的dwc2的驱动)
3)CherryUSB中已支持EHCI,但未支持OHCI,是否意味着类似全志的SoC中支持标准EHCI/OHCI的USB host暂时无法使用全速/低速设备(如USB鼠标/键盘等)?

希望能得到解答,谢谢!

OTG over USB/IP

Hi!

I am very excited to find this project.

I am trying to emulate USB MSD over USB/IP via ESP32. The end goal would be multiple Raspberry Pis, with ESP32's connected to their USB ports. The ESP32 would be available over USB/IP and then I would be able to use gadgetfs to configure the MSD to serve up over OTG.

Is this possible? I do not have experience with ESP-IDF, etc. I would be very thankful for any help, I might be able to donate some money if it would help too.

ubuntu系统下,git clone后,直接git diff会提示CRLF 将被 LF 替换

warning: class/audio/usbd_audio.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/cdc/usbd_cdc.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/cdc/usbh_cdc_acm.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/cdc/usbh_cdc_acm.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/hid/usbd_hid.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/hid/usbh_hid.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/hid/usbh_hid.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/hub/usbh_hub.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/hub/usbh_hub.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/msc/usbd_msc.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/msc/usbh_msc.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/msc/usbh_msc.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: class/video/usbd_video.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: common/usb_dc.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: common/usb_def.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: common/usb_util.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: core/usbd_core.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: core/usbd_core.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: core/usbh_core.c 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: core/usbh_core.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。
warning: usb_config.h 中的 CRLF 将被 LF 替换。<
在工作区中该文件仍保持原有的换行符。

Later roadmap

  • class driver

  • msc device driver with os,support filesystem interface

  • printer class support, device and host

  • mtp class support, device and host

  • cdc rndis host

  • cdc rndis device

  • hub process optimise in host mode

  • ftdi simulation,Copyright?

  • adb server driver

  • port

  • synopsys dwc2 device port optimise

  • synopsys dwc2 host port optimise

  • renesas usb ip port

  • rp2040 device port ?

  • rp2040 host port ?

  • ohci port

  • ehci with iso transfer

  • xhci port

  • application

  • daplink template for all chips

  • audio with i2s or audio codec

  • video with dvp

  • network with eth

  • network with wifi

  • network with printer,downloading file from net and print through printer

  • uf2

  • usb2 all bus:uart、i2c、spi、can

  • dfu download with st tool

  • tool

  • ci test

  • config tool update:winusb desc、hid report desc、audio desc、video desc

  • class Stress tests scripts

  • winusb windows and linux driver

provide a way to override default SCSI_inquiry name

here is the hardcoded define in usbd_msc.c:461

static bool SCSI_inquiry(uint8_t **data, uint32_t *len)
{
    //...some code

    uint8_t inquiry[SCSIRESP_INQUIRY_SIZEOF] = {
        /* 36 */

        /* LUN 0 */
        0x00,
        0x80,
        0x02,
        0x02,
        (SCSIRESP_INQUIRY_SIZEOF - 5),
        0x00,
        0x00,
        0x00,
        'B', 'o', 'u', 'f', 'f', 'a', 'l', 'o', /* Manufacturer : 8 bytes */
        'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product      : 16 Bytes */
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
        '0', '.', '0', '1' /* Version      : 4 Bytes */
    };

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.