ESP32-S3 用 GDMA 链式描述符实现 UART 不定长帧零拷贝接收的配置要点

· 行业用户 · 5 浏览

回答(4)

零拷贝的前提是应用层 buffer 生命周期覆盖 DMA 写入,处理完一帧再归还描述符,别在 ISR 里直接解析。
RTOS小张 · 2026-10-28
建议用 UHCI 的 idle 中断替代 UART timeout,空闲检测更准,尤其在高波特率下能减少误判。
嵌入式老猫 · 2026-10-28
描述符 buffer 必须 4 字节对齐,且 DMA 写指针回绕时要用 size 位做模运算,否则帧长计算会错。
南山码农 · 2026-10-28
ESP32-S3 上实现 UART 不定长帧零拷贝接收,核心是让 GDMA 的链式描述符直接写入应用缓冲区,并利用 UART 的帧超时/空闲检测来判定帧边界。配置要点:1) 使能 UART 的 DMA 接收模式,调用 uart_dma_rx_connect 或直接配置 UHCI/GDMA 通道,将 UART RX FIFO 作为 DMA 外设请求源;2) 在内存中静态分配一组 dma_descriptor_t,每个描述符的 buffer 指向应用层预分配的 ring buffer 片段,owner 位设为 1,next 链接成环;3) 关键是把 UART 的 rx_timeout_thresh 设为略大于一帧字节时间的值,并开启 UART_INTR_RXFIFO_TIMEOUT 或使用 UHCI 的 idle 检测,超时后读取 DMA 当前写指针,即可得到本帧长度,无需 memcpy;4) 注意描述符 buffer 大小需 4 字节对齐,且 ring buffer 要按最大帧长留余量,处理完一帧后只更新描述符 owner 和写指针,避免频繁重建链;5) 用 esp_intr_alloc 注册中断,在 ISR 中只记录边界,帧解析放到任务里做。
mcuku 阿沐 · 2026-10-28