我想设计一个非常简单、高效的点对点协议层,它在低端 8 位微处理器上使用 UART。它的 RAM 极其有限,而且只有最简单的算术运算。UART 处理字节的成帧,可以假设该层可以依赖这一事实。(错误检测将在更高级别上完成)。
该协议将按如下方式工作:
- 服务器和客户端无法区分
- 接收和传输是完全独立的(所以只需要考虑单向)
- 无连接且不可靠(一个帧/数据包将被发送并被遗忘)
- 帧/数据包将以start 分隔,因此在检测帧的开始时需要尽可能少的 RAM(以几个字节的顺序)。
- 帧/数据包将以结束分隔,以区分 1. 接收下一个字节的延迟和 2. 帧/数据包的结束。
我的第一个想法如下:
- 一帧的开始是由一个字节的:
00xxxxxx(其中,x可被用于指定帧的类型的更高级别的) - 帧的结尾由一个字节组成:(
11xxxxxx其中x被丢弃) - 该帧包含任意数量的内容字节:(内容
01xxxxxx在哪里x)
这意味着微处理器在等待帧开始时实际上不需要任何 RAM;它只需要在接收到的每个字节时检查它是否匹配00xxxxxx。
这个想法的问题显然是浪费带宽:每 8 位中有 2 个(加上整个结束分隔字节)。
我的第二个有缺陷的想法是用两个字节而不是一个字节做类似的事情。例如:
- 一帧的开始由一个字节组成,如上所示:
00xxxxxx - 帧的结尾也将是一个字节,如上所示:
11xxxxxx - 内容将以字节对为单位:
01xxxxxx,xxxxxxxx
但这是有缺陷的,因为内容字节对的第二个字节可能与开始或结束定界符混淆。UART 可以在没有警告的情况下随时断开和重新连接,因此该层需要有一种方法可以通过字节值找到数据包的开头。
我的逻辑失败了 - 我看不出有什么方法可以改进我的第一个版本。我一直在阅读大量不同的协议,但找不到任何可以适应的协议,更不用说按原样使用了。我的第二个想法有致命的缺陷吗?或者我只是没有意识到如何在不在 RAM 中存储太多的情况下将起始分隔符与第二个内容字节的分隔符区分开来?
欢迎任何想法,包括我可以适应或采用的协议,或对上述想法的更改。
回复评论
UDP 看起来很像矫枉过正,太高级了。我当然不需要寻址(端口或其他)。我不认为 OSI 模型可以应用于我的要求,但是我需要在数据链路层而不是稍后传输 (UDP) 上做更多的事情。它将是(可重用堆栈的一部分)通过虚拟 COM(串行)端口(使用蓝牙-UART 或 USB-UART 硬件桥接器)在主机(通常是 PC)和微处理器(PIC、Atmel)之间进行通信)。它绝不是一个一刀切的协议,而只是适合非常有限的硬件功能来执行任务,例如发送键+值对或命令+参数等,其中值/参数将是可变的长度,从 0 到超过 2^16(但可以拆分)。一些接近但也太过分的协议:
最优先考虑的是低计算要求和资源,其次是带宽效率。
微处理器总是要么在接收数据时使用数据,要么在获取数据时发送数据,这就是它们没有太多 RAM 的原因。他们也可能进行实时处理,因此他们需要处理的传输/接收数据越少越好。使用低端微处理器的原因是它们的数量很多,并且需要降低成本。