1、从GitHub或者其他网站下载最新的协议栈源码
源码结构如图所示:
其中src是协议栈源码,可直接拿来使用,apps里面是一些功能的应用示例,有BACnet IP,BACnet MSTP,BACnet Router等功能。
2、协议栈移植完成后,需要改造几个函数与自己的硬件接口想匹配才能使用
1)使用以下四个函数进行初始化工作,可参考协议栈的示例
其中Device_Set_Object_Instance_Number()用来设置本设备的ID号,通过客户端扫描出来的设备就会带上这个ID号,Init_Service_Handlers()用于设置本设备支持哪些服务,比如SERVICE_UNCONFIRMED_WHO_IS,SERVICE_UNCONFIRMED_WHO_HAS,SERVICE_UNCONFIRMED_I_AM,SERVICE_UNCONFIRMED_I_HAVE等等,开发者可根据自己要开发的设备等级去支持相应的服务,BACnet协议栈就是通过这些服务进行数据通讯的,address_init()是初始化地址缓存表,dlenv_init()是接口相关的初始化行为,只有这个初始化正确完成后才能进行IP或者MSTP相关的通讯。
2)dlenv_init()函数里面已经定义好了几种不同介质的初始化行为,有IP6,IP,MSTP,BSC,开发者可根据自己要开发的设备通讯类型去开启不同的宏定义,dlenv_init()里面最重要的是datalink_init()初始化函数
调用此函数就会跳转到对应介质的初始化函数中,如果是定义了BACDL_BIP宏定义则
在bip_init()中用户需自己实现两个socket的创建,可参考应用示例完成,比较简单;如果是定义了BACDL_MSTP宏定义,则通过dlmstp_init()去完成串口的初始化行为,串口的初始化相对麻烦点,这里对串口的初始化还附带了MSTP端口的其他接口功能初始化,如图所示
后续MSTP通讯都通过MSTP_Port来进行,用户需提前注册此接口中的一些函数,可参考如下所示
需要完成RS485接口相关的函数注册以及时间设置相关的函数,可参考如下:
然后在dlmstp_init()函数中完成初始化行为。
至此接口部分的初始化行为就完成了。
3、创建一个任务用于接收BACnet的数据,不停地调用接收端口,如下所示
至此,就基本完成了BACnet协议栈移植和数据通讯相关的工作,如果收到IP端或者485端的数据,会进入npdu_handler()函数中,最终会调用相应的服务处理信息。