diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_dma.jpg b/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_dma.jpg deleted file mode 100644 index 0776e193f1363771971808d8f0b66332b18a779f..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_dma.jpg and /dev/null differ diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_int.jpg b/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_int.jpg deleted file mode 100644 index 18ce4565bc5d126d6958aa2983ab3d29c9520d38..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_int.jpg and /dev/null differ diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_txdma_intrx.jpg b/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_txdma_intrx.jpg deleted file mode 100644 index 43acc89b50ce0d7852fce747a9b59d23a2d4f01b..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_txdma_intrx.jpg and /dev/null differ diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_txpoll_rxint.jpg b/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_txpoll_rxint.jpg deleted file mode 100644 index 0bfac41c8bebd3de6aab8fe190725e1d559f2c28..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/figures/mcfg_txpoll_rxint.jpg and /dev/null differ diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/uart.md b/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/uart.md index 418fa79a60f56204df37a7632707732dd110edbb..2e8f2f8a120b87c2025ab3db0f8a06f1c7e75303 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/uart.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v2/uart.md @@ -57,7 +57,7 @@ rt_device_t rt_device_find(const char* name); 一般情况下,注册到系统的串口设备名称为 uart0,uart1 等,使用示例如下所示: ```c -#define SAMPLE_UART_NAME "uart2" /* 串口设备名称 */ +#define SAMPLE_UART_NAME "uart1" /* 串口设备名称 */ static rt_device_t serial; /* 串口设备句柄 */ /* 查找串口设备 */ serial = rt_device_find(SAMPLE_UART_NAME); @@ -105,12 +105,8 @@ rt_device_open(dev, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING) > [!NOTE] > 注:为了避免 阻塞 / 非阻塞模式 和 轮询 / 中断 / DMA 模式 在文中描述上可能存在的误解,故本文以 应用层操作模式 指代 阻塞 / 非阻塞模式,以 硬件工作模式 指代 轮询 / 中断 / DMA 模式。 -而对于流模式 `RT_DEVICE_FLAG_STREAM`,主要是当串口外设作为控制台时才会使用,该模式用来解决用户回车换行的问题,在正常的串口外设通信场景中,该模式一般不会使用。 - > [!NOTE] -> 注:`RT_DEVICE_FLAG_STREAM` 流模式用于向串口终端输出字符串:当输出的字符是 `"\n"` (对应 16 进制值为 0x0A)时,自动在前面输出一个 `"\r"`(对应 16 进制值为 0x0D) 做分行。 - -流模式 RT_DEVICE_FLAG_STREAM 可以和接收发送模式参数使用或 “|” 运算符一起使用。 +> 注:`RT_DEVICE_FLAG_STREAM` 流模式用于向串口终端输出字符串:当输出的字符是 `"\n"` (对应 16 进制值为 0x0A)时,自动在前面输出一个 `"\r"`(对应 16 进制值为 0x0D) 做分行。在正常的串口外设通信场景中,该模式一般不会使用。 #### 硬件工作模式选择 @@ -129,71 +125,94 @@ rt_device_open(dev, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING) **发送端的模式对应关系如下表所示:** -| 编号 | 配置发送缓冲区(有 / 无)说明 | 硬件工作模式(TX) | 应用层操作模式(TX) | +| **硬件工作模式(TX)** | **应用层操作模式(TX)** | 配置发送缓冲区 | 是否生效 | | ---- | --------------------------------------- | ------------------ | -------------------- | -| (1) | **不使用缓存区,且设置缓存区长度为0** | 轮询 | 阻塞 | -| (2) | 不支持该模式 | 轮询 | 非阻塞 | -| (3) | 使用缓存区 | 中断 | 阻塞 | -| (4) | 使用缓存区 | 中断 | 非阻塞 | -| (5) | **不使用缓存区,但需要设置缓冲区长度大于0** | DMA | 阻塞 | -| (6) | 使用缓存区 | DMA | 非阻塞 | +| 轮询 | 阻塞 | 不使用缓存区,但需要设置**设置缓存区长度为0** | ✔ | +| 轮询 | 非阻塞 | ❌不支持该模式 | ❌ | +| 中断 | 阻塞 | 使用缓存区 | ✔ | +| 中断 | 非阻塞 | 使用缓存区 | ✔ | +| DMA | 阻塞 | 不使用缓存区,但需要设置**缓冲区长度大于0** | ✔ | +| DMA | 非阻塞 | 使用缓存区 | ✔ | -对于编号 (1) 模式,如果必须使用轮询模式时,一定要将缓冲区大小配置为 0,因为如果缓冲区大小不为 0,在应用层使用发送阻塞模式时,将会使用中断模式(如果开 DMA,则使用 DMA 模式)。 +当使用 **轮询 阻塞模式发送**时,一定要将**缓冲区大小配置为 0**,因为如果缓冲区大小不为 0,在应用层使用发送阻塞模式时,将会使用中断模式(如果开 DMA,则使用 DMA 模式)。 -对于编号 (5) 模式,当用户设置为 DMA 阻塞模式时,虽然设置了缓冲区不为 0,但是该缓冲区并不会进行初始化,而是直接进行 DMA 数据搬运。从而省去了内存搬运造成的性能下降的问题。需要注意的是,当使用 DMA 阻塞模式时,虽然不用缓冲区,但是也要将缓冲区长度设置为大于 0 的值,因为当缓冲区长度为 0 时,将会错误地使用轮询模式。 +当使用 **DMA 阻塞模式发送**时,虽然不用缓冲区,但是也要将**缓冲区长度设置为大于 0** 的值,因为当缓冲区长度为 0 时,将会错误地使用轮询模式。虽然设置了缓冲区不为 0,但是该缓冲区并不会进行初始化占用空间,而是直接进行 DMA 数据搬运。 **接收端的模式对应关系如下表所示:** -| 编号 | 配置接收缓冲区(有 / 无)说明 | 硬件工作模式(RX) | 应用层操作模式(RX) | +| **硬件工作模式(RX)** | **应用层操作模式(RX)** | 配置发送缓冲区 | 是否生效 | | ---- | ------------------------------------- | ------------------ | -------------------- | -| (1) | **不使用缓存区,且设置缓存区长度为0** | 轮询 | 阻塞 | -| (2) | 不支持该模式 | 轮询 | 非阻塞 | -| (3) | 使用缓存区 | 中断 | 阻塞 | -| (4) | 使用缓存区 | 中断 | 非阻塞 | -| (5) | 使用缓存区 | DMA | 阻塞 | -| (6) | 使用缓存区 | DMA | 非阻塞 | +| 轮询 | 阻塞 | 不使用缓存区,但需要设置**设置缓存区长度为0** | ✔ | +| 轮询 | 非阻塞 | ❌不支持该模式 | ❌ | +| 中断 | 阻塞 | 使用缓存区 | ✔ | +| 中断 | 非阻塞 | 使用缓存区 | ✔ | +| DMA | 阻塞 | 不使用缓存区,但需要设置**缓冲区长度大于0** | ✔ | +| DMA | 非阻塞 | 使用缓存区 | ✔ | -对于编号 (1) 模式,如果必须使用轮询模式时,一定要将缓冲区大小配置为 0,因为如果缓冲区大小不为 0,在应用层使用接收阻塞模式时,将会使用中断模式(如果开 DMA,则使用 DMA 模式)。 +当使用 **轮询 阻塞模式接收**时,一定要将**缓冲区大小配置为 0**,因为如果缓冲区大小不为 0,在应用层使用接收阻塞模式时,将会使用中断模式(如果开 DMA,则使用 DMA 模式)。 下面举例说明如何配置硬件工作模式: -##### 配置发送接收为 DMA 模式 - 在 menuconfig 中配置效果如下: -![menuconfig](figures/mcfg_dma.jpg) +##### 配置发送接收为 DMA 模式 -上图所示,对于 UART1 的配置为开启 DMA RX 和 DMA TX,且发送和接收缓存区大小设置为 1024 字节。 +```shell +Enable UART1 ---> + [*] Enable UART1 RX DMA (是否使能 RX DMA) + [*] Enable UART1 TX DMA (是否使能 TX DMA) + (64)Set UART1 RX DMA ping-pong buffer size (RX DMA 的乒乓缓冲区) + (128)Set UART1 RX buffer size (rx 缓冲区大小) + (128)Set UART1 TX buffer size (tx 缓冲区大小。TX DMA下无效但必须大于0,请参考上面介绍) +``` +如上所示,对于 UART1 的配置为开启 DMA RX 和 DMA TX,且发送和接收缓存区大小设置为 128 字节 由此用户在应用层对串口的接收和发送的操作模式进行配置时,无论配置阻塞或者非阻塞,均使用的是 DMA 模式。 -##### 配置发送接收为中断模式 -在 menuconfig 中配置效果如下: -![menuconfig](figures/mcfg_int.jpg) +##### 配置发送接收为中断模式 -上图所示,对于 UART1 的配置为关闭 DMA RX 和 DMA TX,且发送和接收缓存区大小设置为 1024 字节。 +```shell +Enable UART1 ---> + [ ] Enable UART1 RX DMA (是否使能 RX DMA) + [ ] Enable UART1 TX DMA (是否使能 TX DMA) + (128)Set UART1 RX buffer size (rx 缓冲区大小) + (128)Set UART1 TX buffer size (tx 缓冲区大小。TX DMA下无效但必须大于0,请参考上面介绍) +``` +如上所示,对于 UART1 的配置为开启 INT RX 和 INT TX,且发送和接收缓存区大小设置为 128 字节。 由此用户在应用层对串口的接收和发送的操作模式进行配置时,无论配置阻塞或者非阻塞,均使用的是中断模式。 -##### 配置发送 DMA 模式、接收中断模式 -在 menuconfig 中配置效果如下: -![menuconfig](figures/mcfg_txdma_intrx.jpg) +##### 配置发送 DMA 模式、接收中断模式 + +```shell +Enable UART1 ---> + [ ] Enable UART1 RX DMA (是否使能 RX DMA) + [*] Enable UART1 TX DMA (是否使能 TX DMA) + (128)Set UART1 RX buffer size (rx 缓冲区大小) + (128)Set UART1 TX buffer size (tx 缓冲区大小。TX DMA下无效但必须大于0,请参考上面介绍) +``` -上图所示,对于 UART1 的配置为关闭 DMA RX 和开启 DMA TX,且发送和接收缓存区大小设置为 1024 字节。 +如上所示,对于 UART1 的配置为开启 INT RX ,开启 DMA TX,且发送和接收缓存区大小设置为 128 字节。 由此用户在应用层对串口的接收和发送的操作模式进行配置时,无论配置阻塞或者非阻塞,均使用的是 DMA 发送模式和中断接收模式。 -##### 配置发送轮询模式、接收中断模式(串口控制台默认模式) -在 menuconfig 中配置效果如下: -![menuconfig](figures/mcfg_txpoll_rxint.jpg) +##### 配置发送轮询模式、接收中断模式(串口控制台默认模式) -上图所示,对于 UART1 的配置为关闭 DMA RX 和 DMA TX,接收缓存区大小设置为 1024 字节,但设置 `UART1 TX buffer size` 为 0。 +```shell +Enable UART1 ---> + [ ] Enable UART1 RX DMA (是否使能 RX DMA) + [ ] Enable UART1 TX DMA (是否使能 TX DMA) + (128)Set UART1 RX buffer size (rx 缓冲区大小) + ( 0 )Set UART1 TX buffer size (tx 缓冲区大小。TX DMA下无效但必须大于0,请参考上面介绍) +``` + +如上所示,对于 UART1 的配置为关闭 DMA RX 和 DMA TX,接收缓存区大小设置为 1024 字节,但设置 `UART1 TX buffer size` 为 0。 由此用户在应用层对串口的接收和发送的操作模式进行配置时,发送只能使用阻塞模式,接收可以使用阻塞和非阻塞模式。串口控制台默认使用这样的配置模式,且操作模式为阻塞发送和非阻塞接收。 @@ -217,20 +236,55 @@ rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg); | -RT_ENOSYS | 执行失败,dev 为空 | | 其他错误码 | 执行失败 | +指示控制命令 cmd 当前支持的命令包括: + +```c +/* 更新串口配置 */ +#define RT_DEVICE_CTRL_CONFIG /* arg类型: (struct serial_configure *) */ + +/* 设置接收超时时间。在调用 rt_device_read 之前设置。在轮询模式下不支持 */ +#define RT_SERIAL_CTRL_SET_RX_TIMEOUT /* arg类型: (rt_int32_t *) */ + +/* 设置发送超时时间。在调用 rt_device_write 之前设置。在轮询模式下不支持 */ +#define RT_SERIAL_CTRL_SET_TX_TIMEOUT /* arg类型: (rt_int32_t *) */ + +/* 获取接收超时时间。在轮询模式下不支持 */ +#define RT_SERIAL_CTRL_GET_RX_TIMEOUT /* arg类型: (rt_int32_t *) */ + +/* 获取发送超时时间。在轮询模式下不支持 */ +#define RT_SERIAL_CTRL_GET_TX_TIMEOUT /* arg类型: (rt_int32_t *) */ + +/* 清空接收缓冲区,丢弃所有数据 */ +#define RT_SERIAL_CTRL_RX_FLUSH /* arg类型: (RT_NULL) */ + +/* 清空发送缓冲区,阻塞并等待缓冲区数据全部发送完成。在轮询模式下不支持 */ +#define RT_SERIAL_CTRL_TX_FLUSH /* arg类型: (RT_NULL) */ + +/* 获取未读字节数。在轮询模式下不支持 */ +#define RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT /* arg类型: (rt_ssize_t *) */ + +/* 获取串口配置 */ +#define RT_SERIAL_CTRL_GET_CONFIG /* arg类型: (struct serial_configure *) */ +``` + 控制参数结构体 struct serial_configure 原型如下: ```c struct serial_configure { - rt_uint32_t baud_rate; /* 波特率 */ - rt_uint32_t data_bits :4; /* 数据位 */ - rt_uint32_t stop_bits :2; /* 停止位 */ - rt_uint32_t parity :2; /* 奇偶校验位 */ - rt_uint32_t bit_order :1; /* 高位在前或者低位在前 */ - rt_uint32_t invert :1; /* 模式 */ - rt_uint32_t rx_bufsz :16; /* 接收数据缓冲区大小 */ - rt_uint32_t tx_bufsz :16; /* 发送数据缓冲区大小 */ - rt_uint32_t reserved :4; /* 保留位 */ + rt_uint32_t baud_rate; /* 波特率 */ + rt_uint32_t data_bits :4; /* 数据位 */ + rt_uint32_t stop_bits :2; /* 停止位 */ + rt_uint32_t parity :2; /* 奇偶校验位 */ + rt_uint32_t bit_order :1; /* 高位在前或者低位在前 */ + rt_uint32_t invert :1; /* 模式 */ + rt_uint32_t rx_bufsz :16; /* 接收数据缓冲区大小 */ + rt_uint32_t tx_bufsz :16; /* 发送数据缓冲区大小 */ + rt_uint32_t flowcontrol :1; /* 流控模式 */ + rt_uint32_t reserved :5; /* 保留位 */ +#ifdef RT_SERIAL_USING_DMA + rt_uint32_t dma_ping_bufsz :16; /* rx dma的乒乓缓冲区 */ +#endif }; ``` @@ -271,6 +325,9 @@ RT-Thread 提供的配置参数可取值为如下宏定义: /* 模式可取值 */ #define NRZ_NORMAL 0 /* normal mode */ #define NRZ_INVERTED 1 /* inverted mode */ +/* 流控模式 */ +#define RT_SERIAL_FLOWCONTROL_CTSRTS 1 /* 硬件流控:使用 RTS/CTS 引脚 */ +#define RT_SERIAL_FLOWCONTROL_NONE 0 /* 无流控 */ #define RT_SERIAL_RX_MINBUFSZ 64 /* 限制接收缓冲区最小长度 */ #define RT_SERIAL_TX_MINBUFSZ 64 /* 限制发送缓冲区最小长度 */ @@ -280,22 +337,23 @@ RT-Thread 提供的默认串口配置如下,即 RT-Thread 系统中默认每 ```c /* Default config for serial_configure structure */ -#define RT_SERIAL_CONFIG_DEFAULT \ -{ \ - BAUD_RATE_115200, /* 115200 bits/s */ \ - DATA_BITS_8, /* 8 databits */ \ - STOP_BITS_1, /* 1 stopbit */ \ - PARITY_NONE, /* No parity */ \ - BIT_ORDER_LSB, /* LSB first sent */ \ - NRZ_NORMAL, /* Normal mode */ \ - RT_SERIAL_RX_MINBUFSZ, /* rxBuf size */ \ - RT_SERIAL_TX_MINBUFSZ, /* txBuf size */ \ - 0 \ +#define RT_SERIAL_CONFIG_DEFAULT \ +{ \ + BAUD_RATE_115200, /* 115200 bits/s */ \ + DATA_BITS_8, /* 8 databits */ \ + STOP_BITS_1, /* 1 stopbit */ \ + PARITY_NONE, /* No parity */ \ + BIT_ORDER_LSB, /* LSB first sent */ \ + NRZ_NORMAL, /* Normal mode */ \ + RT_SERIAL_RX_MINBUFSZ, /* rxBuf size */ \ + RT_SERIAL_TX_MINBUFSZ, /* txBuf size */ \ + RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \ + 0, /* reserved */ \ } ``` > [!NOTE] -> 注:虽然默认串口配置设置了 rx_bufsz 和 tx_bufsz 的大小,但是其缓冲区具体长度会在底层驱动初始化时再次配置,这里无需关心其值。 +> 注:虽然默认串口配置设置了 rx_bufsz 和 tx_bufsz 的大小,但是其缓冲区具体长度会在底层驱动初始化时根据Kconfig再次配置,这里无需关心其值。 若实际使用串口的配置参数与默认配置参数不符,则用户可以通过应用代码进行修改。修改串口配置参数,如波特率、数据位、校验位、缓冲区接收 buffsize、停止位等的示例程序如下: @@ -347,19 +405,20 @@ rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_ #define SAMPLE_UART_NAME "uart2" /* 串口设备名称 */ static rt_device_t serial; /* 串口设备句柄 */ char str[] = "hello RT-Thread!\r\n"; -struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 配置参数 */ + /* 查找串口设备 */ serial = rt_device_find(SAMPLE_UART_NAME); /* 以非阻塞接收和阻塞发送模式打开串口设备 */ rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + /* 发送字符串 */ rt_device_write(serial, 0, str, (sizeof(str) - 1)); ``` ### 设置发送完成回调函数 -在应用程序调用 `rt_device_write()` 写入数据时,如果底层硬件能够支持自动发送,那么上层应用可以设置一个回调函数。这个回调函数会在底层硬件数据发送完成后 (例如 DMA 传送完成或 FIFO 已经写入完毕产生完成中断时) 调用。可以通过如下函数设置设备发送完成指示 : +在应用程序调用 `rt_device_write()` 写入数据时,如果底层硬件能够支持自动发送,那么上层应用可以设置一个回调函数。这个回调函数会在底层硬件数据发送完成后 (例如 DMA 传送完成或 FIFO 已经写入完毕产生完成中断时) 调用。仅推荐非阻塞模式下使用,可以通过如下函数设置设备发送完成指示 : ```c rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t dev,void *buffer)); @@ -372,7 +431,7 @@ rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_devic | **返回** | —— | | RT_EOK | 设置成功 | -调用这个函数时,回调函数由调用者提供,当硬件设备发送完数据时,由设备驱动程序回调这个函数并把发送完成的数据块地址 buffer 作为参数传递给上层应用。上层应用(线程)在收到指示时会根据发送 buffer 的情况,释放 buffer 内存块或将其作为下一个写数据的缓存。 +调用这个函数时,回调函数由调用者提供,当硬件设备发送完数据时,由设备驱动程序回调这个函数并把发送完成的数据块地址 buffer (如果存在的话)作为参数传递给上层应用。 ### 设置接收回调函数 @@ -501,7 +560,7 @@ rt_err_t rt_device_close(rt_device_t dev); RT_DEVICE_FLAG_INT_TX RT_DEVICE_FLAG_DMA_RX RT_DEVICE_FLAG_DMA_TX - + // 新版本 oflags 的参数取值 RT_DEVICE_FLAG_RX_NON_BLOCKING RT_DEVICE_FLAG_RX_BLOCKING @@ -509,8 +568,13 @@ rt_err_t rt_device_close(rt_device_t dev); RT_DEVICE_FLAG_TX_BLOCKING ``` - **为了兼容旧版本的框架,使用新版本串口框架时旧版本的应用代码可直接使用,只需注意一点,旧版本的 oflags 参数不再起作用,默认使用新版本的操作模式: 接收非阻塞发送阻塞模式。** +* V2版本默认 `rt_device_read` 为阻塞读取,如果为了兼容V1框架的应用代码可通过下面方式进行修改。 + ```c + rt_int32_t rx_timeout = RT_WAITING_NO; + rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout); + ``` + * 缓冲区宏定义区别 旧版本接收缓冲区统一为 `RT_SERIAL_RB_BUFSZ` ,旧版本没有发送缓冲区的设置。 @@ -534,7 +598,7 @@ rt_err_t rt_device_close(rt_device_t dev); struct serial_configure { rt_uint32_t baud_rate; - + rt_uint32_t data_bits :4; rt_uint32_t stop_bits :2; rt_uint32_t parity :2; @@ -543,12 +607,12 @@ rt_err_t rt_device_close(rt_device_t dev); rt_uint32_t bufsz :16; rt_uint32_t reserved :6; }; - + // 新版本 struct serial_configure { rt_uint32_t baud_rate; - + rt_uint32_t data_bits :4; rt_uint32_t stop_bits :2; rt_uint32_t parity :2; @@ -556,7 +620,12 @@ rt_err_t rt_device_close(rt_device_t dev); rt_uint32_t invert :1; rt_uint32_t rx_bufsz :16; rt_uint32_t tx_bufsz :16; - rt_uint32_t reserved :6; + rt_uint32_t flowcontrol :1; + rt_uint32_t reserved :5; + + #ifdef RT_SERIAL_USING_DMA + rt_uint32_t dma_ping_bufsz :16; + #endif }; ``` @@ -696,3 +765,5 @@ static int uart_dma_sample(int argc, char *argv[]) /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample); ``` + +更多用法可参考 https://github.com/RT-Thread/rt-thread/tree/master/components/drivers/serial/utest/v2