Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
串口DMA接收
5
关于rt-thread的串口驱动dma接收的疑问?
发布于 2020-08-26 20:59:52 浏览:1987
订阅该版
众所周知,在使用串口进行频繁、大容量数据收发场合,在支持DMA的硬件上采用DMA方式进行发送、接收,可以明显降低CPU时间消耗。 通过阅读串口框架层serial.c、uart.c代码,rt-thread提供的串口驱动框架层,关于中断发送、中断接收接收的原理,我的理解为: rt_serial_init():对串口的数据帧格式、波特率等参数进行设置; rt_serial_open():主要对串口发送、接收缓冲区进行创建,设置发送、接收完成回调函数。 对于中断发送、中断接收很好理解: **接收数据时**:硬件产生中断,在中断服务函数中,将数据放到rt_serial_open函数调用时创建的fifo中,然后调用接收数据回调函数(rx_indicate),通知应用线程处理数据 **发送数据时**:rt_serial_write将数据放到发送缓冲区,中断服务程序进行逐字节发送,发送完成后,调用发送完成回调(tx_completion),通知应用线程继续发送数据或者销毁缓冲区。 关于dma发发送、dma接收,有一个地方就不太懂了:关于这里serial->config.bufsz==0这个分支的处理,既然dma接收,又让bufsz为0,这种情况下,采取dma接收,数据直接传到应用层的接收缓冲区了吗?那又如何得知dma接收完成了呢?感觉这个分支是不是多余了? ``` rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) { rt_base_t level; RT_ASSERT((serial != RT_NULL) && (data != RT_NULL)); level = rt_hw_interrupt_disable(); if (serial->config.bufsz == 0) { int result = RT_EOK; struct rt_serial_rx_dma *rx_dma; rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx; RT_ASSERT(rx_dma != RT_NULL); if (rx_dma->activated != RT_TRUE) { rx_dma->activated = RT_TRUE; RT_ASSERT(serial->ops->dma_transmit != RT_NULL); serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX); } else result = -RT_EBUSY; rt_hw_interrupt_enable(level); if (result == RT_EOK) return length; rt_set_errno(result); return 0; } else { struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial); RT_ASSERT(rx_fifo != RT_NULL); if (length < (int)fifo_recved_len) recv_len = length; else recv_len = fifo_recved_len; if (rx_fifo->get_index + recv_len < serial->config.bufsz) rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len); else { rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, serial->config.bufsz - rx_fifo->get_index); rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer, recv_len + rx_fifo->get_index - serial->config.bufsz); } rt_dma_recv_update_get_index(serial, recv_len); rt_hw_interrupt_enable(level); return recv_len; } } ```
查看更多
红枫
认证专家
2020-08-27
这家伙很懒,什么也没写!
这个分支是为了解决在没有使用FIFO情况下只接调用低层驱动完成数据接收,数据是直接传输到用户接收缓冲区中,传输完成条件:1个是长度限制,另1个是串口空闲。
4
个回答
默认排序
按发布时间排序
arminker
2020-08-27
这家伙很懒,什么也没写!
感谢JQRR_7699的解答, 但是还是有疑问~~~ 分析源码,应用使用DMA_RX方式读数据,调用关系为:`rt_device_read——》rt_serial_read——》dma_transmit` 疑问1)**dma_transmit**: 调用底层驱动开始dma接收的应该是这里吧? 疑问2)dma_transmit调用时,dma必然还没有传输完,那么会在这里使用rt_sem_take休眠,然后dma中断或者串口空闲中断来唤醒吗? 对于疑问2,dma_transmit是驱动层函数,应该不会调用rt_sem_take类似的操作,如果的理解没错,我猜测应用层应该这么写 ``` rcvsize = rt_device_read(dev, buf, len); // 读设备, 不会睡眠,立即返回 rt_sem_take(sem); // 调用后睡眠。 等待dma通道产生传输完成中断,调用rx_indicate释放信号 ``` 所以,按照我的理解,rt_device_read会立马返回,而且返回的就是传递的那个长度len。 那按你说,`传输完成条件:1个是长度限制,另1个是串口空闲。`,如果是串口空闲的情况,读取数据的长度岂不是不对了?
撰写答案
登录
注册新账号
关注者
1
被浏览
2k
关于作者
arminker
这家伙很懒,什么也没写!
提问
11
回答
5
被采纳
0
关注TA
发私信
相关问题
1
rt-thread串口DMA接收方式疑问
2
串口驱动中UART_DMA_RX_IRQHandler函数的疑问
3
volatile在多线程及串口驱动框架中的应用疑问
4
bsp中stm32串口dma接收
5
RT-THREAD STUDIO 配置UART5 DMA中断接收 报错
6
串口DMA接收数据,一条数据多次回调
7
stm32l4r5zi lpuart1无法接收数据
8
如果才能提高串口回复速度?
9
stm32h750串口dma可以进中断,但无法接收数据
10
STM32 串口DMA接收问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部