LC2047a 发表于 2019-7-17 15:29:11

HAL_UART_Receive_DMA 接收缓冲区将被重写

本帖最后由 LC2047a 于 2019-7-18 13:05 编辑

我想构建一个串口控制台。
接收缓冲区为32字节。(HAL_UART_Receive_DMA)
我希望它接受0字+回车,至31字+回车,然后传送到电脑。。

但是当输入超过32个字时,接收缓冲区将被重写。


如:

发送29个字节
输入 : 12345678901234567890123456789
输出 : 12345678901234567890123456789+'\0'

发送31个字节
输入 : 1234567890123456789012345678901
输出 : 1234567890123456789012345678901+'\0'

发送33个字节
输入 : 1234567890123456789012345678901AB
输出 : AB+'\0'
而我想要的是删除超过31个字所有东西。
输出 : 1234567890123456789012345678901+'\0'

补充一点,假设用户使用复制和粘贴消息(字符串)进行输入。

请帮忙解决它。





radio2radio 发表于 2019-7-19 12:34:18

LC2047a 发表于 2019-7-19 08:35
但我真的有这样的问题。
你能建议我一些上位机的软件吗?

SSCOM

LC2047a 发表于 2019-7-19 08:35:30

radio2radio 发表于 2019-7-18 13:54
另外,是否可以进行“粘贴字符串输入”,与UART的接收端的处理没有关系。在UART的RX线看来,字符都是一串一 ...

但我真的有这样的问题。
你能建议我一些上位机的软件吗?

radio2radio 发表于 2019-7-18 21:51:52

LC2047a 发表于 2019-7-18 21:23
用打字样式输入逐一字符,每个字符之间有一段时间。
但是我认为用粘贴字符串进行输入,STM32可以一次捕获 ...

必须可以一次捕获所有字符,长度不是问题。
比如要输入加密密钥,有几百上千个字节,打字肯定不行了。
再长,粘贴也不方便了,就得把字符串放到文件里面,一样可以发给UART。

LC2047a 发表于 2019-7-18 21:23:25

radio2radio 发表于 2019-7-18 13:54
另外,是否可以进行“粘贴字符串输入”,与UART的接收端的处理没有关系。在UART的RX线看来,字符都是一串一 ...

用打字样式输入逐一字符,每个字符之间有一段时间。
但是我认为用粘贴字符串进行输入,STM32可以一次捕获所有字符。

LC2047a 发表于 2019-7-18 21:07:10

radio2radio 发表于 2019-7-18 13:33
要保留缓冲区第一个的内容而不是被覆盖,你始终都要开一大的缓冲区,一般是一个“二级缓冲区”,用来保存 ...

好的! 我尝试修改代码以一个字一个字地捕获字符串。

radio2radio 发表于 2019-7-18 13:54:38

另外,是否可以进行“粘贴字符串输入”,与UART的接收端的处理没有关系。在UART的RX线看来,字符都是一串一串进来的,你不知道进来的是不是粘贴的。

是否可以粘贴,与上位机的软件有关!

radio2radio 发表于 2019-7-18 13:33:32

LC2047a 发表于 2019-7-18 08:53
谢谢你!

增加缓冲区大小,但始终它仍然有限。


要保留缓冲区第一个的内容而不是被覆盖,你始终都要开一大的缓冲区,一般是一个“二级缓冲区”,用来保存一次输入的全部字符!二级缓存与UART的接收缓存,可以是互相独立的。 每次接收1个字符的UART也能用。

上面是原理,真正做起来很简单的,使用c语言系统函数scanf():

    char str; //此二级缓存,一定要大于可能出现的最大输入字符数

    scanf("%s", str); //waiting input string
    printf("Input = %s\r\n", str);

怎么样让scanf()函数动起来,你自己在论坛上面找吧。

LC2047a 发表于 2019-7-18 12:35:27

本帖最后由 LC2047a 于 2019-7-18 12:36 编辑

radio2radio 发表于 2019-7-18 10:51
如果知道可能发生缓冲区溢出,就要:
1. 使用环形缓冲区。
2. 前面输入进来的字符要及时处理,即处理输入 ...
谢谢大家!
该程序,可以从粘贴中捕获字符串。
此功能很好用,但长时间操作无法避免/检测到缓冲区将被重写问题,然后系统发生错误。

如果减小缓冲区大小(仅允许输入一个字符)并逐个检查它。 这可以阻止输入错误,但不接受粘贴字符串输入。

似乎问题出现在HAL_UART_Receive_DMA()内部。 当缓冲区变满时,计数器将返回零(缓冲区的开始)。

在市场上其他人是怎么做?

请指教!

radio2radio 发表于 2019-7-18 10:51:50

LC2047a 发表于 2019-7-18 08:53
谢谢你!

增加缓冲区大小,但始终它仍然有限。对,增加缓冲区大小能够减少32字节的失败问题。


如果知道可能发生缓冲区溢出,就要:
1. 使用环形缓冲区。
2. 前面输入进来的字符要及时处理,即处理输入的速度要快过字符进来的速度。
3. 如果受到某些限制,不能及时处理,就要考虑降低UART的波特率。
4. 考虑输入的需求,限制非法输入,比如超长度的字串。
5. 是否需要溢出后放弃,和请求重发。
页: [1] 2
查看完整版本: HAL_UART_Receive_DMA 接收缓冲区将被重写