HPM5301EVKLITE测试USB HS,cherryusb cdc
本来想用RT-thread Studio生成工程测试的,结果没有现成例子,改了半天也没法运行,放弃了。
用HPM原厂的SDK生成cherryusb cdc工程,Segger embeded studio直接打开编译成功,顿时感觉上面那个好难用啊,然后照着这边工程生成的例子往上面环境搬运,还是失败了,水平不行。
几处例子代码稍微修改一下便于测试:
/*
* Copyright (c) 2022-2023 HPMicro
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x01
#define CDC_INT_EP 0x83
/*!< config descriptor size */
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
#ifdef CONFIG_USB_HS
#define CDC_MAX_MPS 512
#else
#define CDC_MAX_MPS 64
#endif
/*!< global descriptor */
static const uint8_t cdc_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
/*
* string0 descriptor
*/
USB_LANGID_INIT(USBD_LANGID_STRING),
/*
* string1 descriptor
*/
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
/*
* string2 descriptor
*/
0x26, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'C', 0x00, /* wcChar10 */
'D', 0x00, /* wcChar11 */
'C', 0x00, /* wcChar12 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
/*
* string3 descriptor
*/
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
#ifdef CONFIG_USB_HS
/*
* device qualifier descriptor
*/
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x40,
0x01,
0x00,
#endif
0x00
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[8192];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[8192];
volatile bool dtr_enable;
volatile bool ep_tx_busy_flag;
void usbd_event_handler(uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
/* setup first out ep read transfer */
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 8192);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
usbd_ep_start_read(ep, read_buffer, 8192);
usbd_ep_start_write(CDC_IN_EP, read_buffer, nbytes);
}
void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(ep, NULL, 0);
} else {
ep_tx_busy_flag = false;
}
}
/*!< endpoint call back */
struct usbd_endpoint cdc_out_ep = {
.ep_addr = CDC_OUT_EP,
.ep_cb = usbd_cdc_acm_bulk_out
};
struct usbd_endpoint cdc_in_ep = {
.ep_addr = CDC_IN_EP,
.ep_cb = usbd_cdc_acm_bulk_in
};
/* function ------------------------------------------------------------------*/
struct usbd_interface intf0;
struct usbd_interface intf1;
void cdc_acm_init(void)
{
usbd_desc_register(cdc_descriptor);
usbd_add_interface(usbd_cdc_acm_init_intf(&intf0));
usbd_add_interface(usbd_cdc_acm_init_intf(&intf1));
usbd_add_endpoint(&cdc_out_ep);
usbd_add_endpoint(&cdc_in_ep);
usbd_initialize();
}
void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
{
(void)intf;
if (dtr) {
dtr_enable = 1;
}
}
void init_send_data(void)
{
write_buffer[0] = 'h';
write_buffer[1] = 'p';
write_buffer[2] = 'm';
write_buffer[3] = 'i';
write_buffer[4] = 'c';
write_buffer[5] = 'r';
write_buffer[6] = 'o';
write_buffer[7] = 0x0D;
write_buffer[8] = 0x0A;
memset(&write_buffer[9], 'a', 2037);
write_buffer[8190] = 0x0D;
write_buffer[8191] = 0x0A;
}
void cdc_acm_data_send_with_dtr_test(void)
{
ep_tx_busy_flag = true;
usbd_ep_start_write(CDC_IN_EP, write_buffer, 8192);
while (ep_tx_busy_flag) {
}
}
/*
* Copyright (c) 2022 HPMicro
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "board.h"
#include "hpm_debug_console.h"
#include "usb_config.h"
#include <stdio.h>
#define LED_FLASH_PERIOD_IN_MS 300
extern volatile bool dtr_enable;
extern void cdc_acm_init(void);
extern void cdc_acm_data_send_with_dtr_test(void);
extern void init_send_data(void);
int main(void) {
uint32_t u = 0;
board_init();
board_init_led_pins();
board_init_usb_pins();
intc_set_irq_priority(CONFIG_HPM_USBD_IRQn, 2);
board_timer_create(LED_FLASH_PERIOD_IN_MS, board_led_toggle);
printf("cherry usb cdc_acm device sample.\n");
cdc_acm_init();
board_delay_ms(2000);
init_send_data();
while (1) {
cdc_acm_data_send_with_dtr_test();
}
return 0;
}
主机读测试代码如下
import serial
import time
baudrate = 1152000
pack_size = 8192
total_count = 5200
import serial.tools.list_ports
ports = []
for port in serial.tools.list_ports.comports():
ports.append(port.name)
print(ports)
#com_num = input("请输入需要测试的串口号:")
ser = serial.Serial('COM10', baudrate)
ser.close()
if(ser.isOpen()):
print("串口关闭失败")
else:
print("串口关闭成功")
ser.open()
print("串口打开成功")
ser.dtr = True
start_time = 0
size_count = 0
print("开始测试")
for i in range(1):
while 1:
if size_count == 0:
start_time = time.time()
com_input = ser.read(pack_size)
size_count = size_count + 1
if size_count == total_count:
end_time = time.time()
size_count = 0
total_time = end_time - start_time
print("测试数据量%dMB, 时间%.2fs, 速度%.2fMB/s" %(total_count*pack_size/1000000, total_time, (total_count*pack_size/1000000)/total_time))
break
ser.close()
if(ser.isOpen()):
print("串口关闭失败")
else:
print("串口关闭成功")
主机写测试代码如下
import serial
import time
try:
from serial.tools.list_ports import comports
except ImportError:
raise serial.serialutil.SerialException
test_comx = 'COM10'
test_baudrate = 20000000
test_maxsize = 10*1024*4096
test_data = '0xAA' * 4096
test_serial = serial.Serial(test_comx, test_baudrate, timeout = 1)
def test_cdc_out():
send_count = 0
begin = time.time()
while True:
if send_count < test_maxsize:
txdatalen = test_serial.write(test_data.encode("utf-8"))
send_count += txdatalen
else:
print("cdc out speed %f MB/s" %(send_count//1024//1024/(time.time() - begin)))
break
if __name__ == '__main__':
print('test cdc out speed')
test_serial.setDTR(0)
test_cdc_out()
发现#define CDC_MAX_MPS 512
不能改大,否则不能正常找到设备,按照理论上USB HS最多8192个数据包,这样最大速度就是4MB/s,实测写3.62 MB/s,读速度2.25MB/s。
看到有人能测到30MB/s,是需要如何改才能达到呢?
移植参考cherryusb 文档,已经非常详细了。
多谢大神,关了log就ok了
以上是官方测试脚本测的读速度上不来啊,我用别人链接改的可以测到33.24MB/s
我说我是来学开车的,你说要先学汽车组成😂,先干为敬,多谢了@sakumisu
你学开车,也不能上来把人家方向盘改了把。一样的道理。能用就行,辛苦了
cherryusb的性能设计比tinyusb优秀,希望rt-thread能把它作为核心模块支持来集成,天下苦tinyusb久矣,tinyusb的设计理念没有为高速USB留下发展空间。@sakumisu
我也希望啊,不过有阻力,暂时还是以软件包吧。