📄 modbussal.cpp
字号:
#include "modbussal.h"#include "modbusregset.h"#include "msdevset.h"void* CModbusSAL::thrdModbusSlave(void *pVoid){ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); CModbusSAL *pAS = (CModbusSAL *)pVoid; sleep(2); while (1) { CFrameNode fnRecv; if (pAS->m_DLService.IND(fnRecv) == 1) //有指示; pAS->ProcessIND(fnRecv); }}CModbusSAL::CModbusSAL(CAllMgr* pAllMgr,CSerialPortDef* pChannel) : CSAppService(pAllMgr,true) , m_DLService(pChannel,true){ m_hThread = 0; m_wChannelID = pChannel->m_wChannelNo;}CModbusSAL::~CModbusSAL(){ if (m_hThread > 0) { cout << "modbus slave: " << m_hThread << endl; pthread_cancel(m_hThread); }}bool CModbusSAL::Init(){ bool bRet = false; xbXBase x,x1; CModbusRegDefSet setReg(&x,"MSREG.DBF"); CMSDevSet setDev(&x1); if (setDev.GetFirst()) { do { if (m_wChannelID == setDev.m_wChannelID) { struMSDev dev; if (setReg.GetFirst()) { do { if (setReg.m_wMSDevID == setDev.m_wDevID) { struLocal local; struReg reg; local.wDevNo = setReg.m_wDevID; local.wLocalNo = setReg.m_wRegAddr; reg.wArea = setReg.m_wArea; reg.wRegAddr = setReg.m_wLocalAddr; pair <struReg, struLocal> temp(reg,local); dev.mapRegs.insert(temp); } } while (setReg.GetNext()); } dev.byAddr = setDev.m_byDllAddr; m_setRegs.insert(dev); }
} while (setDev.GetNext());
}
if (m_DLService.Status() == 0)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if (pthread_create(&m_hThread,&attr,CModbusSAL::thrdModbusSlave,(void *)this) == 0)
bRet = true;
else m_hThread = 0;
pthread_attr_destroy(&attr);
}
return bRet;}void CModbusSAL::ProcessIND(CFrameNode& fnRecv){ struMSDev dev; dev.byAddr = fnRecv.m_bySrcAddr; set<struMSDev>::const_iterator it1 = m_setRegs.find(dev); if (it1 != m_setRegs.end()) { CFrameNode fnSend; fnSend.m_byDesAddr = fnRecv.m_bySrcAddr; fnSend.m_byCID = fnRecv.m_byCID; BYTE* pbySource = fnRecv.m_pbyData; if (fnRecv.m_wSize != 4) { // exception 3 - bad structure to message fnSend.m_byCID |= 0x80; fnSend.SetSize(1); fnSend.m_pbyData[0] = 3; } else { switch(fnRecv.m_byCID) { case 4: // <10000 ?3xxxx :8xxxx read n input word { // read registers // request 03 rr rr nn nn // response 03 bb da ta ...... unsigned regNo = CW(pbySource); unsigned regCount = CW(pbySource); if (regCount == 0) regCount=1; if (regCount >126) regCount = 126; if ((regNo < 10000) && (regCount + regNo > 10000)) regCount = 10000-regNo; struReg reg; reg.wArea = 3; if (regNo>=10000) { regNo = regNo-10000; reg.wArea = 8; if (regCount > 63) regCount = 63; } BYTE byBYTESize = (reg.wArea == 3)?(regCount*2):(regCount*4); fnSend.SetSize(1+byBYTESize); BYTE* pbyTemp = fnSend.m_pbyData; *pbyTemp++ = byBYTESize; WORD w1=0; for (WORD w=0;w<regCount;w++,regNo++) { struLocal local; reg.wRegAddr = regNo; map<struReg, struLocal>::const_iterator it = it1->mapRegs.find(reg); if (it != it1->mapRegs.end()) { local = it->second; CAnalog* pAnalog = m_pAllMgr->GetAnalog(local.wDevNo*1000+local.wLocalNo); if (pAnalog) { w1++; double fValue = pAnalog->GetValue(); if (reg.wArea == 8) { long lValue = (long) fValue; SDW(lValue,pbyTemp); } else { short sValue = (short) fValue; SW(sValue,pbyTemp); } } else { if (reg.wArea == 8) SDW(0,pbyTemp); else SW(0,pbyTemp); } } else { *pbyTemp ++ = 0; *pbyTemp ++ = 0; if (reg.wArea == 8) { *pbyTemp ++ = 0; *pbyTemp ++ = 0; } } }//end for if (w1 == 0) { fnSend.m_byCID |= 0x80; fnSend.SetSize(1); fnSend.m_pbyData[0] = 4; } break; } case 5: //0xxxx, YK, write 1 bit { unsigned bitregNo = CW(pbySource); unsigned w = CW(pbySource); bool bOn = (w==0)?false:true; struLocal local; struReg reg; reg.wArea = 0; reg.wRegAddr = bitregNo; map<struReg, struLocal>::const_iterator it = it1->mapRegs.find(reg); if (it != it1->mapRegs.end()) { local = it->second; if (!m_pAllMgr->YK(local.wDevNo,local.wLocalNo,bOn)) { fnSend.m_byCID |= 0x80; fnSend.SetSize(1); fnSend.m_pbyData[0] = 3; } else { fnSend.SetSize(4); BYTE* pbyTemp = fnSend.m_pbyData; SW(bitregNo,pbyTemp); SW(w,pbyTemp); } } else { fnSend.m_byCID |= 0x80; fnSend.SetSize(1); fnSend.m_pbyData[0] = 4; } break; } case 2://1xxxx read n input bit { unsigned regNo = CW(pbySource); unsigned regCount = CW(pbySource); BYTE byBYTESize = (regCount/8)+((regCount%8)?1:0); fnSend.SetSize(1+byBYTESize); BYTE* pbyTemp = fnSend.m_pbyData; *pbyTemp++ = byBYTESize; struReg reg; reg.wArea = 1; WORD w1=0; for (WORD w=0;w<regCount;w++,regNo++) { if (w%8 == 0) *(pbyTemp + w/8) = 0; struLocal local; reg.wRegAddr = regNo; map<struReg, struLocal>::const_iterator it = it1->mapRegs.find(reg); if (it != it1->mapRegs.end()) { local = it->second; CDigital* pDigital = m_pAllMgr->GetDigital(local.wDevNo*1000+local.wLocalNo); if (pDigital) { w1++; bool bValue = pDigital->GetValue(); BYTE byValue = *(pbyTemp + w/8); BYTE bbb=1<<(w%8); if (bValue) *(pbyTemp + w/8) = byValue | bbb; else { bbb = ~bbb; *(pbyTemp + w/8) = byValue & bbb; } } } } // OK so prepare the 'OK response' if (w1 == 0) { fnSend.m_byCID |= 0x80; fnSend.SetSize(1); fnSend.m_pbyData[0] = 4; } break; } default: // generate exception 1 - unknown function code fnSend.m_byCID |= 0x80; fnSend.SetSize(1); fnSend.m_pbyData[0] = 1; break; } } m_DLService.RESP(&fnSend); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -