📄 threadfunc.c
字号:
#include "include/mcuapi.h"void *Thread_NoUse(void *iPort)//如果某个串口规约选择备用,线程退出{ int j,retval; int nPort = *((int *)iPort); SubDevice[nPort].iPort = *((int *)iPort); for(j=0;j<SubDevice[nPort].SubTotalNum;j++) { SubDevice[nPort].SubStations[j].sub_address = 0; SubDevice[nPort].SubStations[j].sub_YC_NUM = 0; SubDevice[nPort].SubStations[j].sub_YX_NUM = 0; SubDevice[nPort].SubStations[j].sub_YC_Addr = 0; SubDevice[nPort].SubStations[j].sub_YX_Addr = 0; } SubDevice[nPort].SubTotalNum = 0; retval = 100 + nPort; pthread_exit(&retval);}void *Thread_XJ800BH(void *iPort)//许继103规约处理线程 { int nPort = *((int *)iPort); int ret,i,m,nOrder = 0; int OffLineIndex = 0; int nRead,iRequireNum = 0; int nLen,iCon_Number,iNetGroup; unsigned char IEC104DataBuf_C[256]; unsigned char IEC103DataBuf_C[256]; SUB_Station *pSub = NULL; ResetAllCU(nPort); while(1) { ret = 0; nRead = Read_104Data_From_Memory(nPort, IEC104DataBuf_C); if( nRead > 0 ) { iNetGroup = IEC104DataBuf_C[0]>>4; iCon_Number = IEC104DataBuf_C[0]&0x0f; if (CONN_IsEngStation(iNetGroup,iCon_Number)) //来自工程师站的命令报文 ret = IEC_Frame_TCPTo103(nPort, IEC103DataBuf_C, IEC104DataBuf_C+1); else //来自操作员站的命令报文 ret = IEC_Frame_104To103(nPort, IEC103DataBuf_C, IEC104DataBuf_C+1); } else { iNetGroup = 0xff; iCon_Number = 0xff; iRequireNum = SUB_GetNextOnline(iRequireNum,nPort); pSub = &SubDevice[nPort].SubStations[iRequireNum]; if(pSub->sub_state == SUB_STATE_ONLINE) ret = LocalIEC103Cmd(pSub->sub_CS,pSub->sub_address,IEC103DataBuf_C); } if(ret>0) Command_Handle(nPort, iNetGroup, iCon_Number, IEC103DataBuf_C, ret); nOrder = (nOrder+1)%5; if(nOrder==0) { OffLineIndex = SUB_GetNextOffLine(OffLineIndex, nPort); pSub = &SubDevice[nPort].SubStations[OffLineIndex]; if(pSub->sub_state != SUB_STATE_ONLINE) ResetOneCU(nPort, OffLineIndex); } }}void *Thread_GEPLC(void *iPort) //GE PLC 串口Modbus规约处理线程,只能连接一个PLC{ int nPort = *((int *)iPort); int ret,i, k, nLen,nRead,nRecv,iError; int iCon_Number,iNetGroup,nGroup = 0; unsigned short CommandBuff[8]; unsigned char IEC104DataBuf_C[256], ModbusBuff[256]; unsigned char SendBuff[256], RecvBuff[256], YxStore[1024]; unsigned char ucAddr = SubDevice[nPort].SubStations[0].sub_address; if(SubDevice[nPort].SubStations[0].sub_type==0xF3) WriteGR100Data = 1; else WriteGR100Data = 0; if(SubDevice[nPort].SubStations[0].sub_YC_NUM > 511) // modify for soe SubDevice[nPort].SubStations[0].sub_YC_NUM = 511; if(SubDevice[nPort].SubStations[0].sub_YX_NUM > 512) SubDevice[nPort].SubStations[0].sub_YX_NUM = 512; SubDevice[nPort].SubStations[0].sub_DataTemp[0]=0; //modify for soe 此寄存器存旧的SOE指针old_SOEPointer while(1) { nRead = Read_104Data_From_Memory(nPort,IEC104DataBuf_C); if(nRead>0) { iNetGroup = IEC104DataBuf_C[0]>>4; //读取到的第一个字节的高4位是网络号(0:A网;1:B网) iCon_Number = IEC104DataBuf_C[0]&0x0f; //读取到的第一个字节的低4位连接号(0-5) if(!CONN_IsEngStation(iNetGroup,iCon_Number)) { ret = IEC_Frame_104ToModbus(ModbusBuff,CommandBuff,IEC104DataBuf_C+1); if (ret>0) GEPLC_Command_Handle(nPort,iNetGroup,iCon_Number,ModbusBuff,CommandBuff,ret); } } else { nRead = ReadHMICommand(IEC104DataBuf_C); if( nRead > 0 ) ProcessHMICmd(nPort, ucAddr, IEC104DataBuf_C, nRead); else { iError = 0; nLen = Get_GEPLC_Frame(SendBuff,ucAddr,nGroup,nPort); for(k=0; k<3; k++) { SYS_Delay(200); COMM_SendBuff(nPort, SendBuff, nLen); nRecv = Read_Modbus_Frame(nPort,ucAddr,RecvBuff); if (nRecv>0) { if (SubDevice[nPort].SubStations[0].sub_state == SUB_STATE_OFFLINE) { OnCommOK(nPort, 0); SubDevice[nPort].SubStations[0].sub_state = SUB_STATE_ONLINE; } if(RecvBuff[1]==0x02) CheckYXChange(nPort, YxStore, RecvBuff); if(RecvBuff[1]==0x03) Process_GEPLC_Recv(nPort, RecvBuff); break; } else { if(nRecv<=0) iError++; } } if (iError==3) { if (SubDevice[nPort].SubStations[0].sub_state == SUB_STATE_ONLINE ) { OnCommError(nPort, 0); SubDevice[nPort].SubStations[0].sub_state = SUB_STATE_OFFLINE; } } nGroup++; nGroup%=3; } } }}void *Thread_GR100(void *iPort){ fd_set COM_Read; struct timeval timeout; int nPort = *((int *)iPort); int ret,i,k,nRead,iError = 0; int nLen,nRecv,iRequireNum = 0; int iCon_Number,iNetGroup,uIndex; unsigned short CRC_Check; GR100_DD_DATA DD_Buff[SUB_MAX]; unsigned char IEC104DataBuf_C[256]; unsigned char SendBuff[256],RecvBuff[256]; int SubTotal = SubDevice[nPort].SubTotalNum; unsigned char DevType = SubDevice[nPort].SubStations[0].sub_type; unsigned char ucAddr = SubDevice[nPort].SubStations[0].sub_address; unsigned short usYCAddr; while(1) { switch(DevType) { case 0xF1: //GR100为Modbus Slave(16位模式) case 0xF2: //GR100为Modbus Slave(32位模式) { nRead = Read_104Data_From_Memory(nPort,IEC104DataBuf_C); if(nRead>0) { iNetGroup = IEC104DataBuf_C[0]>>4; iCon_Number = IEC104DataBuf_C[0]&0x0f; if(!CONN_IsEngStation(iNetGroup, iCon_Number)) { uIndex = SUB_AddrToIndex(IEC104DataBuf_C[IEC104_OFFSET_ADDR+1]); GR100_Response_DD(nPort, iNetGroup, iCon_Number, IEC104DataBuf_C+1, &DD_Buff[uIndex]); } } else { iError=0; ucAddr = SubDevice[nPort].SubStations[iRequireNum].sub_address; usYCAddr = SubDevice[nPort].SubStations[iRequireNum].sub_YC_Addr; if (usYCAddr == 63)//默认遥测地址为63,针对通常情况 { nLen = Get_GR100_Frame(SendBuff, nPort, iRequireNum); } else if (usYCAddr == 64)//遥测地址64针对竹格多无零序电压,寄存器地址不连续情况 { nLen = Get_GR100ZGD_Frame(SendBuff, nPort, iRequireNum); } for(k=0;k<3;k++) { COMM_SendBuff(nPort, SendBuff, nLen); SYS_Delay(200); nRecv = Read_Modbus_Frame(nPort,ucAddr,RecvBuff); if(nRecv>0) { if (SubDevice[nPort].SubStations[iRequireNum].sub_state == SUB_STATE_OFFLINE) { GR100_Data[0] = 0; GR100_Data[1] = 1; OnCommOK(nPort,iRequireNum); SubDevice[nPort].SubStations[iRequireNum].sub_state = SUB_STATE_ONLINE; } if (usYCAddr == 63) { Process_GR100_Recv(nPort, RecvBuff, iRequireNum); } else if (usYCAddr == 64) { Process_GR100ZGD_Recv(nPort, RecvBuff, iRequireNum); } break; } else { if(nRecv<=0) iError++; } SYS_Delay(200); } if (iError==3) { if (SubDevice[nPort].SubStations[iRequireNum].sub_state == SUB_STATE_ONLINE ) { GR100_Data[0] = 0; GR100_Data[1] = 0; OnCommError(nPort,iRequireNum); SubDevice[nPort].SubStations[iRequireNum].sub_state = SUB_STATE_OFFLINE; } } SYS_Delay(300); iRequireNum = (iRequireNum+1)%SubTotal ; } } break; case 0xF3: //GR100为Modbus Master(16位模式) { nRead = Read_104Data_From_Memory(nPort,IEC104DataBuf_C); if(nRead>0) { iNetGroup = IEC104DataBuf_C[0]>>4; iCon_Number = IEC104DataBuf_C[0]&0x0f; if(!CONN_IsEngStation(iNetGroup, iCon_Number)) Response_COMState(nPort,iNetGroup,iCon_Number,IEC104DataBuf_C+1);//总召唤时上送通信状态 } timeout.tv_sec = 0; timeout.tv_usec = 200000; FD_ZERO(&COM_Read); FD_SET(COM[nPort], &COM_Read); if(select(COM[nPort]+1, &COM_Read, NULL, NULL, &timeout) != 0) { if(FD_ISSET(COM[nPort], &COM_Read)) { nRecv = Read_Modbus_Cmd(nPort, ucAddr, RecvBuff); if(nRecv>0) { memcpy(SendBuff, RecvBuff, 6); CRC_Check = CRC16(SendBuff, 6); SendBuff[6] = HIBYTE(CRC_Check); SendBuff[7] = LOBYTE(CRC_Check); COMM_SendBuff(nPort, SendBuff, 8); iError = 0; if(SubDevice[nPort].SubStations[0].sub_state == SUB_STATE_OFFLINE) { OnCommOK(nPort,0); SubDevice[nPort].SubStations[0].sub_state = SUB_STATE_ONLINE; } ProcessMasterGR100(nPort, RecvBuff); } else { if(nRecv==Error_Recv) COM_Clear(nPort); } } } iError++; if(iError >= 100) //如果200个运行周期没有正确接收到数据,报通讯中断 { iError = 0; if(SubDevice[nPort].SubStations[0].sub_state == SUB_STATE_ONLINE) { iError = 0; OnCommError(nPort,0); SubDevice[nPort].SubStations[0].sub_state = SUB_STATE_OFFLINE; } } } break; } }}void *Thread_TCWDXJ(void *iPort){ int ret,i,k,m,n; int nPort = *((int *)iPort); int iCon_Number,iNetGroup,iError=0; int nLen,nRead,nRecv,iRequireNum = 0; unsigned char SendBuff[256],RecvBuff[256]; unsigned char ucAddr,IEC104DataBuf_C[256]; int SubTotal = SubDevice[nPort].SubTotalNum; for(i=0; i<SubTotal; i++) { if(SubDevice[nPort].SubStations[i].sub_YC_NUM%24 == 0) SubDevice[nPort].SubStations[i].sub_FunOrder = SubDevice[nPort].SubStations[i].sub_YC_NUM/24; else SubDevice[nPort].SubStations[i].sub_FunOrder = SubDevice[nPort].SubStations[i].sub_YC_NUM/24+1; } while(1) { nRead=Read_104Data_From_Memory(nPort,IEC104DataBuf_C); if(nRead>0) { iNetGroup = IEC104DataBuf_C[0]>>4; iCon_Number = IEC104DataBuf_C[0]&0x0f; if(!CONN_IsEngStation(iNetGroup,iCon_Number)) Response_COMState(nPort,iNetGroup,iCon_Number,IEC104DataBuf_C+1);//总召唤时上送通信状态 } else { iError=0; ucAddr = SubDevice[nPort].SubStations[iRequireNum].sub_address; for(n=0; n<SubDevice[nPort].SubStations[iRequireNum].sub_FunOrder; n++) { nLen = Get_TCWDXJ_Frame(SendBuff, nPort, iRequireNum, n); for(k=0;k<3;k++) { COMM_SendBuff(nPort, SendBuff, nLen); SYS_Delay(200); nRecv = Read_TCWDXJ_Frame(nPort, iRequireNum, n, RecvBuff); if (nRecv>0) { if (SubDevice[nPort].SubStations[iRequireNum].sub_state == SUB_STATE_OFFLINE) { OnCommOK(nPort,iRequireNum); SubDevice[nPort].SubStations[iRequireNum].sub_state = SUB_STATE_ONLINE; } Process_TCWDXJ_Recv(RecvBuff, nPort, iRequireNum, n); break; } else { if(nRecv<=0) iError++; } SYS_Delay(300); } if (iError==3) { if (SubDevice[nPort].SubStations[iRequireNum].sub_state == SUB_STATE_ONLINE ) { OnCommError(nPort,iRequireNum); SubDevice[nPort].SubStations[iRequireNum].sub_state = SUB_STATE_OFFLINE; } } SYS_Delay(500); } iRequireNum = (iRequireNum+1)%SubTotal; } }}void *Thread_DL645(void *iPort){ int nPort=*((int *)iPort); unsigned long ulInf ; unsigned short TempYC[16]; int i,j,k,m,TotalMeter,uInf_Modbus=-1; int ret,nLen,nRead,nRecv,iRequireNum=0; int iCon_Number,iNetGroup,iErrCount,offset; unsigned char ucSect=1,SendBuff[16],RecvBuff[256]; unsigned char IEC104DataBuf_C[256],ucBuff[32]; unsigned char DeviceAddr=SubDevice[nPort].SubStations[0].sub_address; unsigned char ucDI[] = {0x10, 0x90, 0x10, 0x91, 0x20, 0x91, 0x20, 0x90}; unsigned short ucCMD_IA[10]={0xB611,0xB612,0xB613,0xB621,0xB622,0xB623,0xB630,0xB640,0xB650,0xB664}; unsigned char DevType = SubDevice[nPort].SubStations[0].sub_type; unsigned char RequirePQ = 0, ConvertBuff[16], SerialNum[16][6] ; if(SubDevice[nPort].SubStations[0].sub_type == 0xF3) { offset = 50*(nPort-1); TotalMeter = LOBYTE(MyFlashBuff[DianDuAddr + offset]); if(TotalMeter>16) TotalMeter = 16; printf("%d",TotalMeter); for(i=0;i<TotalMeter;i++) { for(j=0;j<3;j++) { SerialNum[i][2*j+0] = LOBYTE(MyFlashBuff[DianDuAddr+1 + offset + 3*i + j]); SerialNum[i][2*j+1] = HIBYTE(MyFlashBuff[DianDuAddr+1 + offset + 3*i + j]); } DL645_Meter[nPort].WS_Meter[i].SubState= SUB_STATE_OFFLINE; } } else { TotalMeter = SubDevice[nPort].SubStations[0].sub_YC_NUM; if(TotalMeter>16) TotalMeter=16; for(i=0;i<TotalMeter;i++)//把该串口下所有的电度表视为一个装置,YC_Num为电度表个数 { DL645_Meter[nPort].WS_Meter[i].SubAddr = HEX_TO_BCD(i+1); DL645_Meter[nPort].WS_Meter[i].SubState= SUB_STATE_OFFLINE; } if(SubDevice[nPort].SubStations[0].sub_type==0xF2) RequirePQ = 1; } DL645_Meter[nPort].iMeter = TotalMeter; while(1) { nRead = Read_104Data_From_Memory(nPort,IEC104DataBuf_C); if(nRead>0) { iNetGroup = IEC104DataBuf_C[0]>>4; iCon_Number = IEC104DataBuf_C[0]&0x0f; if(!CONN_IsEngStation(iNetGroup,iCon_Number)) Response_DL645_DD(nPort,iNetGroup,iCon_Number,IEC104DataBuf_C+1); } else { for( i = 0; i < TotalMeter; i++ )//查完所有电表 { if (DL645_Meter[nPort].WS_Meter[i].SubState == SUB_STATE_ONLINE) //只要有一块电表通讯正常就认为装置通讯正常 { if (SubDevice[nPort].SubStations[0].sub_state == SUB_STATE_OFFLINE) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -