diff options
| author | sakumisu <[email protected]> | 2025-12-12 22:45:10 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2025-12-12 22:45:10 +0800 |
| commit | da2263728aba07a28d9b6946b7acb6b0a0a97bb1 (patch) | |
| tree | 2a53759e9992b54dbf582b8ba111e0c54e1bcf1d /docs/source | |
| parent | 707e865627e65b9d661a431c92d57e50ab9d20ab (diff) | |
refactor(serial): add host serial framework
Signed-off-by: sakumisu <[email protected]>
Diffstat (limited to 'docs/source')
| -rw-r--r-- | docs/source/api/api_host.rst | 105 | ||||
| -rw-r--r-- | docs/source/demo/usbh_serial.rst | 94 |
2 files changed, 196 insertions, 3 deletions
diff --git a/docs/source/api/api_host.rst b/docs/source/api/api_host.rst index 28287a0b..51b1c502 100644 --- a/docs/source/api/api_host.rst +++ b/docs/source/api/api_host.rst @@ -154,14 +154,115 @@ lsusb int lsusb(int argc, char **argv); -CDC ACM +SERIAL ----------------- +usbh_serial_open +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_open`` 根据路径打开一个串口设备。 + +.. code-block:: C + + struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags); + +- **devname** 串口路径 +- **open_flags** 打开标志,参考 `USBH_SERIAL_OFLAG_*` 定义 +- **return** serial 结构体句柄 + +usbh_serial_close +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_close`` 关闭串口设备。 + +.. code-block:: C + + void usbh_serial_close(struct usbh_serial *serial); + +- **serial** serial 结构体句柄 + +usbh_serial_control +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_control`` 对串口进行配置。 + +.. code-block:: C + + int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg); + +- **serial** serial 结构体句柄 +- **cmd** 控制命令,参考 `USBH_SERIAL_CMD_*` 定义 +- **arg** 控制参数指针 +- **return** 0 表示正常其他表示错误 + +usbh_serial_write +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_write`` 向串口写数据。 **串口设备如果是 USB2TTL 类型,必须按照波特率发送,否则会丢包** + +.. code-block:: C + + int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen); + +- **serial** serial 结构体句柄 +- **buffer** 数据缓冲区指针 +- **buflen** 要写入的数据长度,如果是 USB2TTL 设备,一次最高 wMaxPacketSize +- **return** 实际写入的数据长度或者错误码 + +.. note:: 有无设置波特率都可以使用该 API,当未设置波特率时,长度无限制,如果设置了波特率则为 wMaxPacketSize。 + +usbh_serial_read +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_read`` 从串口读数据。 **如果没有设置波特率,不允许使用该 API**。 + +.. code-block:: C + + int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen); + +- **serial** serial 结构体句柄 +- **buffer** 数据缓冲区指针 +- **buflen** 要读取的最大数据长度 +- **return** 实际读取的数据长度或者错误码 + +usbh_serial_cdc_write_async +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_cdc_write_async`` 异步从串口读数据。 **如果设置了波特率,不允许使用该 API**。 + +.. code-block:: C + + int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg); + +- **serial** serial 结构体句柄 +- **buffer** 数据缓冲区指针 +- **buflen** 要发送的数据长度 +- **complete** 读数据完成回调函数 +- **arg** 回调函数参数 +- **return** 0 表示正常其他表示错误 + +usbh_serial_cdc_read_async +"""""""""""""""""""""""""""""""""""" + +``usbh_serial_cdc_read_async`` 异步从串口读数据。 **如果设置了波特率,不允许使用该 API**。 + +.. code-block:: C + + int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg); + +- **serial** serial 结构体句柄 +- **buffer** 数据缓冲区指针 +- **buflen** 要读取的最大数据长度,一次最高 16K。并且需要是 wMaxPacketSize 的整数倍 +- **complete** 读数据完成回调函数 +- **arg** 回调函数参数 +- **return** 0 表示正常其他表示错误 + + HID ----------------- MSC ----------------- -RNDIS +NETWORK -----------------
\ No newline at end of file diff --git a/docs/source/demo/usbh_serial.rst b/docs/source/demo/usbh_serial.rst index 58355cfe..c3c99255 100644 --- a/docs/source/demo/usbh_serial.rst +++ b/docs/source/demo/usbh_serial.rst @@ -1,4 +1,96 @@ usbh_serial =============== -当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。
\ No newline at end of file +Serial 框架当前支持 cdc acm, ftdi, cp210x, ch34x, pl2303,gsm 驱动。当前支持两种使用方式, +一种是使用源生 CherryUSB usbhost serial API 进行操作,另一种是基于平台封装的 API 操作,比如 rt-thread device API。,nuttx posix API。 + +下面演示的是使用 CherryUSB usbhost serial API 进行串口回环测试,并且使用阻塞发送,异步读取的方式: + +.. code-block:: C + + struct usbh_serial *serial; + + serial = usbh_serial_open("/dev/ttyACM0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK); + if (serial == NULL) { + serial = usbh_serial_open("/dev/ttyUSB0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK); + if (serial == NULL) { + USB_LOG_RAW("no serial device found\r\n"); + goto delete; + } + } + + struct usbh_serial_termios termios; + + memset(&termios, 0, sizeof(termios)); + termios.baudrate = 115200; + termios.stopbits = 0; + termios.parity = 0; + termios.databits = 8; + termios.rtscts = false; + termios.rx_timeout = 0; + ret = usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios); + if (ret < 0) { + USB_LOG_RAW("set serial attr error, ret:%d\r\n", ret); + goto delete_with_close; + } + + serial_tx_bytes = 0; + while (1) { + /* for common, we use timeout with 0xffffffff, this is just a test */ + ret = usbh_serial_write(serial, serial_tx_buffer, sizeof(serial_tx_buffer)); + if (ret < 0) { + USB_LOG_RAW("serial write error, ret:%d\r\n", ret); + goto delete_with_close; + } else { + serial_tx_bytes += ret; + usb_osal_msleep(10); // 11.52 Byte/ms at 115200bps --> 64Byte/5.5ms + + if (serial_tx_bytes == SERIAL_TEST_LEN) { + USB_LOG_RAW("send over\r\n"); + break; + } + } + } + + volatile uint32_t wait_timeout = 0; + serial_rx_bytes = 0; + while (1) { + ret = usbh_serial_read(serial, &serial_rx_data[serial_rx_bytes], SERIAL_TEST_LEN); + if (ret < 0) { + USB_LOG_RAW("serial read error, ret:%d\r\n", ret); + goto delete_with_close; + } else { + serial_rx_bytes += ret; + + if (serial_rx_bytes == SERIAL_TEST_LEN) { + USB_LOG_RAW("receive over\r\n"); + for (uint32_t i = 0; i < SERIAL_TEST_LEN; i++) { + if (serial_rx_data[i] != 0xa5) { + USB_LOG_RAW("serial loopback data error at index %d, data: 0x%02x\r\n", (unsigned int)i, serial_rx_data[i]); + goto delete_with_close; + } + } + USB_LOG_RAW("serial loopback test success\r\n"); + break; + } + } + wait_timeout++; + + if (wait_timeout > 500) { // 5s + USB_LOG_RAW("serial read timeout\r\n"); + goto delete_with_close; + } + + usb_osal_msleep(10); + } + + usbh_serial_close(serial); + + +用户需要考虑以下三种场景: + +- USB2TTL 设备 + 启用了波特率,这种情况下需要使用 `usbh_serial_write` 和 `usbh_serial_read` 进行收发数据, **并且需要根据波特率控制发送频率,防止对端丢包**; + +- 纯 USB 设备 + 未启动波特率,这种情况下可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async` 进行异步收发数据,阻塞则用 `usbh_serial_write` 并且不需要控制发送频率。不可以使用 `usbh_serial_read`。 + +- 纯 USB 设备 + 启动波特率,同 1,但是速率打折扣。不可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async`。如果是 GSM 设备需要使用第一种。
\ No newline at end of file |
