分析BACnet协议栈1Word格式.docx
《分析BACnet协议栈1Word格式.docx》由会员分享,可在线阅读,更多相关《分析BACnet协议栈1Word格式.docx(16页珍藏版)》请在冰豆网上搜索。
![分析BACnet协议栈1Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/3/0debefb3-d9b5-479f-9051-1b091a7bd9d6/0debefb3-d9b5-479f-9051-1b091a7bd9d61.gif)
*/
/*Useionicewrappertoimproveserialperformance:
$sudoionice-c1-n0./bin/bacserv12345
*/
/*handlereturnedfromopen()*/
staticintRS485_Handle=-1;
/*baudratesettingsaredefinedin<
asm/termbits.h>
whichis
includedby<
staticunsignedintRS485_Baud=B38400;
//波特率选择38400bps
/*serialportname,/dev/ttyS0,
/dev/ttyUSB0forUSB->
RS485fromB&
BElectronicsUSOPTL4*/
staticchar*RS485_Port_Name="
/dev/ttyUSB0"
;
/*系统默认是通过USB转485的,根据需要设置,若你的开发板用485接口,则用staticchar*RS485_Port_Name="
/dev/ttyS0"
代替*/
/*someterminalI/OhaveRS-485specificfunctionality*/
#ifndefRS485MOD
#defineRS485MOD0
#endif
/*serialI/Osettings*/
staticstructtermiosRS485_oldtio;
/*Ringbufferforincomingbytes,inordertospeedupthereceiving.*/
staticFIFO_BUFFERRx_FIFO;
/*buffersizeneedstobeapowerof2*/
staticuint8_tRx_Buffer[4096];
#define_POSIX_SOURCE1/*POSIXcompliantsource*/
/*********************************************************************
*DESCRIPTION:
Configurestheinterfacename
*RETURN:
none
*ALGORITHM:
*NOTES:
*********************************************************************/
voidRS485_Set_Interface(
char*ifname)
{
/*note:
expectsaconstantchar,orcharfromtheheap*/
if(ifname){
RS485_Port_Name=ifname;
}
}
Returnstheinterfacename
constchar*RS485_Interface(
void)
returnRS485_Port_Name;
/****************************************************************************
Returnsthebaudratethatwearecurrentlyrunningat
*****************************************************************************/
uint32_tRS485_Get_Baud_Rate(
uint32_tbaud=0;
switch(RS485_Baud){
caseB0:
baud=0;
break;
caseB50:
baud=50;
caseB75:
baud=75;
caseB110:
baud=110;
caseB134:
baud=134;
caseB150:
baud=150;
caseB200:
baud=200;
caseB300:
baud=300;
caseB600:
baud=600;
caseB1200:
baud=1200;
caseB1800:
baud=1800;
caseB2400:
baud=2400;
caseB4800:
baud=4800;
caseB9600:
baud=9600;
caseB19200:
baud=19200;
caseB38400:
baud=38400;
caseB57600:
baud=57600;
caseB115200:
baud=115200;
caseB230400:
baud=230400;
default:
baud=9600;
returnbaud;
SetsthebaudrateforthechipUSART
boolRS485_Set_Baud_Rate(
uint32_tbaud)
boolvalid=true;
switch(baud){
case0:
RS485_Baud=B0;
case50:
RS485_Baud=B50;
case75:
RS485_Baud=B75;
case110:
RS485_Baud=B110;
case134:
RS485_Baud=B134;
case150:
RS485_Baud=B150;
case200:
RS485_Baud=B200;
break;
case300:
RS485_Baud=B300;
case600:
RS485_Baud=B600;
case1200:
RS485_Baud=B1200;
case1800:
RS485_Baud=B1800;
case2400:
RS485_Baud=B2400;
case4800:
RS485_Baud=B4800;
case9600:
RS485_Baud=B9600;
case19200:
RS485_Baud=B19200;
case38400:
RS485_Baud=B38400;
case57600:
RS485_Baud=B57600;
case115200:
RS485_Baud=B115200;
case230400:
RS485_Baud=B230400;
valid=false;
if(valid){
/*FIXME:
storethebaudrate*/
returnvalid;
Transmitaframeonthewire
voidRS485_Send_Frame(
volatilestructmstp_port_struct_t*mstp_port,
/*portspecificdata*/
uint8_t*buffer,
/*frametosend(upto501bytesofdata)*/
uint16_tnbytes)
{
/*numberofbytesofdata(upto501)*/
uint32_tturnaround_time=Tturnaround*1000;
uint32_tbaud=RS485_Get_Baud_Rate();
ssize_twritten=0;
intgreska;
/*sleepingforturnaroundtimeisnecessarytogiveotherdevices
timetochangefromsendingtoreceivingstate.*/
usleep(turnaround_time/baud);
//至少要等待Tturnaround时间才启动RS485缓冲器发送
/*
On
success,
the
numberofbyteswrittenarereturned(zeroindicates
nothingwaswritten).
Onerror,-1
is
returned,
and
errno
set
appropriately.
If
count
iszeroandthefiledescriptorreferstoa
regularfile,0willbereturnedwithoutcausinganyothereffect.
For
aspecialfile,theresultsarenotportable.
written=write(RS485_Handle,buffer,nbytes);
//RS485_Handle初始时是为-1,当发出open操作时应该是个正整数,而write函数的原型是(fd,buf,n)
greska=errno;
if(written<
=0){
printf("
writeerror:
%s\n"
strerror(greska));
}else{
/*waituntilalloutputhasbeentransmitted.*/
tcdrain(RS485_Handle);
//Linux中的传输等待函数
/*
/*perMSTPspec,sortof*/
if(mstp_port){
mstp_port->
SilenceTimerReset();
return;
Getabyteofreceivedata
RS485_Check_UART_Data函数分别检查ReceiveError、DataAvailable。
然后选择端口从UART中读数据
voidRS485_Check_UART_Data(
volatilestructmstp_port_struct_t*mstp_port)
fd_setinput;
structtimevalwaiter;
uint8_tbuf[2048];
intn;
if(mstp_port->
ReceiveError==true){
/*donothingbutwaitforstatemachinetocleartheerror*/
/*burningtime,sowaitalongertime*/
waiter.tv_sec=0;
waiter.tv_usec=5000;
}elseif(mstp_port->
DataAvailable==false){
/*waitforstatemachinetoreadfromtheDataRegister*/
if(FIFO_Count(&
Rx_FIFO)>
0){
/*dataisavailable*/
DataRegister=FIFO_Get(&
Rx_FIFO);
DataAvailable=true;
/*FIFOisgivingdata-don'
twaitverylong*/
waiter.tv_usec=10;
/*FIFOisempty-waitalongertime*/
/*grabbytesandstuffthemintotheFIFOeverytime*/
FD_ZERO(&
input);
FD_SET(RS485_Handle,&
n=select(RS485_Handle+1,&
input,NULL,NULL,&
waiter);
if(n<
if(FD_ISSET(RS485_Handle,&
input)){
n=read(RS485_Handle,buf,sizeof(buf));
FIFO_Add(&
Rx_FIFO,&
buf[0],n);
voidRS485_Cleanup(
/*restoretheoldportsettings*/
tcsetattr(RS485_Handle,TCSANOW,&
RS485_oldtio);
//tcgetattr用于获取终端的相关参数,而tcsetattr函数用于设置终端参数
close(RS485_Handle);
voidRS485_Initialize(
structtermiosnewtio;
RS485:
Initializing%s"
RS485_Port_Name);
Opendeviceforreadingandwriting.
Blockingmode-moreCPUef