FIBERIOT / 基础知识
串口线上传来一串字节,接收程序怎样知道一份报文已经结束?一种办法是约定特殊标记。但如果测量值或文件内容本身恰好含有这个标记,直接发送就会被误认成结束。字节转义正是为了解决这种“数据长得像控制符”的问题。理解它,需要把字符接收、报文边界和业务含义分开看,而不只是检查波特率。

01字符接收正确,还不等于报文已经分好
常见异步串口用起始位、数据位和停止位帮助接收器识别一个字符。接收器把字符交给程序后,程序看到的是连续字节,并不会因为某一串字节恰好是温度读数,就自动知道读数从哪里开始、在哪里结束。字符边界和完整报文边界属于不同层的问题。
应用协议可以使用固定长度、长度字段、间隔时间或特定标记等办法划分报文,各自都有适用条件。本文讨论标记法,并借SLIP这个简单的串行封装例子解释字节转义;不表示所有串口协议都采用SLIP,也不建议把现有设备的协议随意改掉。
飞畅FCT-1100-F1S1单路三合一串口服务器提供串行设备接入网络的真实产品背景。它让人容易看见一个工程边界:字节经过接口或网络转发,并不自动获得新的业务含义。本文不据此推定该型号内部使用什么分帧协议,具体能力仍以对应资料和配置为准。
02一个标记,为什么会有两种身份
假设双方约定某个字节表示结束。接收器读到它时,就把此前缓存的数据交给后续程序。这种办法很直观:就像阅读一段话时通过标点识别句子。但二进制数据并不像普通文字那样,可以保证某个数值永远不会出现在内容中。
例如,一份测量记录可能包含任意字节;如果其中一个字节正好和结束标记相同,接收程序便面临歧义:它到底是内容的一部分,还是划定边界的信号?单看这个字节的数值,无法同时得到两种答案。需要在发送前增加双方共同理解的表达规则。
不能简单要求“所有数据都避开这个数”。这样会限制原始数据能够表达的范围,甚至悄悄改变数值。也不能指望换成光纤后歧义自然消失:光电转换改变承载形式,不会替应用协议解释每一个字节的角色。线路质量与编码约定需要分别处理。
03转义,是换一种表达,不是把数据删掉
可以把转义理解为给特殊内容加一个提示:“接下来不是普通控制动作,请按约定还原成数据。”发送端扫描原始内容,遇到需要保护的字节,就发送替代序列;接收端按反方向规则恢复。双方最终应得到同一份原始内容。
以RFC 1055描述的SLIP为例,用十六进制表示时,END是C0,ESC是DB。数据里的C0转换为DB DC,数据里的DB转换为DB DD,真正的结束边界仍用未被转义的C0表达。这里的数值专属于这个例子,不能照搬给其他协议。
为什么连DB本身也要处理?因为它承担“下一字节需要特别解释”的作用。如果原始DB不加区分就传输,接收器可能把后面的普通数据误当成转义后缀。转义规则不仅要保护结束标记,也要保护用来解释规则的提示符,才能避免新的歧义。

04沿着一小段数据,看看变化发生在哪里
假设原始内容依次为11、C0、22、DB、33。中间两个特殊字节不能直接原样放在带标记的线上。编码后,内容变成11、DB DC、22、DB DD、33;在边界处再放置实际的END,接收方才能把线上的控制角色与还原后的内容区别开。
这个演示采用报文前后均放C0的形式。RFC 1055提到在开头也发送END的做法,帮助清理此前积累的异常字节;连续边界产生的空内容不应当成正常IP报文交付。不要把这个示例理解成所有协议都要求前后各一个相同标记。
还原完成后,中间的C0和DB重新成为普通数据,边界标记本身不属于交付内容。于是线上发送的字节数可能比原始内容多。串口服务器计数、抓包字节数和应用收到的长度若位于不同处理层,就不能只凭数值不同立即认定发生丢字节。
05接收程序需要记住自己处在哪种状态
接收器不是拿到一个字节就独立判断完毕。至少需要区分“普通读取”和“已经遇到转义提示、正在等待后缀”这两种状态。在普通状态下,结束标记表示报文边界;遇到DB,则切换为等待后缀,而不是立即把DB当作原始数据输出。
在等待后缀状态下,接收器根据约定恢复特殊数据,再返回普通读取。这个过程说明,两个字节之间的联系由接收状态维持,不依赖它们必须出现在同一次软件读取里。程序本次只读到DB,下次才读到DC,仍应保留并正确完成这一状态转换。
实际实现还要约定异常后缀、缓存上限、空报文和中途断线怎样处理。本文没有把某一种异常策略说成所有协议的统一答案。若上层程序在每次收到网络数据时都清空解析状态,或者把网络读取次数当作报文次数,即使传输没有损坏,拆帧仍可能出错。

06找到边界,不代表完成差错与安全检查
转义主要解决表达歧义,不会自动补上校验、重传、身份认证或加密。能够把一串字节重新分成若干段,并不证明每一段都正确,也不证明发送者可信。SLIP本身提供的能力很有限,因此不能把它当成工业控制安全协议的通用替代品。
不同协议的校验与转义顺序也不能凭印象套用。例如PPP的HDLC式封装有自己的标志、透明传输和帧校验规定,其转义细节并不等于SLIP。把两者的标记值、后缀规则或校验阶段混在一起,可能导致双方都接收到字节,却永远不能接受报文。
工程核对时应画出原始业务数据、封装编码、物理或网络传输、解码和业务校验的位置。看到通信错误,先确认采集点处在哪一层,再比较编码前后应有的内容。不要拿转义后的序列直接与解码后的业务字段逐字节比对,制造出并不存在的故障。
07用可重复的小样本核对双方约定
测试应从设备和协议资料开始,保存版本、接口配置、打包方式和抓取位置。准备普通数据、包含结束标记的数据、包含转义字节的数据以及连续特殊字节等样本,逐项核对编码与还原结果。样本是方法演示,不是任何产品已经完成的实测报告。
随后检查分次到达、粘连到达和连接中断等实现需要覆盖的条件。测试在授权环境中使用无危险业务含义的数据,不把示例字节直接当成生产设备的控制指令。若双方使用的协议不同,应先澄清协议与转换职责,而不是反复调整波特率碰运气。
初学者可以记住:UART负责识别字符,分帧规则负责识别报文,转义负责让内容中的特殊值不被误当成控制符。把这三层分清,就能理解为什么端口收到了字节,应用却可能仍然读不出一份完整的数据。
资料依据
RFC 1055:SLIP,1988年6月,非Internet标准;RFC 1662:PPP的HDLC式封装,1994年7月。产品背景:飞畅FCT-1100-F1S1串口服务器,不据此宣称产品采用SLIP。具体协议、校验和异常策略需按设备资料核对。
现场常见问题
串口能收到字符,就能自动识别报文吗?
不能。UART字符接收与应用分帧是不同层次;报文边界要由双方的协议约定解释。
SLIP中数据C0和DB怎样转义?
内容C0替换为DB DC,内容DB替换为DB DD;未转义的END标记承担边界作用。规则不适用于所有串口协议。
字节转义能代替校验或加密吗?
不能。转义解决数据与控制符的表达歧义,不自动提供差错检测、重传、身份认证或加密。
适用边界与延伸阅读
通用串口分帧与SLIP转义示例,不是特定产品协议或实测数据。


