Linux自定义BACNet设备实现:如何响应Read-Property请求?
问题
我正在开发一款兼容BACNet的Linux自定义设备,选定了BACNet Stack作为开发库。已成功从GitHub最新版本编译,并测试了编译目录中提供的server示例及readprop、writeprop工具(为使writeprop正常工作曾对其修改,但此非重点)。
现在我困惑于如何实现可响应Read-Property请求的设备:在server示例中,可通过以下代码注册处理函数:
apdu_set_confirmed_handler( SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
但查看h_rp.c源码时发现,其中调用了device.h中的Device_Read_Property函数,似乎重载该函数更合理。请问我是否应该重载Device_Read_Property?该库似乎缺少完整的设备实现示例。
回答
应该重载Device_Read_Property函数,这是BACnet Stack设计中让开发者自定义设备属性读取逻辑的标准方式,比直接替换handler_read_property更贴合BACnet设备模型的分层设计。
为什么选择重载Device_Read_Property
handler_read_property是APDU服务的顶层处理函数,负责解析请求报文、调度底层逻辑、组装响应报文,直接修改它会破坏库的分层结构,后续维护和扩展成本更高。Device_Read_Property是库专门预留的设备属性访问入口,所有Read-Property请求最终都会路由到这个函数,重载它就能统一处理所有属性读取请求,无需修改APDU层面的处理逻辑。
具体实现步骤
- 按照
device.h中的声明,在你的设备代码中重新实现Device_Read_Property函数,签名必须一致:BACNET_READ_PROPERTY_DATA *Device_Read_Property(BACNET_READ_PROPERTY_DATA *rp_data) - 函数内部根据
rp_data中的参数处理请求:- 通过
rp_data->object_type判断请求的对象类型(比如OBJECT_DEVICE、OBJECT_ANALOG_INPUT); - 通过
rp_data->object_instance定位具体的对象实例; - 通过
rp_data->property_id确定要读取的属性(比如PROPERTY_PRESENT_VALUE、PROPERTY_OBJECT_NAME); - 将对应设备的实际数据写入
rp_data->application_data,并设置rp_data->application_data_len,同时返回rp_data指针。
- 通过
- 对于设备不支持的对象或属性,返回对应的错误码(比如
ERROR_CODE_UNKNOWN_PROPERTY),确保符合BACnet协议规范。 - 编译时让你的实现覆盖库中默认的
Device_Read_Property(默认实现通常返回模拟数据,仅用于示例演示)。
补充说明
BACNet Stack确实没有提供工业级的完整设备实现示例,但可以结合server示例和头文件中的枚举宏(如对象类型、属性ID的定义)逐步搭建自己的设备模型。建议先从实现设备对象的核心属性(如设备名称、固件版本)入手,再逐步添加模拟输入/输出、二进制输入/输出等常用对象。
内容的提问来源于stack exchange,提问作者Alexandre Lavoie
相关产品推荐
相关产品推荐

