Giter Site home page Giter Site logo

cherry-embedded / cherryusb Goto Github PK

View Code? Open in Web Editor NEW
1.0K 33.0 216.0 55.53 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.81% Python 0.60% CMake 0.60%
usb-host usb-device usb cdc hid uvc uac dfu ehci hub

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

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鼠标/键盘等)?

希望能得到解答,谢谢!

stm32f0系列单片机枚举失败

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

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?

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.

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 替换。<
在工作区中该文件仍保持原有的换行符。

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

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

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 Host多个HID设备该如何处理?

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

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

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.

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!

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

Porting copyright issue

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

望回复,谢谢!

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.

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

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-MTP(Media Transfer Protocol)

是否考虑增加 MTP?

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

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

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

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.

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.

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

[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转换芯片MAX3421E的协议栈移植问题

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

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

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

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); ,导致在某些异常情况下死锁

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

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

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

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.

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

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.