使用 uart select 接收超时的问题

tuweidong
Posts: 4
Joined: Fri Nov 23, 2018 11:58 pm

使用 uart select 接收超时的问题

Postby tuweidong » Sat Nov 24, 2018 12:37 am

在使用uart的select来接收数据时, 传入read函数的buflen小于输入缓冲区内已经接收到的数据, 仅在第一次调用select函数时可以正确的执行,然后recv 指定长度的数据;
当我第二次调用select函数时, 它会提醒我timeout,但是此时输入缓冲区内依然还有数据没有被recv;
当然,每一次调用select之前都已经使用FD_ZERO和FD_SET函数来清理套接字集合.

可以在例程peripherals/uart_select上进行简单改造来重现这一现象:
1. 将UART_NUM_0修改为UART_NUM_1或者UART_NUM_2, 相应的修改相关的参数, recv接收长度设置为1
2. 串口工具连接uart接口, 通过串口工具 发送一次 0x02 0x03
3. 观察程序打印的接收到的数据, 可以看到只接收到0x02 ,然后提示timeout
4. 通过串口工具再次发送 0x02 0x03, 可以看到打印出来的字符为0x03, 证明上一次接收到的0x03在输入缓冲区内.

我该如何解决此问题呢? 谢谢

tuweidong
Posts: 4
Joined: Fri Nov 23, 2018 11:58 pm

Re: 使用 uart select 接收超时的问题

Postby tuweidong » Sat Nov 24, 2018 10:43 am

如果接收数据量累计大于rx_buf_size的大小, select将永远无法接收到数据 ,

ZHDX227
Posts: 16
Joined: Thu Oct 25, 2018 4:43 am

Re: 使用 uart select 接收超时的问题

Postby ZHDX227 » Sun Nov 25, 2018 6:49 am

我在做USB绑定的UART0通讯时, 遇到一些类似的问题.

当我向芯片发送大量数据时, 例如8K字节

如果芯片此时没有使用printf, 则可以完全发送.

如果刚好此时又printf输出字符串,

这个时候发送的数据便存在2个问题

1 - 数据的位置乱了, 例如 1234567890 会变成 1238945670

2 - 芯片内的代码无法读取完整的数据, 总有一些数据卡着等待接收.
例如发 aaa bbb ccc ddd 这些数据, 肯可能只收到 aaa bbb ccc d , 剩下dd 收不到. 如果此时再发送eee过去, 则芯片收到的是dd , 而eee又收不到. 这个现象一旦放生, 通过esp_restart()是清除不了的. 必须硬重启一下.

查看了一下源代码, 发现控制台的输入输出的代码并不是开源的. 没办法再调试下去了.

uart的代码则是开源的, 不过看来控制台输入输出与uart.c一点关系都没有.

我是希望这个问题能够解决的. 目前我为了避开这个问题, 是采取每0.01秒最多发送64字节的方式来控制发送频率.

不知道楼主你遇到的问题, 是不是rx/tx在同时发数据?

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: 使用 uart select 接收超时的问题

Postby ESP_houwenxiang » Mon Nov 26, 2018 6:40 am

Hi,
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.
tuweidong wrote:
Sat Nov 24, 2018 10:43 am
如果接收数据量累计大于rx_buf_size的大小, select将永远无法接收到数据 ,
thanks !!
wookooho

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: 使用 uart select 接收超时的问题

Postby ESP_houwenxiang » Mon Nov 26, 2018 6:42 am

ZHDX227 wrote:
Sun Nov 25, 2018 6:49 am
我在做USB绑定的UART0通讯时, 遇到一些类似的问题.

当我向芯片发送大量数据时, 例如8K字节

如果芯片此时没有使用printf, 则可以完全发送.

如果刚好此时又printf输出字符串,

这个时候发送的数据便存在2个问题

1 - 数据的位置乱了, 例如 1234567890 会变成 1238945670

2 - 芯片内的代码无法读取完整的数据, 总有一些数据卡着等待接收.
例如发 aaa bbb ccc ddd 这些数据, 肯可能只收到 aaa bbb ccc d , 剩下dd 收不到. 如果此时再发送eee过去, 则芯片收到的是dd , 而eee又收不到. 这个现象一旦放生, 通过esp_restart()是清除不了的. 必须硬重启一下.

查看了一下源代码, 发现控制台的输入输出的代码并不是开源的. 没办法再调试下去了.

uart的代码则是开源的, 不过看来控制台输入输出与uart.c一点关系都没有.

我是希望这个问题能够解决的. 目前我为了避开这个问题, 是采取每0.01秒最多发送64字节的方式来控制发送频率.

不知道楼主你遇到的问题, 是不是rx/tx在同时发数据?
请问这个问题也是在使用 uart_select 时遇到的吗?
wookooho

tuweidong
Posts: 4
Joined: Fri Nov 23, 2018 11:58 pm

Re: 使用 uart select 接收超时的问题

Postby tuweidong » Mon Nov 26, 2018 7:14 am

ESP_houwenxiang wrote:
Mon Nov 26, 2018 6:40 am
Hi,
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.
tuweidong wrote:
Sat Nov 24, 2018 10:43 am
如果接收数据量累计大于rx_buf_size的大小, select将永远无法接收到数据 ,
thanks !!
你好:
第二个问题的现象: 当select后每次接收的数据量小于发送的数据量, 多次发送数据后, 应用层接收不到任何数据, 可能是接收缓冲区或者接收fifo满了.

tuweidong
Posts: 4
Joined: Fri Nov 23, 2018 11:58 pm

Re: 使用 uart select 接收超时的问题

Postby tuweidong » Mon Nov 26, 2018 7:18 am

ZHDX227 wrote:
Sun Nov 25, 2018 6:49 am
我在做USB绑定的UART0通讯时, 遇到一些类似的问题.

当我向芯片发送大量数据时, 例如8K字节

如果芯片此时没有使用printf, 则可以完全发送.

如果刚好此时又printf输出字符串,

这个时候发送的数据便存在2个问题

1 - 数据的位置乱了, 例如 1234567890 会变成 1238945670

2 - 芯片内的代码无法读取完整的数据, 总有一些数据卡着等待接收.
例如发 aaa bbb ccc ddd 这些数据, 肯可能只收到 aaa bbb ccc d , 剩下dd 收不到. 如果此时再发送eee过去, 则芯片收到的是dd , 而eee又收不到. 这个现象一旦放生, 通过esp_restart()是清除不了的. 必须硬重启一下.

查看了一下源代码, 发现控制台的输入输出的代码并不是开源的. 没办法再调试下去了.

uart的代码则是开源的, 不过看来控制台输入输出与uart.c一点关系都没有.

我是希望这个问题能够解决的. 目前我为了避开这个问题, 是采取每0.01秒最多发送64字节的方式来控制发送频率.

不知道楼主你遇到的问题, 是不是rx/tx在同时发数据?
你好
我的rx/tx并不是同时在收发数据, 是否可以提高uart0的波特率来试一下?

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: 使用 uart select 接收超时的问题

Postby ESP_houwenxiang » Mon Nov 26, 2018 8:04 am

tuweidong wrote:
Mon Nov 26, 2018 7:14 am
ESP_houwenxiang wrote:
Mon Nov 26, 2018 6:40 am
Hi,
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.
tuweidong wrote:
Sat Nov 24, 2018 10:43 am
如果接收数据量累计大于rx_buf_size的大小, select将永远无法接收到数据 ,
thanks !!
你好:
第二个问题的现象: 当select后每次接收的数据量小于发送的数据量, 多次发送数据后, 应用层接收不到任何数据, 可能是接收缓冲区或者接收fifo满了.
好的,明白了. 缓冲区满了之后驱动层会关闭中断.之后就无法接收到中断里抛出的信号量. 只要第一个问题解决了这个问题也就不会出现了.我们会尽快解决这个问题的.

thanks
wookooho

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: 使用 uart select 接收超时的问题

Postby ESP_houwenxiang » Mon Nov 26, 2018 8:09 am

tuweidong wrote:
Mon Nov 26, 2018 7:18 am
ZHDX227 wrote:
Sun Nov 25, 2018 6:49 am
我在做USB绑定的UART0通讯时, 遇到一些类似的问题.

当我向芯片发送大量数据时, 例如8K字节

如果芯片此时没有使用printf, 则可以完全发送.

如果刚好此时又printf输出字符串,

这个时候发送的数据便存在2个问题

1 - 数据的位置乱了, 例如 1234567890 会变成 1238945670

2 - 芯片内的代码无法读取完整的数据, 总有一些数据卡着等待接收.
例如发 aaa bbb ccc ddd 这些数据, 肯可能只收到 aaa bbb ccc d , 剩下dd 收不到. 如果此时再发送eee过去, 则芯片收到的是dd , 而eee又收不到. 这个现象一旦放生, 通过esp_restart()是清除不了的. 必须硬重启一下.

查看了一下源代码, 发现控制台的输入输出的代码并不是开源的. 没办法再调试下去了.

uart的代码则是开源的, 不过看来控制台输入输出与uart.c一点关系都没有.

我是希望这个问题能够解决的. 目前我为了避开这个问题, 是采取每0.01秒最多发送64字节的方式来控制发送频率.

不知道楼主你遇到的问题, 是不是rx/tx在同时发数据?
你好
我的rx/tx并不是同时在收发数据, 是否可以提高uart0的波特率来试一下?
Hi, 数据的接收和发送硬件上相互之间是不会影响的. 你的问题是指发送数据的同时使用 printf 导致数据出错还是指 tx 和 rx 之间会有影响?
thanks !!
wookooho

ZHDX227
Posts: 16
Joined: Thu Oct 25, 2018 4:43 am

Re: 使用 uart select 接收超时的问题

Postby ZHDX227 » Tue Nov 27, 2018 12:14 am

ESP_houwenxiang wrote:
Mon Nov 26, 2018 8:09 am
Hi, 数据的接收和发送硬件上相互之间是不会影响的. 你的问题是指发送数据的同时使用 printf 导致数据出错还是指 tx 和 rx 之间会有影响?
thanks !!

在周末做了一下测试. 有了一些基本的结论.
做法 : 用一个task每隔一段时间用fread或fget来读取数据.

现象 , 如果每隔0.01秒读取数据, 那么运作正常 , 如果每隔0.1秒读取数据, 会大量丢包.

设置为每0.001秒读取数据, 然后运行一些非常消耗CPU的其他task , 会出现丢包现象.

这可以通过先发送一个要求准备通信的命令, 用 vTaskSuppendAll 来停止其他task , 缓解这现象.

不知道除了fread/fget这种方法, 还有没有其他更直接的方法去读取uart0的数据?


第二个问题, 应该是bug,

在读取数据的时候, 会出现1个字节的数据滞留缓冲区的现象.

例如 , 发送一批字节 0123456789....0123456789

有可能只接收到 0123456789....012345678

最后面那个 9 , 无论等待多长时间, 都读不到.

这时, 如果发送 ABCDEFG 过去 , 那么程序只能读到 9ABCDEF ,

这次轮到G是无法等待得到, 必须有下一批数据到达了才能读取.

而这个情况会逐渐恶化, 慢慢积累2个字节, 3个字节..

到了一定数量之后, 便出现字符乱序的现象, 0123456789发送过去直接会变成 0128934567

漏掉的字符, 可以通过 增加 大量的 \n\n\n\n\n\n\n\n\n\n 来解决. 漏就让 \n 放在尾巴好了.

但一旦出现字符乱序的现象, 就无法再进行通信了. 必须重启芯片了.


另外一点是, 一开始uart0是不使用uart.c里的代码的. 好像是非开源的lib里完成了这事情.
而通过执行 uart_param_config , uart_driver_install 后, uart.c里的代码有反应了, uart_rx_intr_handler_default也被调用了
然而使用uart.c里的逻辑, 上面的问题依然存在.

这样我的确可以作更深入的调试. 这星期太忙. 也许安排在下个月, 调试得出结论再回来回帖分享一下发现.

不排除是usb或者是cp2012的原因, 又或者是windows API或System.IO.Ports.SerialPort的问题.

Who is online

Users browsing this forum: No registered users and 32 guests