硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1214|回复: 16
收起左侧

[UART] 串口dma发送丢失数据

  [复制链接]

13

主题

54

回帖

93

积分

初级会员

积分
93
发表于 2022-10-12 10:39:38 | 显示全部楼层 |阅读模式
1.目前板子的硬件  stm32h7+8266
2.软件部分的是freertos  串口通信使用的是串口空闲中断+dma。
3.目前的情况:板子原来是以太网口,现在想加上wifi功能所以加了个wifi的串口模块,8266做服务器,然后把客户端的数据通过串口转发给h7处理,h7处理后再通过串口发送给8266,8266再发送给客户端。
现在是一个客户端通信的情况下数据正常,如果两个客户端通信,h7同时发送两个客户端消息给8266就会出现数据丢失的情况,丢失数据的尾巴。
image.png
4.我用调试看  dma发送会进入busy的状态,下面是我发送的代码:
[C] 纯文本查看 复制代码
void WIFI_USART_Send_Data(u8 *buf,u16 len)
{
//  while(HAL_UART_Transmit_DMA(&WIFI_USART_Handler,buf,len) == HAL_BUSY);//试过一直在这里等待busy也不行
    if(HAL_UART_Transmit_DMA(&WIFI_USART_Handler,buf,len) == HAL_BUSY)//串口2发送数据
    {
        HAL_UART_DMAStop(&WIFI_USART_Handler);
        HAL_UART_Receive_DMA(&WIFI_USART_Handler,WIFIRxFIFO.buf[WIFIRxFIFO.index],WIFI_FIFO_BUF_LEN);
        HAL_UART_Transmit_DMA(&WIFI_USART_Handler,buf,len);
    }
    while(__HAL_UART_GET_FLAG(&WIFI_USART_Handler,UART_FLAG_TC) != SET);
}

5.接收的部分是空闲中断触发后把接收数据的指针索引写入队列,然后切换指针的索引,然后在任务处理一直等待队列的消息。
6.怀疑过是波特率过高的问题,后面把波特率降到9600也有这个现象出现,测试过在115200的通信下收和发【10ms、45个字节】没有数据丢失,但是这个测试的情况下没有出现过进入busy的状态。
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-12 11:15:21 | 显示全部楼层
在dma发送后用系统延时100ms 貌似正常了。。。
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-12 11:41:23 | 显示全部楼层
myNameIsLin 发表于 2022-10-12 11:15
在dma发送后用系统延时100ms 貌似正常了。。。

不行,我再增加第三个客户端通信 情况又出现了
回复

使用道具 举报

1

主题

6

回帖

9

积分

新手上路

积分
9
发表于 2022-10-12 11:55:10 | 显示全部楼层
可以试试不使用DMA发送
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-12 14:46:26 | 显示全部楼层
本帖最后由 myNameIsLin 于 2022-10-12 15:08 编辑

搞错了。。。。
回复

使用道具 举报

13

主题

192

回帖

231

积分

高级会员

积分
231
发表于 2022-10-12 16:57:37 | 显示全部楼层
我们以前的情况是,使用DMA发送后,就释放掉了发送buffer指针。有的时候发现会丢失尾部信息,后来发现DMA发送后,不能立即释放buffer指针,否则里面的内容会被污染,然后再发送。
你可以参考一下,是不是同样的问题。
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-12 19:58:51 | 显示全部楼层
zhang0352505 发表于 2022-10-12 16:57
我们以前的情况是,使用DMA发送后,就释放掉了发送buffer指针。有的时候发现会丢失尾部信息,后来发现DMA发 ...

这个数组用的是系统分配的内存,是固定用来发送的,应该不是这个问题
回复

使用道具 举报

4

主题

46

回帖

58

积分

初级会员

积分
58
发表于 2022-10-12 23:56:54 | 显示全部楼层
多线程操作的时候,记得给API加互斥信号量锁,要是HAL_UART_Transmit_DMA执行到一半的时候被另一个发送函数抢断,前面一包的数据还没发完就会去发抢断的那个线程的数据,就会出现你出现的情况
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2022-10-16 15:25:06 | 显示全部楼层
用LL库实现的,1.5M波特率毫无压力:
https://blog.csdn.net/qq_2055361 ... 1001.2014.3001.5501
回复

使用道具 举报

2

主题

4

回帖

10

积分

新手上路

积分
10
发表于 2022-10-17 17:32:06 | 显示全部楼层
串口就一个线程用还是多个线程同时用?有没有加互斥锁?
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-18 14:26:44 | 显示全部楼层
Nerd 发表于 2022-10-17 17:32
串口就一个线程用还是多个线程同时用?有没有加互斥锁?

只有一个任务使用
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-18 14:49:11 | 显示全部楼层
Acuity 发表于 2022-10-16 15:25
用LL库实现的,1.5M波特率毫无压力:
https://blog.csdn.net/qq_20553613/article/details/125108990?spm= ...

谢谢  我看看
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-18 14:53:40 | 显示全部楼层
出现情况的原因好像是短时间多次调用了串口dma的发送 HAL_UART_Transmit_DMA
回复

使用道具 举报

6

主题

640

回帖

658

积分

金牌会员

积分
658
QQ
发表于 2022-10-18 20:00:59 | 显示全部楼层
服务器通过串口给两个客户端发送数据,发送客户端A没有执行完就发送客户端B了?这个肯定需要自己确认发送客户端A完成后才能发送客户端B
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-10-20 18:11:53 | 显示全部楼层
发现一个问题就是dma发送完成不进入发送完成回调,这是什么情况,UART_DMATransmitCplt
回复

使用道具 举报

4

主题

46

回帖

58

积分

初级会员

积分
58
发表于 2022-10-25 00:06:14 | 显示全部楼层
myNameIsLin 发表于 2022-10-20 18:11
发现一个问题就是dma发送完成不进入发送完成回调,这是什么情况,UART_DMATransmitCplt

你开了DMA中断向量dma_irq_handler并且在里面调用了HAL_DMA_IRQHandler了么,发送完成的中断回调实际上是DMA中断调的.
回复

使用道具 举报

5

主题

65

回帖

80

积分

初级会员

积分
80
发表于 2022-10-29 10:07:48 | 显示全部楼层
你多个发送用了一个数组,dma发送了,但是不能立即处理数组,应该是处理了导致把处理后的数据发送出去了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-12 15:19 , Processed in 0.274604 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表