使用 uart select 接收超时的问题
使用 uart select 接收超时的问题
在使用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在输入缓冲区内.
我该如何解决此问题呢? 谢谢
当我第二次调用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在输入缓冲区内.
我该如何解决此问题呢? 谢谢
Re: 使用 uart select 接收超时的问题
如果接收数据量累计大于rx_buf_size的大小, select将永远无法接收到数据 ,
Re: 使用 uart select 接收超时的问题
我在做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在同时发数据?
当我向芯片发送大量数据时, 例如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在同时发数据?
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: 使用 uart select 接收超时的问题
Hi,
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.
thanks !!
wookooho
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: 使用 uart select 接收超时的问题
请问这个问题也是在使用 uart_select 时遇到的吗?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在同时发数据?
wookooho
Re: 使用 uart select 接收超时的问题
你好:ESP_houwenxiang wrote: ↑Mon Nov 26, 2018 6:40 amHi,
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.thanks !!
第二个问题的现象: 当select后每次接收的数据量小于发送的数据量, 多次发送数据后, 应用层接收不到任何数据, 可能是接收缓冲区或者接收fifo满了.
Re: 使用 uart select 接收超时的问题
你好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的波特率来试一下?
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: 使用 uart select 接收超时的问题
好的,明白了. 缓冲区满了之后驱动层会关闭中断.之后就无法接收到中断里抛出的信号量. 只要第一个问题解决了这个问题也就不会出现了.我们会尽快解决这个问题的.tuweidong wrote: ↑Mon Nov 26, 2018 7:14 am你好:ESP_houwenxiang wrote: ↑Mon Nov 26, 2018 6:40 amHi,
你遇到的第一个问题是因为 select 会等待一个信号量, 这个信号量只有在中断里才会 give, 所以导致了已经缓冲的数据无法读取到. 我们的工程师会尽快解决这个问题的. 第二个问题可以描诉的详细一点吗?有可能是缓冲区溢出导致的,我们得确认一下.thanks !!
第二个问题的现象: 当select后每次接收的数据量小于发送的数据量, 多次发送数据后, 应用层接收不到任何数据, 可能是接收缓冲区或者接收fifo满了.
thanks
wookooho
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: 使用 uart select 接收超时的问题
Hi, 数据的接收和发送硬件上相互之间是不会影响的. 你的问题是指发送数据的同时使用 printf 导致数据出错还是指 tx 和 rx 之间会有影响?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的波特率来试一下?
thanks !!
wookooho
Re: 使用 uart select 接收超时的问题
ESP_houwenxiang wrote: ↑Mon Nov 26, 2018 8:09 amHi, 数据的接收和发送硬件上相互之间是不会影响的. 你的问题是指发送数据的同时使用 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: sanmaodeai and 60 guests