Arduino如何处理串行缓冲区溢出?它会丢弃最新的输入数据还是最旧的数据?缓冲区可以容纳多少个字节?
Arduino如何处理串行缓冲区溢出?它会丢弃最新的输入数据还是最旧的数据?缓冲区可以容纳多少个字节?
Answers:
对于硬件串行端口,您可以在HardwareSerial.cpp中看到缓冲区大小根据特定AVR上可用的RAM量而变化:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
对于SoftwareSerial.h中的软件串行端口,接收器缓冲区大小_SS_MAX_RX_BUFF
定义为64个字节。在这两种情况下,它都会停止尝试在接收到的数据已满时将其插入队列中,因此您可以根据从队列中检索数据的方式来混合新旧数据。
理想情况下,最好确保始终以迅速的方式清空缓冲区以避免缓冲区填充。如果您的问题与阻塞主循环的其他代码有关,则也许看一下计时器并实现一个简单的状态机。
您可以从HardwareSerial的源中看到,如果传入字节找到环形缓冲区已满,则将其丢弃:
inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
我得到的印象是,如果我将数据传输到Arduino,并且在Arduino端没有有效的数据“拉取器”,那么如果到达的数据量超出缓冲区的容量,则将其丢弃。你能确认吗?
是的,它将被丢弃。除非您实施自己的软件,否则没有软件或硬件流控制。
但是,如果使用64字节的缓冲区并以(例如)9600波特接收数据,则每1.04 ms会得到一个字节,因此填充缓冲区需要66.6 ms。在16 MHz处理器上,您应该能够经常检查缓冲区以至于缓冲区不满。如果您现在不想处理数据,那么您真正要做的就是将数据从HardwareSerial缓冲区移到您自己的缓冲区中。
从#if (RAMEND < 1000)
检查中可以看出,具有1000字节以上RAM的处理器将获得64字节的缓冲区,而那些RAM较少的处理器将获得16字节的缓冲区。
您写入的数据放置在相同大小的缓冲区(16或64字节)中。如果发送缓冲区是否已满,则发送代码“块”,等待中断以将下一个字节发送出串行端口。
如果中断被关闭,则将永远不会发生,因此您不会在中断服务程序内进行串行打印。
1/960 = 0.001042 s
-每1.04毫秒一个字节。