用于嵌入式微处理器开发的BACnet协议栈源码
- 格式:pdf
- 大小:587.84 KB
- 文档页数:93
3.2.3 楼宇自控网络协议BACnet (2)3.2.3.1 BACnet 的历史 (2)3.2.2.2 BACnet 的主要内容 (2)3.2.2.3 BACnet 与生产商 (8)3.2.2.4 BACnet 与工程商 (11)3.2.2.6 BACnet 的前景 (13)3.2.3 楼宇自控网络协议BACnetBACnet是Building Automation and Control Networks 的缩写,它是针对楼宇自控领域的标准,制定这个标准的目的是为了使不同生产商提供的控制设备能够互操作,也使业主不再依赖特定的私有技术。
BACnet是暖通空调行业唯一的国际标准。
3.2.3.1 BACnet 的历史BACnet 的研发工作始于1987 年,专门在美国暖通空调和制冷工程师协会(ASHREA)下面成立了BACnet标准设计委员会(SPC135)并在美国T ennessee省Nashville市召开第一次会议。
- 历经8年半的发展;- 由12个国家的81位专家提出了741条建议并进行了3次公众发布;- 1995年6月由美国暖通空调和制冷工程师协会(ASHREA)首次发布,并于当年成为美国国家标准,编号为:ANSI/ASHRAE 135-1995;- 2001年发布更新的标准ANSI/ASHRAE 135-2001;- 2003年1月BACnet成为了建筑行业ISO国际标准,标准号:ISO 16484-5;- BACnet产品适用于 HVAC, 消防, 照明, 安防等领域;- 可用的产品包括控制器, 网关, 路由器和诊断工具等;- BACnet在 ASHRAE 的持续资助下得到发展;- 公众或委员会成员可在任何时间提出对协议的改变建议;- 所有的改变必须经过公众讨论和认可;- SSPC 135 (BACnet标准设计委员会 135) 负责与CEN (欧洲), ABOK(俄罗斯)和 IEIEJ(日本)的联系。
msstatePAN — (一个公开源码的 Zigbee 协议栈)作者简介:Robert Reese,an associate professor in the Electrical & Computer Engineering department at Mississippi State University. 我简称R教授,是在参考Microchip Zigbee stack 的基础上自己编写的,基于 Zigbee1.0 ,支持硬件平台 CC2430 和PIC184620+CC2420 ,里面好像也有MSP430.其中Zigbee各个层的源码都是公开的,而且里面的实验历程也比较多,还有一个很好的说明手册。
个人认为代码写得不够规范,网络地址是静态分配的(只支持树状路由,而没有 AODV路由)对于想深入研究zigbee协议栈还是很有帮助的,链接如下所示:/~reese近来想用RSSI来测量节点间的距离,在用TI协议栈时代码量太大下载个程序老费劲了。
还是考虑用丢弃已久的R教授的协议栈,简称zigbee精简协议栈,在网上看到一篇相关的文章,顺便也总结一下。
1 ZigBee精简协议栈简介美国密西西比州立大学的Robert Reese教授出于教学、科研目的开发出一套精简版(subset)ZigBee协议栈。
标准协议栈和精简协议栈的功能对比如表1所列,可以看出,精简协议栈实现了ZigBee 的主要功能。
国内一些研究机构在此精简协议上进行扩充,实现了一些其原本不具备的功能。
这里再补充一些术语概念,这有助于理解协议栈的代码结构。
IEEE Address节点的8位802.15.4网络地址,也称为长地址。
Network Address节点的2位网络地址,也称短地址。
PAN个人局域网。
PAN ID个人局域网标识符。
HAL协议栈物理抽象层。
PHY协议栈物理层。
MAC协议栈媒体访问控制层。
NWK协议栈网络层。
Nand Flash闪存的使用I=0 (0~63) 0 1I=1(64~127) 64 65I=2128 129Shell #nbadBad block0x000000EA 234 0x01d40000Bad block0x000000EC 236 0x01d80000Bad block0x000000F4 244 0x01e80000Bad block0x000000F6 246 0x01ec0000Bad block0x000010A8 4264 0x21500000Bad block0x00001938 6456 0x32700000Bad block0x0000193A 6458 0x32740000Tarena# nand eraseTarena# tftp 20008000 ImageTarena# nand erase 1200000 c00000Tarena# nand write 20008000 1200000 c00000CPU依靠指令来计算和控制系统,每款CPU在设计时就规定了一系列与硬件电路相配合的指令系统。
最为主流体系结构来讲,指令集分为:复杂指令集和精简指令集精简指令集RISC:简单,指令的功能更加单一复杂指令集CISC:精简指令集RISC:1.指令功能简单,尽可能做到单周期执行2.指令定长(32位,16位)X86指令不定长,8位,16位,24位,32位3.所有数据运算都是在CPU的寄存器里面完成,速度快4.要求寄存器数量多5.专门拿出一类指令和存储器打交道取指地址 F正在执行地址 E的关系?0 ADD4 SUB8 AND1ADD 取指2SUB 取指 ADD解码3AND 取指 SUB解码 ADD执行PC 是寄存器,CPU寄存器,取指地址执行的地址=PC-8ARM编程模型:1.工作模式:管理SVC:复位、SWI指令快速中断:发生高优先级的中断中断:发生低优先级的中断中止:访问存储器非法情况未定义:执行指令时,不能识别系统:权限高用户:权限受限2.工作模式分类:权限:特权模式:其余6种模式非特权模式:用户模式异常/非异常:异常模式:管理、快速中断、中断、中止、未定义非异常模式:系统、用户3.状态之间切换:ARM状态:执行ARM指令,PC字对齐,最后两个bit为00Thumb状态:执行Thumb指令,PC半字对齐,最后一个bit为0 切换方式:指令切换:BX处理器自动切换:发生异常时,自动进入到对应模式用指令切换:1.特权模式之间可以随意切换2.可以从特权模式切换到用户模式3.但是不能从用户模式切换到特权模式4.如果用户模式想进入特权模式,可以通过调用SWI指令R0-R15,CPSR,SPSR等所有的寄存器对于软件来说,都是没有地址的。
源程序代码清单:#include<reg51.h>#define uchar unsigned char //宏定义#define uint unsigned int //宏定义sbit rs=P3^4; //液晶数据/指令选择端:1-数据,0-指令sbit lcden=P3^5; //液晶使能控制端:下降沿有效sbit shift_key=P3^2; //调位键sbit up_key=P3^3; //增加键sbit confirm_key=P3^6; //确认键uchar temp=0; //定义定时器溢出计数变量,每隔62.5ms 产生1次溢出,temp加1uint year=2012; //定义年变量并赋初值2012年uchar month=03,day=20,week=1;//定义月、日、星期变量,并赋初值3月20日uchar hour=0,minute=00,second=00;//定义时、分、秒变量,并赋初值00时00分00秒uchar codeweek_string[7][4]={"MON","TUE","WED","THU","FRI","SAT","SUN"};//定义星期英文缩写表uchar data month_day[12]={31,0,31,30,31,30,31,31,30,31,30,31};//定义每月天数表/*--定时计数器T0及中断初始化函数--*/void init(void){ TMOD=0x01; //设置定时器0为工作方式1TH0=(65536-50000)/256+5/256;//16位计数初值除以256得到高8位初值,加5/256为消除实际累计误差TL0=(65536-50000)%256+5%256;//16位计数初值除以256的余数得到低8位初值,加5%256为消除实际累计误差EA=1; //开总中断ET0=1; //开启定时器0中断EX0=1; //开启外部中断,外部中断用于调整时间PT0=1; //将定时器0中断设置高优先级,调整时间期不停止计时TR0=1; } //启动定时器0void delay(uint n){ uint i,j;for(i=n;i>0;i--)for(j=140;j>0;j--); //延时1ms}/*-------LCD1602写指令函数-----*/void LCD1602_write_com(uchar com){ rs=0; //rs=0,置指令输入状态P0=com; //输出指令码delay(1); lcden=1;delay(1); lcden=0;} //lcden下降沿,使能端有效/*-------LCD1602写数据函数-----*/void LCD1602_write_dat(uchar dat){ rs=1; //rs=1,置数据输入状态P0=dat; //输出待显示字符的字符码(ASCII码)delay(1); lcden=1; delay(1); lcden=0; }void leapyear() //判断某年是否闰年函数{ if ((year%400==0) || (year%100!=0) && (year%4==0))month_day[1]=29; //闰年2月29天elsemonth_day[1]=28; } //平年2月28天uchar CaculateWeek(int y,char m, char d)//由年、月、日计算星期函数{ uchar w;if(m==1){m=13;y=y-1;}else if(m==2){m=14;y=y-1;}w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;return w; }/*定时计数器中断程序,每当定时计数器溢出时触发中断,执行该程序*/ void time0() interrupt 1{ TH0=(65536-50000)/256+5/256;//16位计数初值除以256得到高8位初值 TL0=(65536-50000)%256+5%256;//16位计数初值除以256的余数得到低8位初值if(temp==19) //折合值,使计时准确{ temp=0;if(second==59){ second=0;if(minute==59){ minute=0;if(hour==23){ hour=0;leapyear();//闰、平年计算if(day==month_day[month-1])//判断日期是否到了每月最后一天{ day=1;if(month==12){ month=1; year++; } //年加一else month++;} //月加一else day++;} //日加一else hour++;} //时加一else minute++;} //分加一else second++;} //秒加一else temp++;week=CaculateWeek(year,month,day); } //根据年月日计算星期void int0() interrupt 0//外部中断函数,当按下shift_key键时产生外部中断进入调整状态{ bit flag;uchar setup_bit=0; //setup_bit用于计数移位次数do{ if(confirm_key==0) //判断确认键是否按下{ delay(1); //延时消抖if(confirm_key==0) //确认确认键是否按下{while(!confirm_key); //等待确认键释放setup_bit=0; //移位计数值返回0LCD1602_write_com(0x0c); //关闭光标显示goto rep; } //转移到中断程序结束处}elseif(shift_key==0) //判断移位键是否按下{delay(1);//延时消抖if(shift_key==0) //确认移位键是否按下{ while(!shift_key); //等待移位键释放if(setup_bit==10) //共10位{ setup_bit=0; //移位计数值返回0LCD1602_write_com(0x0c);//关闭光标显示goto rep; } //转移到中断程序结束处else{ setup_bit++; //移位计数值加1LCD1602_write_com(0x0e); }//打开光标显示} }switch(setup_bit) //判断调整哪位,从而确定光标显示位置{ case 1:LCD1602_write_com(0x80+0x48+4);//光标设置到分个位显示位置 break;case 2:LCD1602_write_com(0x80+0x48+3);//光标设置到分十位显示位置 break;case 3:LCD1602_write_com(0x80+0x48+1);//光标设置到时个位显示位置 break;case 4:LCD1602_write_com(0x80+0x48+0);//光标设置到时十位显示位置 break;case 5:LCD1602_write_com(0x80+0x01+9);//光标设置到日个位显示位置 break;case 6:LCD1602_write_com(0x80+0x01+8);//光标设置到日十位显示位置break;case 7:LCD1602_write_com(0x80+0x01+6);//光标设置到月个位显示位置 break;case 8:LCD1602_write_com(0x80+0x01+5);//光标设置到月十位显示位置 break;case 9:LCD1602_write_com(0x80+0x01+3);//光标设置到年个位显示位置 break;case 10:LCD1602_write_com(0x80+0x01+2);//光标设置到年十位显示位置 break;default:break; }if(up_key==0) //判断增加键是否按下{delay(1);if(up_key==0) //确认增加键是否按下{while(!up_key); //等待增加键释放flag=1; } //增加键已按动elseflag=0; } //增加键未按动elseflag=0; //增加键未按动if(flag) //若增加键按动{ switch(setup_bit) //判断是哪位,从而调整哪位{ case 1:if(minute%10==9) //若分个位为9minute=minute-9; //则分个位清零elseminute++; //否则分个位加1LCD1602_write_dat(0x30+minute%10);//写入1602LCD break;case 2:if(minute/10==5) //若分十位为5minute=minute-50; //则分十位清零elseminute=minute+10;//否则分十位加1LCD1602_write_dat(0x30+minute/10);//写入1602LCDbreak;case 3:if(hour%10==9)hour=hour-9;elsehour++;LCD1602_write_dat(0x30+hour%10);//写入1602LCDbreak;case 4:if(hour/10==2)hour=hour-20;elsehour=hour+10;LCD1602_write_dat(0x30+hour/10);//写入1602LCD break;case 5:if(day%10==9)day=day-9;elseday++;LCD1602_write_dat(0x30+day%10);//写入1602LCD break;case 6:if(day/10==3)day=day-30;elseday=day+10;LCD1602_write_dat(0x30+day/10);//写入1602LCD break;case 7:if(month%10==9)month=month-9;elsemonth++;LCD1602_write_dat(0x30+month%10);//写入1602LCD break;case 8:if(month/10==1)month=month-10;elsemonth=month+10;LCD1602_write_dat(0x30+month/10);//写入1602LCD break;case 9:if(year%10==9)year=year-9;elseyear++;LCD1602_write_dat(0x30+year%10);//写入1602LCDbreak;case 10:if(year%100/10==9)year=year-90;elseyear=year+10;LCD1602_write_dat(0x30+year%100/10);//写入1602LCD break;default: break; }} }while(setup_bit!=0); //若所有位未调整完则返回,否则退出调整模式 rep:; }/*-------LCD1602初始化函数-----*/void LCD1602_init(){LCD1602_write_com(0x38); //设置液晶显示方式:16x2行,5x7点阵,8位数据总线LCD1602_write_com(0x0c); //设置字符显示开关及光标显示模式:开启字符显示,不显示光标LCD1602_write_com(0x06); //设置数据指针及显示屏移动模式:数据指针增(即光标右移),显示屏不移LCD1602_write_com(0x01); }//液晶屏幕清屏void main(){ init(); //定时计数器T0及中断初始化LCD1602_init(); //LCD1602初始化while(1){ uchar i;LCD1602_write_com(0x80+0x01); //设置第1行显示首地址01LCD1602_write_dat(0x30+year/1000);//输出年千位的字符码LCD1602_write_dat(0x30+(year%1000)/100);//输出年百位的字符码 LCD1602_write_dat(0x30+(year%100)/10);//输出年十位的字符码LCD1602_write_dat(0x30+year%10);//输出年个位的字符码LCD1602_write_dat('-');//输出'-'字符码LCD1602_write_dat(0x30+month/10);//输出月十位的字符码LCD1602_write_dat(0x30+month%10);//输出月个位的字符码LCD1602_write_dat('-');//输出'-'字符码LCD1602_write_dat(0x30+day/10);//输出日十位的字符码LCD1602_write_dat(0x30+day%10);//输出日个位的字符码LCD1602_write_dat('(');//输出'('字符码for (i=0;i<3;i++)LCD1602_write_dat(week_string[week][i]);//输出星期英文缩写字符码 LCD1602_write_dat(')');//输出')'字符码LCD1602_write_com(0x80+0x40+0x02); //设置第2行显示首地址04 LCD1602_write_dat('T');//输出'T'字符码LCD1602_write_dat('I');//输出'I'字符码LCD1602_write_dat('M');//输出'M'字符码LCD1602_write_dat('E');//输出'E'字符码LCD1602_write_dat(':');//输出' '字符码LCD1602_write_dat(' ');//输出' '字符码LCD1602_write_dat(0x30+hour/10);//输出小时十位的字符码 LCD1602_write_dat(0x30+hour%10);//输出小时个位的字符码 LCD1602_write_dat(':');//输出':'字符码LCD1602_write_dat(0x30+minute/10);//输出分十位的字符码 LCD1602_write_dat(0x30+minute%10);//输出分个位的字符码 LCD1602_write_dat(':');//输出':'字符码LCD1602_write_dat(0x30+second/10);//输出秒十位的字符码 LCD1602_write_dat(0x30+second%10);//输出秒个位的字符码 }}}。
移远模块(Quectel)是物联网中常用的一种模块,可以嵌入到各种设备中以实现无线通信。
对于嵌入式开发,通常需要使用到该模块的SDK(软件开发包)来编写代码。
下面是一个使用C语言编写的简单嵌入式移远模块代码示例,用于通过串口发送AT指令:
```c
#include "quectel_sdk.h"
int main() {
// 初始化串口
uart_init();
// 发送AT指令
send_at_cmd("AT+CSQ", 3);
// 等待返回值
int ret = wait_for_rsp(1000);
if (ret == 0) {
printf("CSQ response: %s\n", rsp_buffer);
} else {
printf("No response\n");
}
// 关闭串口
uart_deinit();
return 0;
}
```
该代码首先初始化了串口,然后发送了一个AT指令来查询信号质量(CSQ)。
等待一段时间后,程序会检查返回值并打印结果。
最后,程序关闭了串口。
需要注意的是,这只是一个简单的示例代码,实际应用中需要根据具体需求进行修改和扩展。
同时,还需要根据移远模块的SDK文档来了解更多关于API函数和参数的详细信息。
状态机协议栈开源代码(原创实用版)目录1.状态机协议栈概述2.状态机协议栈开源代码的意义3.状态机协议栈的主要功能4.如何使用状态机协议栈开源代码5.状态机协议栈的未来发展正文1.状态机协议栈概述状态机协议栈(State Machine Protocol Stack)是一种用于实现网络通信协议的开源软件库。
它主要用于帮助开发者构建各种网络协议,如TCP/IP、HTTP、FTP 等。
状态机协议栈通过提供一组通用的 API 和数据结构,使得开发者可以方便地实现和调试网络协议。
2.状态机协议栈开源代码的意义状态机协议栈的源代码公开,意味着开发者可以自由地查看、修改和定制代码。
这不仅有助于提高代码的质量和可维护性,还可以促进网络协议技术的创新和传播。
此外,开源状态机协议栈还有助于培养更多的网络协议技术人才,推动我国网络通信领域的发展。
3.状态机协议栈的主要功能状态机协议栈主要包括以下功能:(1)提供通用的网络协议实现框架,包括 TCP/IP、UDP、ICMP 等协议;(2)支持多种应用层协议,如 HTTP、FTP、SMTP 等;(3)提供灵活的 API 接口,方便开发者进行二次开发和定制;(4)支持多种编程语言和平台,如 C、C++、Python 等;(5)提供完善的测试和调试工具,确保协议栈的稳定性和可靠性。
4.如何使用状态机协议栈开源代码使用状态机协议栈开源代码的步骤如下:(1)首先,访问状态机协议栈的开源代码仓库,如 GitHub、GitLab 等;(2)下载并安装状态机协议栈的源代码,根据官方文档进行配置;(3)阅读官方文档和示例代码,了解状态机协议栈的使用方法和注意事项;(4)根据自己的需求,使用状态机协议栈提供的 API 和数据结构实现相应的网络协议;(5)进行调试和测试,确保实现的网络协议符合预期。
5.状态机协议栈的未来发展随着网络通信技术的不断发展,状态机协议栈将面临更多的挑战和机遇。
未来,状态机协议栈可能会在以下几个方面进行改进和发展:(1)支持更多的网络协议和技术,如 5G、物联网等;(2)提供更丰富的 API 和功能,简化开发者的使用难度;(3)引入人工智能和机器学习技术,提高网络协议的智能化水平;(4)拓展国际市场,提高在全球范围内的影响力。
103协议c语言代码摘要:1.103 协议简介2.C 语言编程基础3.103 协议C 语言代码实例4.代码解析与注释正文:【103 协议简介】103 协议,全称是“中国国家电网公司电能量采集与监控系统通信协议”,是我国电能量采集与监控系统中采用的一种通信协议。
该协议主要用于电表与采集器、采集器与监控系统之间的数据通信,以实现远程自动抄表、实时监控等功能。
【C 语言编程基础】C 语言是一种广泛应用于嵌入式系统开发的编程语言,具有语法简洁、执行效率高、跨平台等特点。
C 语言编程基础主要包括变量、数据类型、运算符、控制结构、函数、数组、指针等概念。
【103 协议C 语言代码实例】以下是一个简单的103 协议C 语言代码实例,用于电表与采集器之间的通信:```c#include <stdio.h>#include <string.h>#include "103protocol.h"// 103 协议头文件#define PROTOCOL_VERSION 1#define REQUEST_ID 0x01#define RESPONSE_ID 0x02#define APPID 0x01#define DATA_LENGTH 64int main(){uint8_t buffer[DATA_LENGTH];uint8_t check_sum = 0;uint8_t i;// 初始化for (i = 0; i < DATA_LENGTH; i++){buffer[i] = 0;}// 添加数据// 假设采集器地址为0x01, 0x02, 0x03, 0x04 buffer[0] = 0x01; // 协议版本buffer[1] = PROTOCOL_VERSION;buffer[2] = REQUEST_ID;buffer[3] = APPID;buffer[4] = 0x01; // 设备类型:电表buffer[5] = 0x01; // 设备地址:0x01buffer[6] = 0x01; // 传输协议:0x01buffer[7] = 0x02; // 通信规约:0x02buffer[8] = 0x03; // 数据项:电能示值buffer[9] = 0x01; // 数据长度:0x01buffer[10] = 0x01; // 数据类型:浮点数buffer[11] = 0x00; // 数据值:0x0000// 计算校验和for (i = 0; i < DATA_LENGTH - 1; i++){check_sum += buffer[i];}buffer[DATA_LENGTH - 1] = check_sum;// 发送数据// 调用103 协议发送函数// 发送成功printf("数据发送成功");return 0;}```【代码解析与注释】1.引入头文件,定义103 协议相关宏和变量。
BACstac/32v6.5 Porting Guide for EmbeddedPlatformsDocument Version:1.0Cimetrics,Inc.141Tremont Street,Floor11BOSTON,MASSACHUSETTS02111USATELEPHONE:+1(617)350-7550FAX:+1(617)350-7552E-MAIL:products@(sales),support@(tech.support)WEB:BACstac/32v6.5Porting Guide for Embedded Platformsby Cimetrics,Inc.Document Version:1.0EditionCopyright©1999-2012Cimetrics,Inc.BACstac and BACstac/32are trademarks of Cimetrics Inc.BACnet is a registered trademark of the American Society of Heating,Refrigeration and Air-Conditioning Engineers,Inc.(ASHRAE).LonTalk is a trademark of Echelon Corp.All other trademarks are owned by their respective companies.Table of Contents1.Introduction (1)2.Source Code (2)Overview (2)arch (2)apil (2)examples (2)include (3)test (3)tsml (3)dl (3)nl (3)osa (3)oslib (3)utils (4)unit_test (4)Build variables for makefiles (4)Steps to Build BACstac/32on your Platform (8)3.How to Write the OSA (10)Terminology (10)OSA Initialization and Deinitialization (11)OSAInit() (12)OSAClose() (12)Threads (13)General description (13)OSACreateThread() (13)OSATerminateThread() (14)OSAWaitForThread() (14)Semaphores (15)General description (15)OSAInitSemaphore() (15)OSAWaitForSemaphore() (15)OSAReleaseSemaphore() (16)OSADestroySemaphore() (16)Recursive mutexes (16)OSAInitRecursiveMutex() (16)OSALockRecursiveMutex() (17)OSAUnlockRecursiveMutex() (17)OSADestroyRecursiveMutex() (17)Fast mutexes (18)OSAInitFastMutex() (18)OSALockFastMutex() (18)OSAUnlockFastMutex() (19)OSADestroyFastMutex() (19)Atomic variables (19)General description (19)OSAAtomicGet() (20)OSAAtomicSet() (20)OSAAtomicInc() (20)OSAAtomicIncTest() (20)OSAAtomicDec() (20)OSAAtomicDecTest() (21)OSAAtomicAdd() (21)OSAAtomicSub() (21)Dynamic memory (21)General description (22)OSAAlloc() (22)OSAFree() (22)Time (22)General description (23)OSAGetTickCount() (23)OSASleep() (23)System logging utilities (23)General description (24)OSALogMessage() (24)Byte ordering andfloating point format utilities (25)General description (25)Cardinal byte order (25)IEEE-754compliance (26)OSAFPClassify() (26)OSAGenerateSpecFPValue() (27)Debugging support utilities (27)General description (27)OSAPanic() (27)4.How to Write the Configuration Module (29)Using Configuration Structures (29)OSA Configuration (29)Tuning Parameters (30)5.How to Add a Data Link Layer (31)Abbreviations (31)What is a sub-DL? (32)How Does the Sub-DL Operate? (34)System resources (35)Interface with hardware (35)Sub-DL⇔DL-common interface (36)Data Message (36)Data Message Interface (36)List of sub-DLs (42)Sub-DL operations (42)Operation Init (43)Operation Close (43)Operation Accept (44)Operation Bind (44)Operation Unbind (46)Operation SendTo (46)Operations Connect and Disconnect (47)Operation Ioctl (47)Support functions (48)Null sub-DL example (49)Porting Ethernet Sub-DL (52)Porting B/IP(Addendum A)Sub-DL (60)Porting PTP Sub-DL (64)Porting ARCNET sub-DL (68)Porting MS/TP Sub-DL (81)6.Building Unit Tests&Examples (85)Building the Test Programs (85)OSA Tests (85)Data Link Layer Tests (86)Network Layer Test (86)Example Server Application-FEEDBACK (86)Example Client Application-DUMPALL (87)List of Figures5-1.Simplified BACstac Architecture (33)5-2.Internal Sub-DL Structure (34)5-3.Sub-DL and Its Environment (34)5-4.Simplified Sub-DL⇔DL Interface Structure (36)5-5.PTP Sub-DL Operation in the“Null-modem”Mode (64)5-6.PTP Sub-DL Operation in the“Dial-up”Mode (65)Chapter1.IntroductionThank you for your interest in Cimetrics’BACstac™software.The BACstac Networking Software provides you with the ability to create embedded controls which use ASHRAE’s BACnet®protocol for communication.Implementa-tions of the BACstac are currently available for32-bit versions of Windows XP,Windows Vista,Windows7,Windows Server2003,Windows Server2008,Windows Server2008R2,Linux2.6,and some32-bit embedded platforms.This document describes how to port the BACstac/32source code to your platform.For a description of how to construct applications using the BACstac software,please refer to the BACstac Users'Guide.For a description of the data types and API routines available in the BACstac software,please refer to the BACstac Programmers'Reference.In order to use this software you will need the following:•Embedded32-bit platform•32-bit RTOS with network interface drivers•ANSI C compiler•Make utility•The BACnet Standard(ANSI/ASHRAE135-2010or later)BACstac/32is shipped with all source code and makefiles needed to build it as monolith Routing BACstac Edition for Win32or Linux platform with the following data link included:BACnet/IP,Point-To-Point,Ethernet.To build BACstac on Win32platform you can use either Borland C++5.5or Microsoft Visual C++2003,2005,or2008. If you choose Linux option,you will need Linux with glibc2.1or better and gcc2.95or higher with all set of standard developer tools.Ability to run the original BACstac version in the same network with your target platform will significant reduce porting time at the testing stage.BACnet Protocol Analyzer(BAS-o-matic)is also very helpful with testing.It not only allows to see sent BACnet requests and responses,but also to send modified packets if necessary to verify the implementation reaction.This document contains the following sections to help you port the BACstac to your platform:1.an overview of the source code layout of the BACstac2.a description of the modules that you will need to rewrite for your platform3.recommended steps in your porting project,using the BACstac module and library test applicationsChapter2.Source CodeThe root directory of the source tree includes directories for modules and projects and also arch directory.The modules are libraries(such as osa,nl,etc),which can be shared by different projects.The source code for BACstac32includes only one project:BACstac.It contains all BACstac specific modules,such as apil,tsml,etc.The arch directory is the place where all platform specificfiles are located.Each platform has its own subdirectory inside of it.OverviewThe source code has the following directories:archThis directory contains all system dependent code,makefiles and everything else what is platform specific.The di-rectory has two subdirectories:linux and win32,where system dependentfiles for the corresponding platform are located.The structure of this subdirectories is same as the root directory but without arch.Makefiles to build some module for specific project are placed under directory with the project name.For ex-ample,main Makefile to build BACstac for Win32platform is placed in arch\win32\BACstac directory.The project directory has a few subdirectories containing makefiles used to build some module for BACstac project. The apil module,which can be build as client,server,or gateway library,has three corresponding subdirecto-ries:cli,srv,and gtw inside of arch\win32\BACstac\apil\api,arch\win32\BACstac\apil\objects,and arch\win32\BACstac\apil\services directories.apilAPI Layer(Upper Application Layer)includes subdirectories for Access Routines,BACstac API,Parser(ASN syntax validator),Coder(encoder/decoder),Objects(object database),CBNOBJ(the CBNOBJ utility and examples of.TPI files for some devices),and Services(Encoder,Request Dispatch,Hook Dispatch and Default Actions)containing the corresponding source code.CBNOBJ is Cimetrics BACnet Object Compiler used to create device templates for use in BACstac server and gateway applications which use the BACstac object database and default actions.CBNOBJ parses a.TPIfile(Text PICS-a standard specified in ASHRAE Standard135.1:"Method of Test for Conformance to BACnet)and creates a template of a device with its objects,properties and initial values.BACstac API,Objects,and Services can be compiled as a client,service,or getaway library.All other are shared are same for all three types of APIL.examplesThis directory contains25examples of BACstac application.Each of them has its own directory with corresponding name.The utils subdirectory includes source code of library shared by all BACstac examples.There are three types of examples:client,server,and gateway.Each of them must be linked to the corresponding BACstac version of apil library.Besides,examples use OSL and syslib libraries.For more information see examples\readme.txtincludeThis directory contains headerfiles used by different BACstac modules.The api subdirectory includes BACstac API available for BACstac applications.testThe directory contains collection of integral tests for BACstac.tsmlThe Transaction State Machine Layer(Lower Application Layer)implements the transmission and reception protocol for BACnet APDU.The overview of it is given in clause5.3of ANSI/ASHRAE Standard135-2010or later and formal description in clause5.4.Besides,the TSM layer for the workstation version implements application multiplexing to allow multiple BACstac applications to work at the same time on one computer.dlData Link Layer.Contains common code for multiplexing ports and data link layer types.Includes subdirectories for the BACnet/IP and PTP(Point-To-Point)data link layers.Normally code for a data link layer is non-portable since it interfaces to particular device drivers on a platform.The BACnet/IP data link layer code is reasonably portable and therefore it is often a good choice for starting the porting process.The PTP data link layer code is written in terms of a serial port abstraction module(implemented in arch\win32\dl\ptp\comm\comm.c and arch/linux/dl/ptp/comm/comm.c).The PTP code is also reasonably portable.nlNetwork Layer.Contains common code for both Routing(gateway)and Nonrouting(vanilla)network layer imple-mentations.The Routing NL should be used for controls which will support multiple BACnet network interfaces(for example,to link a building backbone tofield network),or which will support PTP,or which will wish to use a virtual network to implement an embedded gateway.The Vanilla NL should be used for controls which have a single net-work interface.The Routing NL in BACstac/32is based on the same code found in Cimetrics Routers and Tunnelling Routers.osaOperating System Abstraction Layer.Contains a document describing Application Program Interface(API)of the OSA and unit tests for its functions.(The non-portable code implementing the OSA on Win32and Linux platforms is located in arch\win32\osa and arch/linux/osa directories.)oslibOperating System Library.This is scaledown version of OSA used by examples.Its API is a subset of OSA API,and its functions has OSL prefix instead of OSA.utilsThe Utilities Module is a library used by many other modules,which is built on the OSA primitives to provide general purpose data and structure(such as thread-safe buffer pools)and operation on them.unit_testThere is no such as directory in the root of the source tree but some modules(OSA,DL,NL)have such subdirectory. It contains a set of unit tests for respective module intended to test the module implementation with minimal using of other libraries.See Chapter6for details.Build variables for makefilesThe BACstac source code comes with makefiles for Borland C/C++and Microsoft Visual C/C++for Win32platform, and GNU makefiles for Linux.This makefiles can be a start point to create your own makefiles or IDE project for your target platform.The supplied makefiles contain important information which you may interesting in:•Build configuration options•the list offiles to build•C preprocessor macro depending on building configurationThe building configuration option for Win32platform are set in thefile arch\win32\BACstac\Autoconf.make. Many of them are for debug purposes,others are useful in different ways.Below is their list:CONFIG_DEBUG=0Includes BACstac debug code,such as ASSERTs and tracing.If enabled then the DEBUG preprocessor macro is defined,otherwise the NDEBUG preprocessor macro is defined.Allowed values:0(disable),1(enable). CONFIG_DEBUG_INFO=0Includes compiler debugging information(source line numbers,etc)during compilation and linking.Allowed values:0(disable),1(enable).CONFIG_STACK_ARCH=SINGLE_PROCESSProtocol stack architecture:either"monolithic"or"single-process"(the TSML and AL run in the same process), or"client/server"or"daemon"(the AL(s)and TSML run in separate processes).For now this option also de-termines presence of the user multiplexor,which is only included in multiprocessor build.In the future these options might be controlled independently.Allowed values:SINGLE_PROCESS,MULTI_PROCESS.DefinesBACSTAC_MULTIPLEXOR and BACSTAC_DAEMON_PROCESS preprocessor macros.BACstac/32is pro-vided to work in single process configuration only.CONFIG_DL_NIC,CONFIG_DL_BIP,CONFIG_DL_PTP=n,y,yDatalink technologies:define one or more sub-DLs to be included.In the data link layer code,there is a jump table whose entries are controlled by these settings.DL_NIC(Ethernet),DL_BIP(BACnet/IP),DL_PTP(Point-To-Point).Allowed values:y,n.Defines BACSTAC_DL_NIC,BACSTAC_DL_BIP,BACSTAC_DL_PTP pre-processor macros.CONFIG_GENERATE_MAP=0MAP option:turns.MAPfile generation by the linker on or off.Specific to the Borland and Microsoft makefiles.Allowed values:0(off),1(on).CONFIG_RC_STRICT=0Resource leak checking:turns on internal checks of resource usage(memory,system objects,PDUs)(ignored in non-DEBUG build).Allowed values:0(disable),1(enable).Defines RC_STRICT preprocessor macro.The building configuration option for Linux platform are described below.Many of them are for debug propose only.Cross compile prefix(CROSS_COMPILE)Specifies the prefix used for gcc and related bin-utils executables used during compilation.Leave it empty for a non-cross build.Routing NL(CONFIG_NL_ROUTER)If you want to build a routing version of the Network layer,say Y.Establish remote PTP connection(CONFIG_NL_CONNECT)If you want to enable establishing remote PTP connection(i.e.sending Establish-Connection-To-Network to routers that responded with I-Could-Be-Router-To-Network),say Y.If you are not sure,say Y here.Debug Routing(CONFIG_DEBUG_ROUTING)If you want to enable debug log information about all changes to the routing table,say Y.Support Segmentation(CONFIG_SEGMENTATION)Enable support for sending or receiving segmented APDU messagesBACstac daemon(BACSTAC_DAEMON_PROCESS)BACstac can be compiled either as"monolithic"(a single process that contains the whole BACnet stack and user application),or"client/server"(a.k.a."daemon"),where one or more BACstac based programs may use the same BACstac stack simultaneously.Enable ioctl(CONFIG_IOCTL)If you want to enable ioctl functionality in BACstac,say Y.Build shared libraries(CONFIG_BUILD_SO)If you want to build BACstac shared libraries instead of static ones,say Y.ARCNET=Clause8(CONFIG_ARCNET)If you want BACnet over"raw"ARCNET link,say Y.Don’t forget to enable"arc0s"interface in the Linux kernel.Ethernet=Clause7(CONFIG_ETHERNET)If you want BACnet over"raw"Ethernet link,say Y.Tunneled IP(T/IP)=Annex H(CONFIG_ANNEXH)If you want BACnet over IP tunnel as described in Annex H,say Y.BACnet over IP(B/IP)=Annex J(CONFIG_BIP)If you want BACnet over IP,say Y.Config BBMD(CONFIG_BBMD)If you want to enable BBMD functionality in this device,say Y.Don’t bind to the physical interface(CONFIG_BIP_NO_BINDTODEVICE)This disables binding a socket used by B/IP data link to a particular device(like"eth0"),which is specified in the configuration.If a socket is bound to an interface,only packets received from that particular interface are processed by the socket.Binding to the device requires the CAP_NET_RAW privilege(which only’root’has by default).If binding to the device is disabled then BACstac creates two UDP sockets and bound them to the device IP address and network broadcast mask correspondingly.Note:Binding to the device is the default mode for all versions of BACstac for Linux,but it may not work correctly in present two or more cards connected to the same network(e.g.Ethernet and Wi-Fi).Also,it blocks all traffic from other interfaces,which may be not desirable when BACtac is used as a BBMD for devices that are located on another network.Point to Point(PTP)=Clause10(CONFIG_PTP)If you want BACnet over Point-To-Point protocol as described in Chapter10of the BACnet standard,say Y. Null-network(B/Null)(CONFIG_NULL)Null-network is extension to the ANSI/ASHRAE135-1995and its subsequent annexes.Null-network interface does nothing except assigns a network number and MAC address to the BACnet device.All messages which are sent to the null-network are quietly disappeared;the is no incoming messages arrived from null-network.However,null-net sub-DL can be useful if you want to make BACnet device which is connected to the world via PTP or T/IP only(neither PTP nor T/IP interface has no associated network number).It is recommended to say Y.Enable debug info in binary(CONFIG_DEBUG_INFO)In other words,pass-g switch to the C compiler or not.If you are a developer,you may say Y here.Otherwise it is recommended to say N.Optimization(CONFIG_OPT_XXX)This option specified the desired level of optimization:•"None"-Do not optimize.•"Base"-Perform all supported optimizations that do not involve a space-speed trade-off.(-O2option for gcc)•"Speed"-It turns on all optimizations specified by"Base"and also turns on some additional optimization that can make the code faster but may significantly increase the code size.(-O3option for gcc)•"Size"-Optimize for size(-Os option for gcc)Omit frame pointer(CONFIG_OMIT_FRAME_PTR)Don’t keep the frame pointer in a register for functions that don’t need one.This avoids the instructions to save, set up and restore frame pointers;it also makes an extra register available in many functions.Enable debugging code(CONFIG_DEBUG)This option enables internal checks and Assert in BACstac.It is necessary to enable other debugging functionality such as debug tracing.Due to additional checks,BACstac may work considerably slower when this option is set. Initilize allocated memory(CONFIG_FILL_MEMORY)All allocated memory is initialized with0xCD byte.It may be useful to detect the use of initialized memory inside of BACstac,but it is less reliable than using specialized tools as’valgrind’and is not compatible with them.Debug IPC buffers(CONFIG_DEBUG_IPCBUF)This option allows additional expensive validation of IPC buffers to detect corruption in structures used to manage them.It can be used only with CONFIG_DEBUG.Alloc save callers(CONFIG_SA VE_CALLERS)If you try tofind a memory leak inside of BACstac,this option allows to save stack addresses at the moment when memory is allocated.This option is only supported on x86architecture and may be incompatible with optimization.Enable tracing(this produce while syslog)(CONFIG_DEBUG_TRACE)If you want to see log messages about each packet received or transmitted and many other events(such as byte transmission in PTP sub-DL),say Y.IMPORTANT:This trace mayflood the system log with many cryptic messages that is impossible to understand without the studying the source code.This log is not intended for normal use.Trace OSA calls(CONFIG_TRACE_OSA_CALL)If you want to trace all OSA calls inside of BACstac,say Y.It may be helpful with debugging,but the log generated by this option may be huge.Suppress tracing for DL(CONFIG_DL_NO_TRACE)If you isn’t BACstac(especially,MS/TP)developer,or you want to know nothing about what data link layer does in some details,say Y here.Suppress tracing for T/IP(CONFIG_ANNEXH_NO_TRACE)If you isn’t BACstac developer,or you don’t need to know what T/TP ports do in details,say Y here.Suppress tracing for PTP(CONFIG_PTP_NO_TRACE)If you isn’t BACstac developer,or you don’t need to see PTPfinite state machines transitions,say Y here.Profiling(CONFIG_GPROF)Generate extra code to write profile information suitable for the analysis program’gprof’.During execution BACstac records how many times each branch and call is executed and how many times it is taken or returns.At exist,all collected data is written to afile called’AUXNAME.gcda’for each sourcefile.NOTES:-This option is necessary to collect coverage information.-This option is not compatible with omitting frame pointer.Test coverage(CONFIG_GCOV)Produce afile that the’gcov’can use to show program coverage.Wait synchronizer statistics(CONFIG_WAIT_STAT)Collect statistics about different synchronizers that caused the current thread to suspend.This statistics is useful because it shows the number of involuntarily context switches caused by each synchronizer.This option is currently incompatible with tracing OSA calls.Config SMP support(CONFIG_SMP)If you want to run BACstac on SMP or multi-core system,say Y.If you say N here,BACstac may work marginally faster on uniprocessor systems but will get broken in subtle way when it runs on SMP.If you are not sure,say Y here.OSA Log identificator(OSA_LOG_IDENT)The string prepended to every system log message.The default value is’bacstac’.PIDfile(CONFIG_PID_FILE)The location of PIDfile created by the BACstac service.Steps to Build BACstac/32on your PlatformTo complete a port of BACstac/32to your platform,the following steps are recommended:•Write the OSA•Write the configuration subsystem(OSA or Utils)•Unit Test the OSA•Unit Test the OSA+Utils+DL•Unit Test the OSA+Utils+DL+NL•Build the full library(OSA+Utils+DL+NL+TSML+APIL)•Test with Examples or Library testsThe following chapters discuss these steps in more detail.Once the library has been successfully ported to your platform you can proceed with developing your embedded BACnet applications.However,the examples and unit tests will continue to be useful for tuning and troubleshooting.Chapter3.How to Write the OSAWriting your own version of the OSA means creating the implementation underneath the module interface defined in arch\win32\include\osa.h.The interface consists of methods for a series of abstract RTOS objects(like threads and semaphores).The examplefiles in the arch\win32\osa subdirectory could provide a starting point,since they organize the implementation by abstract RTOS object type.The following sections describe the required behavior of the routines in that interface.Note that the current version of the OSA uses a naming convention that is different from the rest of the BACstac. The BACstac6.5refers to both old-style and new-style OSA definitions,and a complete transition to the new-style definitions will take some time.New OSA ports should use the style defined in this chapter but provide a wrapper headerfile(arch\win32\include\osa.h)enabling the continued use of the old style. TerminologyBACnetBuilding Automation and Control network protocol,ANSI/ASHRAE Standard135-2010or later.BACstacA BACnet protocol stack implementation by Cimetrics,Inc.™.EventA synchronization primitive.There are W AIT and SIGNAL operations defined on events.The semantics of eventsis identical to that of binary semaphores.HandleAn opaque reference to an object(thread,semaphore,mutex and so on).It can be passed into methods,but cannot be used to access the object directly.MutexMUTual EXclusion device.There are recursive and non-recursive mutexes.The OSA deals only with recur-sive mutexes.The LOCK(WAIT)and UNLOCK(RELEASE)operations are defined on mutexes.Unlike a semaphore,a recursive mutex doesn’t block the thread which owns it.A mutex can only be unlocked by the thread which has locked it(some implementations may allow a thread to unlock a mutex which is owned by another thread but this behavior isn’t a mutex property).The mutex’s main role is to synchronize access to a shared resource(or a critical region of code).OSAOperating System Abstraction Layer.It defines a platform-independent API for system services for the BACstac.Ideally,only the OSA implementation(and data link layers)needs to be rewritten to port BACstac to a new platform.ProcessA unit(atom)of system resources consumption.For every existing process an OS handles allocation,mainte-nance and deallocation of resources(CPU,memory,files,etc.),protection from undesired intervention by other processes(optional),and possibly other services.All programs(either user or system,single-threaded or multi-threaded)run in context of a process.A process may or may not share address space with other processes in the system;this depends on particular hardware and OS.SemaphoreA semaphore is a basic synchronization primitive.In general,every semaphore holds an integer counter whichmay take on values in the range from0to some positive value(the semaphore’s limit).There are semaphores of two kinds:binary(limit is equal to the value1)and general(non-binary,limit is greater than1).INIT,W AIT and RELEASE operations are defined on semaphores.The semaphore’s main role in BACstac is as a counter(to count messages in an interface queue,for instance).It is not used to synchronize access to shared data;a mutex is used for that purpose instead.Unlike a mutex(recursive),there is no notion of"semaphore owner".This means that any thread will block on a semaphore whose count is equal to zero.ThreadA minimal execution unit from the system perspective.A thread shares an address space with other threads of thesame process.A process which has only one thread is called single-threaded(also known as regular process);a process which has more than one thread is called multithreaded.There is an essential difference between threads and processes that share an address space:An OS treats all threads of the same process as a single system resource consumer.However,sometimes threads are implemented as processes having a common address space,possibly with certain restrictions(LinuxThreads,for example).Sometimes,threads are called"lightweight processes". TimerA timer counts a time interval.When the interval expires,the timer signals this event using some method.A timeralways counts real(astronomic)time independently of other timers and threads.Unpredictable results(undefined behavior)In this case the OSA port developer should make OSA implementation as robust as possible.The BACstac(i.e.OSA user)should assume nothing about undefined OSA behavior and avoid conditions that may causeunpredictable results.OSA Initialization and DeinitializationOSAInit()OSAFastMutex*OSAInit(void);OSAInit does all the necessary initialization to bring OSA into action.On success,it returns a pointer to the fast mutex that can be used to perform initialization of the current component atomically.If the function fails,it returns NULL.OSAInit must be called before any other OSA function.OSAInit may be called more than once.Iffirst call to OSAInit has been successful,each subsequent OSAInit call does nothing but increment an internal reference counter.A matching call to OSAClose must be made for each successful OSAInit call.If OSAInit returns NULL,it is recommended that the application terminates itself as soon as possible because OSAInit may put the program into an unstable state(for example,an interval timer may generate signals that will not be handled).OSA initialization scope is one process.Every process that uses OSA must call OSAInit/OSAClose functions.After a successful call to OSAInit OSA may be used by any number of threads within the process.OSAClose()bool OSAClose(void);OSAClose function terminates use of the OSA.It returns TRUE on success and FALSE on error.All internal resources allocated by OSAInit call are freed.OSAClose must be called before a process terminates.For each OSAInit call a corresponding OSAClose call must be made.If OSAClose is called more times then OSAInit the result will be unpredictable.IMPORTANT:All thread created by OSACreateThread function call must be terminated before calling OSAClose; an attempt to call OSAClose before terminating all OSA-created threads may cause unpredictable results.If OSAClose is not called an appropriate number of times before the process terminates,or if OSAClose returns FALSE,some systemwide resources(such as shared memory,semaphores,mutexes)may not be freed correctly and thus wasted.It is possible to initialize and reinitialize OSA more than once:int RunFoo(){static int init_cnt=0;OSAFastMutex*mut=OSAInit();if(!mut)return EXIT_FAILURE;OSALockFastMutex(mut);if(init_cnt++==0){//it is the first instance//initialize global resource here。