我有一个设备通过USB将串行数据以不同的速度和长度发送到我的程序的COM端口。
在数据中有一个数千字节的块,以特殊的不同代码开始和结束('FDDD'用于开始,'FEEE'用于结束)。由于流的长度,有时并非所有数据都是一次性收到的。
在解析之前,将所有字节组合成一条消息的推荐方法是什么?
(我负责缓冲区大小,但无法控制串行线路质量,也无法使用USB进行硬件控制)
谢谢
答案 0 :(得分:0)
实现这一目标的一种可能方法是遵循这些方针:
# variables
# buffer: byte buffer
# buffer_length: maximum number of bytes in the buffer
# new_char: char last read from the UART
# prev_char: second last char read from the UART
# n: index to the buffer
new_char := 0
loop forever:
prev_char := new_char
new_char := receive_from_uart()
# start marker
if prev_char = 0xfd and new_char = 0xdd
# set the index to the beginning of the buffer
n := 0
# end marker
else if prev_char = 0xfe and new_char = 0xee
# the frame is ready, do whatever you need to do with a complete message
# the length of the payload is n-1 bytes
handle_complete_message(buffer, n-1)
# otherwise
else
if n < buffer_length - 1
n := n + 1
buffer[n] := new_char
一些提示/评论:
handle_complete_message
通常会将buffer
的内容复制到其他位置或交换另一个缓冲区,而不是buffer
如果匆匆buffer_length
- 1,因为那样您可能会溢出答案 1 :(得分:0)
经过多次测试,我想出了以下关于我自己问题的简单解决方案(对于c#)。 显示的是最小化的简化解决方案。可以添加长度检查等。 “开始”和“结束”是任意长度的字符串标记。
public void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
SerialPort port = (SerialPort)sender;
inData = port.ReadExisting();
{
if (inData.Contains("start"))
{
//Loop to collect all message parts
while (!inData.Contains("end"))
inData += port.ReadExisting();
//Complete by adding the last data chunk
inData += port.ReadExisting();
}
//Use your collected message
diaplaydata(inData);