#嵌入式设备 #网络 #读写 #无标准库 #BACnet

无标准库 嵌入式-BACnet

嵌入式系统(无标准库)的 BACnet 库

3 个版本 (破坏性更新)

0.3.0 2024 年 5 月 11 日
0.2.0 2023 年 11 月 24 日
0.1.0 2023 年 11 月 16 日

314嵌入式开发 中排名

Download history 166/week @ 2024-05-09 12/week @ 2024-05-16 4/week @ 2024-05-23

每月下载量 170

Apache-2.0

240KB
6.5K SLoC

嵌入式 Bacnet

an obscure reference to a movie

"愿我永不完美。愿我永不满足。愿我永不完美。" —— 查克·帕拉尼科,《搏击俱乐部》

这是一个用于嵌入式设备读取和写入 BACnet 报文的 Rust 库。BACnet 是一种用于建筑自动化和控制的协议。官方规范不幸地被付费墙挡住,因此这个实现是通过交叉引用多个代码实现拼凑而成的。我找到的最全面的实现和文档在这里:https://bacnet.sourceforge.net/,我对此非常感激。这也是一个好资源:http://www.bacnetwiki.com/wiki/

您可以使用此库发送和接收 BACnet 报文。但是,尚未实现整个规范,仅实现了我认为最重要的部分。如果您需要全面实现,请使用上述链接。

此库不需要标准库或内存分配器,因此当您解码网络报文时,请预期将使用迭代器和循环。

工作原理

BACnet 是一种可以在许多传输协议之上工作的协议。此实现仅与使用 UDP 报文的 BACnet IP 一起工作。像许多协议一样,这个也有层。一个应用层包裹在网络层中,网络层包裹在数据链路层中,数据链路层包裹在 UDP 报文中。如下所示

UdpPacket
|
-> DataLink (about the connection)
   |
   -> NetworkPdu (flags and the reason for the message)
      |
      -> ApplicationPdu (the payload)

其中 Pdu 代表协议数据单元。

这是一个典型的 BACnet 客户端使用此库的方式:向标准的 BACnet 端口发送老式的广播 UDP 报文,并监听同一端口的回复。这是使用未确认的 who_is pdu(协议数据单元)完成的。当通过解码不可避免的 i_am 未确认响应找到控制器时,客户端可以发送 UDP 报文直接到该控制器。一个典型的请求可能是一个已确认的 property_read pdu,以从控制器获取对象列表。已确认请求带有标识符,以便控制器可以响应发送的确切请求。

为什么要构建这个

我对所有的缩写和假设的已知知识感到沮丧,并希望制作一个初学者更容易使用的工具。例如,我会倾向于使用冗长的文件名,如 read_property.rs 而不是 rp.c。我假设用户会使用带有自动完成的语言服务器,如 rust-analyzer。现有的 Rust 实现似乎已被放弃,而现代 Rust 的功能提供了新的建模选项,因此这个库采用了相当不同的方法。

设计理念

我希望制作一个易于导航的库。因此,我选择不使用特质来抽象事物,因为在大多数情况下这并不必要,我真的讨厌导航的黑洞。代码布局应该尽可能清晰,您不需要阅读整个代码库就能找到您想要做的事情。

关于参考 C 实现的说明

以下说明适用于以下位置的 C 代码库:https://bacnet.sourceforge.net/ 我发现最重要的部分是位于 src/bacnet/basic/service 文件夹中,该文件夹处理堆栈的应用部分。使用的缩写有一些意义。例如,h_rpm.c 表示 handle_read_property_multiple,用于编码和解码 read_property_multiple 确认请求。此外,h_rpm_a.c 表示 handle_read_property_multiple_acknowledgements,用于编码和解码对上述请求的响应。

单元测试

当我有更多时间时,将会提供单元测试。请暂时使用示例。

了解内部结构

这个库的核心是一个 bacnet 编码器/解码器。因为它不分配内存,并且我们必须处理不同数量的事物(例如,一个 bacnet 报文可以包含任何数量的对象),编码和解码部分有不同的表示。例如,如果您想要编码对象列表,您将从一个容器传递一个切片,因为您事先知道要包含在报文中的对象数量。在解码事物列表时,我们使用迭代器,以便用户可以将这些对象收集到向量中,或者简单地即时处理它们。在内部,这表示为一个读取器,它可以从字节数据缓冲区中即时解码对象。

依赖项

~46–305KB