如何以面向对象的形式实现串行通信协议?

Dan*_*llo 5 delphi oop communication

我正在研究使用RS232连接到PC的嵌入式设备.

我需要做一个软件来与这个嵌入式设备进行通信.

我用Delphi编程.我以前从未习惯使用面向对象.但我试图改变这一点.

我无法以面向对象的方式思考解决这个问题.

我有这个协议:

<STX><STX><COMMAND>[<DATA><DATA>...]<CHKSUM><ETX>
Run Code Online (Sandbox Code Playgroud)

哪里:

<STX> is the Start of TeXt (0x55);
<COMMAND> can be 0x01 for read, 0x02 for write, etc;
<DATA> is any value;
<CHKSUM> is the checksum;
<ETX> is the End of TeXt (0x04).
Run Code Online (Sandbox Code Playgroud)

软件计算机将通过串行发送命令,设备将使用相同的协议应答.

例如:

Reset command
PC sends     : <STX><STX><0x09><0x00><CHKSUM><ETX>
Device answer: <STX><STX><0x09><0x00><CHKSUM><ETX>

Get Version
PC sends     : <STX><STX><0x00><0x02><CHKSUM><ETX>
Device answer: <STX><STX><0x00><0x00><VER_L><VER_H><CHKSUM><ETX>
Run Code Online (Sandbox Code Playgroud)

我必须将文件流发送到设备.

我想获得以面向对象的方式实现这一点的最佳方法的建议和/或示例.我也希望能够进行单元测试.

谢谢

dth*_*rpe 5

您应该查看其他串行发送/接收通信模型,例如HTTP。在.NET中,HTTPWebRequest对象是您收集所有要通过网络发送的信息的地方-包括命令(HTTP方法:GET,PUT,POST等)和字节流。HTTPWebRequest对象(和HTTP堆栈)在内部处理“文书工作”,这些工作包括计算数据的校验和,将大数据分块为较小的数据包等。您要做的所有代码就是构造请求对象,设置命令,分配一个数据流到请求对象的属性,然后发送。

您应该查看现有通信对象模型(如.NET HTTP)的另一个原因是,从主机CPU的角度来看,串行通信通常是异步的。在串行端口上传输请求的字符时以及等待响应时,可能会花费大量CPU时间。对请求/响应使用异步模型,这样就不会阻塞调用线程并可能冻结UI。

为了继续.NET HTTP示例,HTTPWebRequest具有GetResponse方法,该方法发送请求,并将阻塞调用线程,直到收到响应为止。HTTPWebRequest还具有一个BeginGetResponse()/ EndGetResponse()对,因此您可以发送请求并提供一个回调,以便在稍后到达响应时执行该回调。

即使您的立即设计可以使用线程阻塞同步调用模型,您也至少应该研究异步编码模式,并考虑这样实现您的对象。您总是可以以线程阻塞同步的方式调用异步方法,但是以异步的方式调用同步方法要困难得多。现在花一点时间为自己提供更多选择。

  • 我不建议他使用HTTP来实现串行通信。他在询问有关如何布置对象模型的想法。他应该使用一个异步调用对象模型,而HTTP是一种广泛使用的模型,用于寻找有关在自己的异步对象模型中构建内容的想法。API的重叠I / O结构没有为如何建立方便而强大的对象模型提供任何指导。对象模型可能会利用它的底层细节,但是对象模型可能需要做的不仅仅是调用API。 (2认同)

Eri*_*tin 2

有点难以回答,但从我掌握的少量信息来看,我会这样做:

要么您的类知道如何序列化自己,要么使用访问者模式进行序列化。这样做的优点是可以将数据与序列化解耦,并让您更轻松地实现其他序列化机制。

所以我有一个数据类,一个包含数据集合(选择您喜欢的容器)的命令类。Command 类可能会通过公共方法处理校验和计算。我还将有一个通信类来封装命令并开始和结束通信。然后我有一个负责与串行端口连接的类,该类有一个 Send 方法,该方法将引用通信类。

从现有的信息来看,这就是我能想到的设计思路。

至于单元测试,通过良好的设计,您应该能够对几乎所有内容进行单元测试。请记住使用存根,您不想在测试期间访问该串行端口,因此创建一个伪造的串行通信类,例如写入字符串,并将输出的字符串与预期值规范进行比较。