EC800K串口缓冲区问题

EC800K使用的是环形缓冲区,分为软件FIFO和硬件FIFO,硬件缓冲区的缓存很小,软件缓冲区的缓存很大

串口接收完数据是靠的 RX通信有两个中断,dma中断(数据接收到64byte),超时中断(接收数据字节数少于64而不产生dma中断的情况,时长40ms)。

问题
1 DMA搬运数据是直接版到了软件FIFO中去吗

2 EC800K的软件缓冲区是否为8K,当收到数据大于8k时必须将这8K的数据收满才能拿到数据吗,不能提前拿到缓冲区的数据吗

3 我不是很需要硬件流控,我本身是串口收到数据直接通过mqtt吧数据转发出去,另一个设备接收mqtt数据串口输出,mqtt的传输远大于串口的速度

1.DMA只是数据搬运单元. 负责外设搬运到内存或者内存搬运到外设;

对于EC800K模组而言,模组的串口缓冲区没有FIFO的. 就一块内存.
外设搬运到内存时: 前面的数据没读走. 后面的数据就进不来.
内存搬运到外设时: 新的数据会覆盖老的数据. 但因为DMA是填充数据后开启的. 所以没搬完前无法填充数据进去.

FIFO在QuecPython底层没做. 如果需要数据队列,那么就需要自行实现.

2.EC800K的串口缓存区为8K,并不是要到8K收满才能read获取数据,而是指单次最多read接收8K数据,串口外设发送数据给模组之后,此时模组可以通过uart.any接口判断此时未读的数据,随时可以uart.read读取缓存区的数据出来,推荐使用回调进行数据的读取,这种前提下,只要有数据到来就会触发模组的回调,在串口回调中处理数据的读取

3.硬件流控看个人,不需要的前提下,可以不启用硬件流控,当作普通串口使用,uart api介绍可以参考文档class UART - 串口通信 - QuecPython

我做了独立测试,仅使用 uart.any() 每10ms轮询。
PC 连续发送 51300B数据为50k,9600bps。
结果 uart.any() 并没有实时返回未读数据,而是在连续流下首次返回 8191B,之后也是约8191B一批:

first any=8191B
total=8191B
total=16382B
total=24573B
total=32764B
total=40955B

请确认为什么 any() 在连续接收时不是随时可读,而是约8191B才可见。

@zxc123 您好. 正常uart.any()是返回串口BUFF内已经接收的数据量不是数据本身. 需要读具体数据需要uart.read(uart.any())去读取.

但看您说约8191B才可见(没太明白这是啥意思). 另外您脚本中是否还使用了串口回调去接收数据?

目前信息不太全面. 可以反馈下固件版本及测试脚本看下.

固件版本:
QPY_OCPU_V0004_EC800K_CNLC_FW

产品型号:
EC800K

您好,我知道 uart.any() 返回的是未读数据长度,不是数据本身。

我的测试逻辑是:
count = uart.any()
if count:
data = uart.read(min(count, 64))

测试脚本没有使用串口回调,只使用 uart.any()/uart.read() 每10ms轮询。检测接收到自己的数量10ms一轮询,如我现在测试的50K数据,我必须收满这8K的数据才能拿到数据真正的数据和数据的长度

串口参数:
UART2, 9600, 8N1, flowctl=0

PC发送:
USB转串口连续发送 51300 字节,9600bps,不人为插入间隔。

现象:
uart.any() 前面一直返回 0,直到约 8191B 后第一次返回 8191。之后 read 64B 后,any() 变成 8127、8063、7999…,说明缓存里一次性出现了 8191B。

关键日志:
idle any=0 elapsed=21181ms total=0B
first any=8191B at 22111ms
any=8191B read=64B reads=1 total=64B
any=8127B read=64B reads=2 total=128B
any=8063B read=64B reads=3 total=192B

我也测试过 callback 模式,第一次回调也是:
result=[0, 2, 8191]

@zxc123 我们先验证下看下效果. 预计后天下班前有有初步结论. 您届时关注下. :folded_hands:

@zxc123 您好. 本现象我内部确认了下. 情况如下:

DMA搬运串口数据, 并非直接搬运至Python脚本层获取的BUFF内部. 而且存在一个中间层. 中间层通过拷贝动作将数据拷贝至Python层BUFF内(这也是接收数据过程中uart.any函数始终为0的原因). 拷贝动作有两种触发条件: 1. DMATimeOut中断; 2. DMA_BUFF满溢出中断.

目前8191(8K-1)字节才能获取的原因为DMA_BUFF满溢出中断. 部分时间出现非8191(8K-1)字节情况怀疑为出现了DMATimeOut中断, 需要确认需要复现抓取数据波形数据才能确认.

经过测试无论方式接收数据并未有数据丢失现象(见附件图片). 这种情况下是否对您项目数据处理产生影响? 我们对比了SSCOM发送端口一次性发送较多数据, 每包均为8191(8K-1)字节. 目前看这部分处理逻辑符合我们设置逻辑, 并未BUG情况. 欲规避需要数据波形符合要求.