diff --git a/silecs-codegen/src/xml/genparam.py b/silecs-codegen/src/xml/genparam.py index 206c6073d87fd3d70d3123b83a392adbb624f606..9aa31a1c988326ea475e07b4cb30a284dc2c08d1 100644 --- a/silecs-codegen/src/xml/genparam.py +++ b/silecs-codegen/src/xml/genparam.py @@ -128,9 +128,9 @@ def alignM340RegAddress(addr, format, size, dim, dim2, strLen): msize = msize * 2 # while string and uint8-array use 8bit alignment return addr -# Adjust the register address relying on the DIGI-Rabbit RCMx alignment constraints +# Adjust the register address relying on the DIGI-Rabbit RCMx and PCLike alignment constraints # Use 16bits processor and base-address is interpreted as 16bit address -def alignDIGIRegAddress(addr, format, size, dim, dim2, strLen): +def alignPCLikeRegAddress(addr, format, size, dim, dim2, strLen): global msize # internal string/unicode to integer cast @@ -481,18 +481,19 @@ def computeChecksumClass(designDOM, CRC32, logTopics={'errorlog': True}): # This logic allows having a unique adress computing whatever the mode {DEVICE/BLOCK} and the PLC model. # Concerning SIEMENS PLC, block alignment should respect the 16bits alignement constraint for Struct&Array. whichBaseAlignment = { - 'SIMATIC_S7-300' : '16', - 'SIMATIC_S7-400' : '16', - 'SIMATIC_S7-1200' : '16', - 'SIMATIC_S7-1500' : '16', - 'SIMATIC_ET-200S' : '16', - 'SIMATIC_S7-VIRTUAL': '16', - 'Premium' : '16', - 'Quantum' : '16', - 'M340' : '32', # any data-block of M340 model will start on 32bits address + 'SIMATIC_S7-300' : '16', + 'SIMATIC_S7-400' : '16', + 'SIMATIC_S7-1200' : '16', + 'SIMATIC_S7-1500' : '16', + 'SIMATIC_ET-200S' : '16', + 'Premium' : '16', + 'Quantum' : '16', + 'M340' : '32', # any data-block of M340 model will start on 32bits address # even if the first register of the block is a 16bit data. 'Rabbit_RCM_4010' : '16', 'Rabbit_RCM_2000' : '16', + 'S7_virtual_controller' : '16', + 'MODBUS_virtual_controller' : '16', 'BC9020' : '16', 'CX9020' : '32' } @@ -527,7 +528,6 @@ whichRegAddressFunction = { 'SIMATIC_S7-1200' : alignSimaticRegAddress, 'SIMATIC_S7-1500' : alignSimaticRegAddress, 'SIMATIC_ET-200S' : alignSimaticRegAddress, - 'SIMATIC_S7-VIRTUAL' : alignSimaticRegAddress, 'Premium' : alignPremiumRegAddress, 'Quantum' : alignPremiumRegAddress, 'M340' : alignM340RegAddress, @@ -536,8 +536,10 @@ whichRegAddressFunction = { 'PXI_Windows' : alignCNVRegAddress, 'PC_Windows' : alignCNVRegAddress, 'Other_Support_CNV' : alignCNVRegAddress, - 'Rabbit_RCM_4010' : alignDIGIRegAddress, - 'Rabbit_RCM_2000' : alignDIGIRegAddress, + 'Rabbit_RCM_4010' : alignPCLikeRegAddress, + 'Rabbit_RCM_2000' : alignPCLikeRegAddress, + 'S7_virtual_controller' : alignSimaticRegAddress, + 'MODBUS_virtual_controller' : alignPCLikeRegAddress, 'BC9020' : alignBCxxRegAddress, 'CX9020' : alignCXxxRegAddress } @@ -548,8 +550,8 @@ whichBlkAddressFunction = { 'SCHNEIDER'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress, 'SCHNEIDER'+'DEVICE_MODE' : computeSchneiderDeviceBlkAddress, 'NI'+'DEVICE_MODE' : computeNiDeviceBlkAddress, - 'DIGI'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress, - 'DIGI'+'DEVICE_MODE' : computeSchneiderDeviceBlkAddress, + 'PCLike'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress, + 'PCLike'+'DEVICE_MODE' : computeSchneiderDeviceBlkAddress, 'BECKHOFF'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress } @@ -559,8 +561,8 @@ whichInstAddressFunction = { 'SCHNEIDER'+'BLOCK_MODE' : computeAnyBlockInstAddress, 'SCHNEIDER'+'DEVICE_MODE' : computeSchneiderDeviceInstAddress, 'NI'+'DEVICE_MODE' : computeNiDeviceInstAddress, - 'DIGI'+'BLOCK_MODE' : computeAnyBlockInstAddress, - 'DIGI'+'DEVICE_MODE' : computeSchneiderDeviceInstAddress, + 'PCLike'+'BLOCK_MODE' : computeAnyBlockInstAddress, + 'PCLike'+'DEVICE_MODE' : computeSchneiderDeviceInstAddress, 'BECKHOFF'+'BLOCK_MODE' : computeAnyBlockInstAddress } @@ -570,8 +572,8 @@ whichBaseAddressFunction = { 'SCHNEIDER'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress, 'SCHNEIDER'+'DEVICE_MODE' : computeSchneiderAnyNextBaseAddress, 'NI'+'DEVICE_MODE' : computeNiAnyNextBaseAddress, - 'DIGI'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress, - 'DIGI'+'DEVICE_MODE' : computeSchneiderAnyNextBaseAddress, + 'PCLike'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress, + 'PCLike'+'DEVICE_MODE' : computeSchneiderAnyNextBaseAddress, 'BECKHOFF'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress } diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py index 13b414785350c8945f0dae9cadd0a183cd3571b8..3f54f475c950f6ae4bc76c8f74d28592001a60ce 100644 --- a/silecs-codegen/src/xml/genplcsrc.py +++ b/silecs-codegen/src/xml/genplcsrc.py @@ -377,7 +377,7 @@ def generateRabbitSources(paramDOM,sourceFolderPath,logTopics): # ---------------------------------------------------- -def generateVirtualS7Sources(paramDOM,sourceFolderPath,logTopics): +def generatePCLikeSources(paramDOM,sourceFolderPath,logTopics): deploy = getDeploymentInformation(paramDOM) includeDesign = '' allocDesign = '' @@ -590,8 +590,8 @@ def generateControllerCode(controller, paramsFile, sourceFolderPath, logTopics={ paramDOM = libxml2.parseFile(paramsFile) if controller.plcNode.get_name() == 'Siemens-PLC': generateSiemensSources(paramDOM,sourceFolderPath,logTopics) - elif controller.plcNode.get_name() == 'Virtual-Controller': - generateVirtualS7Sources(paramDOM,sourceFolderPath,logTopics) + elif controller.plcNode.get_name() == 'PC-Controller': + generatePCLikeSources(paramDOM,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'Schneider-PLC': generateSchneiderSources(paramDOM,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'Rabbit-uC': diff --git a/silecs-codegen/src/xml/model/Deploy/Controller.py b/silecs-codegen/src/xml/model/Deploy/Controller.py index 9d1c700d5b5501bfa8e9654870f7711f9276bd1e..341bfa1169aceb30377ef7a350aed55628e2ae4d 100644 --- a/silecs-codegen/src/xml/model/Deploy/Controller.py +++ b/silecs-codegen/src/xml/model/Deploy/Controller.py @@ -92,11 +92,11 @@ class Controller(object): elif type == "Beckhoff-PLC": return BeckhoffController(controllerNode) elif type == "Rabbit-uC": - return DigiController(controllerNode) + return RabbitController(controllerNode) elif type == "NI-Controller": return NIController(controllerNode) - elif type == "Virtual-Controller": - return SiemensController(controllerNode) + elif type == "PC-Controller": + return PCController(controllerNode) else: raise Exception( "Controller-Type " + type + " not supported" ) @@ -132,12 +132,21 @@ class SchneiderController(Controller): self.baseAddress = long(self.plcNode.prop('base-address')) self.baseAddress = self.baseAddress * self.addressFactor -# Formally known as "Rabbit Controller" -class DigiController(Controller): +class RabbitController(Controller): addressFactor = 2 def __init__(self, xmlNode): - super(DigiController, self).__init__(xmlNode) - self.brand = "DIGI" + super(RabbitController, self).__init__(xmlNode) + self.brand = "PCLike" + self.baseAddress = long(self.plcNode.prop('base-address')) + self.baseAddress = self.baseAddress * self.addressFactor + +class PCController(Controller): + def __init__(self, xmlNode): + super(PCController, self).__init__(xmlNode) + self.addressFactor = 2 #default + if self.system == "S7 virtual controller": + self.addressFactor = 1 + self.brand = "PCLike" self.baseAddress = long(self.plcNode.prop('base-address')) self.baseAddress = self.baseAddress * self.addressFactor diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy index 7b44e99e7215d0f001c4298f11325a582871b1eb..d0ed2d44065fd5b00326c3ec8f0c068fd7f26364 100644 --- a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy +++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy @@ -5,10 +5,8 @@ <Editor user-login="schwinn" /> </Information> <Deploy-Unit name="AllTypesDU" version="0.1.0" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"/> - - </SilecsDesign> <Controller host-name="Siemens_TiaDevice"> <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="DEVICE_MODE"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> @@ -37,21 +35,19 @@ </Siemens-PLC> </Controller> + <Controller host-name="Virtual_SiemensDevice"> - <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" base-DB-number="0" protocol="DEVICE_MODE"> - <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <PC-Controller model="S7_virtual_controller" system="S7 virtual controller" protocol="DEVICE_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> - </Virtual-Controller> - + </PC-Controller> </Controller> <Controller host-name="Virtual_SiemensBlock"> - <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" base-DB-number="0" protocol="BLOCK_MODE"> - <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <PC-Controller model="S7_virtual_controller" system="S7 virtual controller" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> - </Virtual-Controller> - - + </PC-Controller> </Controller> <Controller host-name="Beckhoff_BC9020"> <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam index 161f848188630bcd335b864d2b27d2390a242756..f8666ab53e46cc0d1970242f9dacc84b55b96ea4 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam @@ -5,7 +5,7 @@ <Generation date="2017-07-20 10:34:35.299118"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> + <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="PCLike" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam index c762cf3a2d749f31bfcab68027c0c19dc4e600ac..1a75876058b1a9f5baee3408d68aa21162f9809e 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam @@ -5,7 +5,7 @@ <Generation date="2017-07-20 10:34:35.271989"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> + <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="PCLike" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp index 81725a8969790887e6e1bea3673bc57f553bda75..8bb3f2ac3fe9db3ecf68c93e2ad560f57ca5a1c1 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp @@ -71,7 +71,7 @@ namespace Silecs subscriptionFlag_ = false; // Creates receive task which relies on the block exchange - if (getPLC()->getProtocolID() == BlockMode) + if (getPLC()->getProtocolModeID() == BlockMode) pAction_ = new CNVRecvBlockMode(this, name_ + "_" + getPLC()->getName()); else pAction_ = new CNVRecvDeviceMode(this, name_ + "_" + getPLC()->getName()); @@ -281,7 +281,7 @@ namespace Silecs CNVData *structBuilder = (CNVData*)calloc(numberOfReg,sizeof(CNVData)); //allocate space for number of register in the block // Creates send task which relies on the block exchange - if (getPLC()->getProtocolID() == BlockMode) + if (getPLC()->getProtocolModeID() == BlockMode) { // ALLOCATE A OUTPUT BLOCK IN BLOCK MODE int numberOfDevice = thePLC->getDeviceMap().size(); diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp index d27cdd367e0a6a0b518e04424db3295bd98de808..c7c0b8a4bf3e5fd9e096ccf601a329909e53c17f 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp @@ -176,7 +176,7 @@ namespace Silecs CNVData regContent; // will contain the register value in a CNVData format. - if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode) + if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), structBufferSize, address_); @@ -603,7 +603,7 @@ namespace Silecs } unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size(); - if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode) + if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } setRegIntoStructBuffer((CNVData*) pBuffer,structBufferSize, regContent, address_); @@ -623,7 +623,7 @@ namespace Silecs std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_); CNVData regContent; // will contain the register value in a CNVData format - if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode) + if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), structBufferSize, address_); @@ -747,7 +747,7 @@ namespace Silecs } unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size(); - if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode) + if (this->getDevice()->getPLC()->getProtocolModeID()==DeviceMode) { // DEVICE MODE { BlockStruct.reg(1-n) } setRegIntoStructBuffer((CNVData*) pBuffer,structBufferSize, regContent, address_); diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp index b144357b739eb4149002513dc0d550fc6289c67a..99e2f60c7468ce3520a6722f28255618fb7fcdcd 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp @@ -36,7 +36,7 @@ namespace Silecs { // Create buffer for the block exchanges bufferSize_ = memSize_; //size of one block type (including alignements) - if (getPLC()->getProtocolID() == BlockMode) + if (getPLC()->getProtocolModeID() == BlockMode) { //BlockMode ==> access all devices in once bufferSize_ *= getPLC()->getDeviceMap().size(); } @@ -55,7 +55,7 @@ namespace Silecs if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", plc: " << getPLC()->getName() << ", access: Input" << ", address: " << address_ << ", mem-size: " << memSize_ << ", buffer-size: " << bufferSize_; // Creates receive task which relies on the block exchange - if (getPLC()->getProtocolID() == BlockMode) + if (getPLC()->getProtocolModeID() == BlockMode) pAction_ = new PLCRecvBlockMode(this); else pAction_ = new PLCRecvDeviceMode(this); @@ -76,7 +76,7 @@ namespace Silecs if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", plc: " << getPLC()->getName() << ", access: Output" << ", address: " << address_ << ", mem-size: " << memSize_ << ", buffer-size: " << bufferSize_; // Creates send task which relies on the block exchange - if (getPLC()->getProtocolID() == BlockMode) + if (getPLC()->getProtocolModeID() == BlockMode) pAction_ = new PLCSendBlockMode(this); else pAction_ = new PLCSendDeviceMode(this); diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp index de398657404ac67a0b28cffb20872cb84aa82e8c..7339f5a7e116e663c91c81596d9ebac8fa55ef1b 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp @@ -289,27 +289,28 @@ namespace Silecs { for (unsigned int j=0; j<dimension2_; j++) // works also for 1d, in this case j is always 0 and points to the element on the array { - switch(getPLC()->getBrandID()) + if (getPLC()->getBrandID() == Beckhoff) + { //Beckhoff controller implement the standard EPOCH on 32bits word + dtSize = sizeof(uint32_t); + uint32_t *timeVal = (uint32_t *)pData; + swapBytesNToH((unsigned char *)&(timeVal[0]), sizeof(uint32_t)); + ((double *)pRecvValue_)[i*dimension2_+j] = static_cast<double>(timeVal[0]); + } + else if (getPLC()->getProtocolTypeID() == S7Protocol) + { ((double *)pRecvValue_)[i*dimension2_+j] = IeRfcGetTime(pData); + } + else if (getPLC()->getProtocolTypeID() == MBProtocol) { - case Siemens: - ((double *)pRecvValue_)[i*dimension2_+j] = IeRfcGetTime(pData); - break; - case Schneider: - case Digi: #ifdef MODBUS_SUPPORT_ENABLED - ((double *)pRecvValue_)[i*dimension2_+j] = IeMdbGetTime(pData); + ((double *)pRecvValue_)[i*dimension2_+j] = IeMdbGetTime(pData); #endif //MODBUS_SUPPORT_ENABLED - break; - case Ni: - //TODO - break; - case Beckhoff: - //Beckhoff controller implement the standard EPOCH on 32bits word - dtSize = sizeof(uint32_t); - uint32_t *timeVal = (uint32_t *)pData; - swapBytesNToH((unsigned char *)&(timeVal[0]), sizeof(uint32_t)); - ((double *)pRecvValue_)[i*dimension2_+j] = static_cast<double>(timeVal[0]); - break; + } + else if (getPLC()->getProtocolTypeID() == CNVProtocol) + { //TODO for NI + } + else + { //should never occur! + throw SilecsException(__FILE__, __LINE__, (int)UNEXPECTED_ERROR, "Controller protocol type undefined!"); } pData += dtSize; } @@ -369,27 +370,29 @@ namespace Silecs for (unsigned int i=0; i<(dimension1_*dimension2_); i++) { time_t epoch = static_cast<time_t>((double)((double *)pSendValue_)[i]); - switch(getPLC()->getBrandID()) + + if (getPLC()->getBrandID() == Beckhoff) + { //Beckhoff controller implement the standard EPOCH on 32bits word + dtSize = sizeof(uint32_t); + uint32_t *timeVal = (uint32_t *)pData; + timeVal[0] = static_cast<uint32_t>(epoch); + swapBytesHToN((unsigned char *)&(timeVal[0]), sizeof(uint32_t)); + } + else if (getPLC()->getProtocolTypeID() == S7Protocol) + { IeRfcSetTime(pData, epoch); + } + else if (getPLC()->getProtocolTypeID() == MBProtocol) { - case Siemens: - IeRfcSetTime(pData, epoch); - break; - case Schneider: - case Digi: #ifdef MODBUS_SUPPORT_ENABLED - IeMdbSetTime(pData, epoch); + IeMdbSetTime(pData, epoch); #endif //MODBUS_SUPPORT_ENABLED - break; - case Ni: - //TODO - break; - case Beckhoff: - //Beckhoff controller implement the standard EPOCH on 32bits word - dtSize = sizeof(uint32_t); - uint32_t *timeVal = (uint32_t *)pData; - timeVal[0] = static_cast<uint32_t>(epoch); - swapBytesHToN((unsigned char *)&(timeVal[0]), sizeof(uint32_t)); - break; + } + else if (getPLC()->getProtocolTypeID() == CNVProtocol) + { //TODO for NI + } + else + { //should never occur! + throw SilecsException(__FILE__, __LINE__, (int)UNEXPECTED_ERROR, "Controller protocol type undefined!"); } pData += dtSize; } diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp index acd4e217c7650ddad5de5edbf6348b0392486be6..dbb1c9c50dfb7328506e27a3a8ba289c908cbdc6 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp @@ -358,7 +358,11 @@ namespace Silecs brand_ = mappingNode.getAttribute("plc-brand"); system_ = mappingNode.getAttribute("plc-system"); protocolMode_ = mappingNode.getAttribute("protocol"); + model_ = mappingNode.getAttribute("plc-model"); + StringUtilities::fromString(baseAddr_,mappingNode.getAttribute("address") ); + usedMem_ = mappingNode.getAttribute("used-mem"); brandID_ = whichPLCBrand(brand_); + modelID_ = whichPLCModel(model_); systemID_ = whichPLCSystem(system_); protocolModeID_ = whichProtocolMode(protocolMode_); protocolTypeID_ = whichProtocolType(system_); @@ -366,15 +370,10 @@ namespace Silecs switch(protocolTypeID_) { case MBProtocol: protocolType_ = "MODBUS-TCP"; break; - case S7Protocol: protocolType_ = "SNAP7-TCP"; break; + case S7Protocol: protocolType_ = "SNAP7-TCP"; break; case CNVProtocol: protocolType_ = "CNV-TCP"; break; }; - model_ = mappingNode.getAttribute("plc-model"); - modelID_ = whichPLCModel(model_); - StringUtilities::fromString(baseAddr_,mappingNode.getAttribute("address") ); - usedMem_ = mappingNode.getAttribute("used-mem"); - std::vector< boost::shared_ptr<ElementXML> > classNodes = mappingNode.childList_; std::vector< boost::shared_ptr<ElementXML> >::const_iterator classIter; for(classIter = classNodes.begin(); classIter != classNodes.end(); classIter++) @@ -553,50 +552,56 @@ namespace Silecs PLCModel PLC::whichPLCModel(std::string model) { StringUtilities::toLower(model); - if (model == "simatic_et-200s") return ET200S; - else if (model == "simatic_s7-300") return S7300; - else if (model == "simatic_s7-400") return S7400; - else if (model == "simatic_s7-1200") return S71200; - else if (model == "simatic_s7-1500") return S71500; - else if (model == "premium") return Premium; - else if (model == "quantum") return Quantum; - else if (model == "m340") return M340; - else if (model == "bc9020") return BC9020; - else if (model == "cx9020") return CX9020; - else if (model == "rabbit_rcm_4010") return RCM4010; - else if (model == "rabbit_rcm_2000") return RCM2000; - else if (model == "compact_rio") return CompactRIO; - else if (model == "pxi_rt") return PXIRT; - else if (model == "pxi_windows") return PXIWindows; - else if (model == "pc_windows") return PCWindows; - else if (model == "other_support_cnv") return OtherSupportCNV; + if (model == "simatic_et-200s") return ET200S; + else if (model == "simatic_s7-300") return S7300; + else if (model == "simatic_s7-400") return S7400; + else if (model == "simatic_s7-1200") return S71200; + else if (model == "simatic_s7-1500") return S71500; + else if (model == "premium") return Premium; + else if (model == "quantum") return Quantum; + else if (model == "m340") return M340; + else if (model == "bc9020") return BC9020; + else if (model == "cx9020") return CX9020; + else if (model == "rabbit_rcm_4010") return RCM4010; + else if (model == "rabbit_rcm_2000") return RCM2000; + else if (model == "compact_rio") return CompactRIO; + else if (model == "pxi_rt") return PXIRT; + else if (model == "pxi_windows") return PXIWindows; + else if (model == "pc_windows") return PCWindows; + else if (model == "linux_x64") return PCLinux64; + else if (model == "linux_i386") return PCLinux32; + else if (model == "other_support_cnv") return OtherSupportCNV; else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_MODEL, model); } PLCSystem PLC::whichPLCSystem(std::string system) { - StringUtilities::toLower(system); - if (system == "step-7") return Step7; - if (system == "tia-portal") return TiaPortal; - else if (system == "unity pro") return Unity; - else if (system == "twincat") return TwinCat; - else if (system == "standard-c") return StdC; - else if (system == "labview") return Labview; + StringUtilities::toLower(system); + if (system == "step-7") return Step7; + if (system == "tia-portal") return TiaPortal; + else if (system == "unity pro") return Unity; + else if (system == "twincat") return TwinCat; + else if (system == "standard-c") return StdC; + else if (system == "s7 virtual controller") return ServerS7; + else if (system == "modbus virtual controller")return ServerMB; + else if (system == "labview") return Labview; else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_SYSTEM, system); } ProtocolType PLC::whichProtocolType(std::string system) - { + { StringUtilities::toLower(system); - if (system == "step-7") return S7Protocol; - if (system == "tia-portal") return S7Protocol; - else if (system == "unity pro") return MBProtocol; - else if (system == "twincat") return MBProtocol; - else if (system == "standard-c") return MBProtocol; - else if (system == "labview") return CNVProtocol; + if (system == "step-7") return S7Protocol; + if (system == "tia-portal") return S7Protocol; + else if (system == "unity pro") return MBProtocol; + else if (system == "twincat") return MBProtocol; + else if (system == "standard-c") return MBProtocol; + else if (system == "s7 virtual controller") return S7Protocol; + else if (system == "modbus virtual controller") return MBProtocol; + else if (system == "labview") return CNVProtocol; else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_SYSTEM, system); - } + } ProtocolMode PLC::whichProtocolMode(std::string mode) diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h index 8af5ed6156a08b4e0680a7a66be8c669555dd355..85adebbd9a3bb25834396d67b6ab717356694d21 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h @@ -45,18 +45,18 @@ namespace Silecs typedef enum { ET200S, S7300, S7400, S71200, S71500, - S7VIRTUAL, Premium, Quantum, M340, BC9020, CX9020, RCM4010, RCM2000, CompactRIO, - PXIRT, PXIWindows, PCWindows, OtherSupportCNV + PXIRT, PXIWindows, PCWindows, OtherSupportCNV, + PCLinux64, PCLinux32 } PLCModel; typedef enum { - Step7, TiaPortal, Unity, TwinCat, StdC, ServerS7, Labview + Step7, TiaPortal, Unity, TwinCat, StdC, ServerS7, ServerMB, Labview } PLCSystem; typedef enum @@ -145,7 +145,7 @@ namespace Silecs std::string getBrand(); /*! - * \brief Returns the PLC development system: STEP-7, TIA-PORTAL, UNITY Pro, TWINCat, Standard-C, Labview + * \brief Returns the PLC development system: STEP-7, TIA-PORTAL, UNITY Pro, TWINCat, Standard-C, Standard-Cpp, Labview * \return PLC development system */ std::string getSystem(); @@ -388,7 +388,8 @@ namespace Silecs inline PLCBrand& getBrandID() { return brandID_; } inline PLCModel& getModelID() { return modelID_; } inline PLCSystem& getSystemID() { return systemID_; } - inline ProtocolMode& getProtocolID() { return protocolModeID_; } + inline ProtocolMode& getProtocolModeID() { return protocolModeID_; } + inline ProtocolType& getProtocolTypeID() { return protocolTypeID_; } void updateLocalData(); diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp index 0ae7c925704e420522bcefe7366986a4355b2ea8..9025ea8cd5648c25f5abca7516d8951a372e0244 100644 --- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp +++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp @@ -1,6 +1,6 @@ #ifdef MODBUS_SUPPORT_ENABLED #include "iemdb.h" - +#include <modbus.h> //Modbus max data size definition (byte counting) #define MAX_WRITE_DATA_SIZE MODBUS_MAX_WRITE_REGISTERS*2 #define MAX_READ_DATA_SIZE MODBUS_MAX_READ_REGISTERS*2 diff --git a/silecs-model/src/xml/DeploySchema.xsd b/silecs-model/src/xml/DeploySchema.xsd index 1bace0fb95ac049d44c5c08122c941c456fe03a1..7e027cfaddd0eb425eafa1f88ef3e0bf7bd5370a 100644 --- a/silecs-model/src/xml/DeploySchema.xsd +++ b/silecs-model/src/xml/DeploySchema.xsd @@ -132,7 +132,6 @@ </xs:documentation> </xs:annotation> </xs:element> - <!-- No support for this type in CERN codegen so far<xs:element name="Beckhoff-RIO" type="BeckhoffRIOType"> <xs:annotation> <xs:documentation>A Beckhoff-RIO deployment defines the physical Mapping of TwinCAT Remote IO modules.</xs:documentation> </xs:annotation> </xs:element> --> <xs:element name="Rabbit-uC" type="RabbituCType"> <xs:annotation> <xs:documentation>A Rabbit-Mapping defines a particular Mapping of @@ -140,11 +139,9 @@ </xs:documentation> </xs:annotation> </xs:element> - <xs:element name="Virtual-Controller" type="VirtualControllerType"> + <xs:element name="PC-Controller" type="PC-ControllerType"> <xs:annotation> - <xs:documentation>Defines a particular C++ code mapping of classes - intended for Software controller - </xs:documentation> + <xs:documentation>Defines a particular C-code mapping of classes intended for PC-based controller</xs:documentation> </xs:annotation> </xs:element> <xs:element name="NI-Controller" type="NIControllerType"> @@ -244,6 +241,12 @@ <xs:enumeration value="Standard-C" /> </xs:restriction> </xs:simpleType> + <xs:simpleType name="PCSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="S7 virtual controller" /> + <xs:enumeration value="MODBUS virtual controller" /> + </xs:restriction> + </xs:simpleType> <xs:simpleType name="NISystemType"> <xs:restriction base="xs:string"> <xs:enumeration value="Labview" /> @@ -265,32 +268,26 @@ <xs:enumeration value="BLOCK_MODE" /> </xs:restriction> </xs:simpleType> - <xs:simpleType name="PCSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="SNAP7 linux32" /> - <xs:enumeration value="SNAP7 linux64" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="DomainType"> + <xs:simpleType name="DomainType"> <xs:restriction base="xs:string"> - <xs:enumeration value="ALL"/> - <xs:enumeration value="ADE"/> - <xs:enumeration value="CPS"/> - <xs:enumeration value="CTF"/> - <xs:enumeration value="ISO"/> - <xs:enumeration value="LEI"/> - <xs:enumeration value="LHC"/> - <xs:enumeration value="LIN"/> - <xs:enumeration value="LN3"/> - <xs:enumeration value="LN4"/> - <xs:enumeration value="PSB"/> - <xs:enumeration value="REX"/> - <xs:enumeration value="SPS"/> - <xs:enumeration value="TST"/> + <xs:enumeration value="ALL" /> + <xs:enumeration value="ADE" /> + <xs:enumeration value="CPS" /> + <xs:enumeration value="CTF" /> + <xs:enumeration value="ISO" /> + <xs:enumeration value="LEI" /> + <xs:enumeration value="LHC" /> + <xs:enumeration value="LIN" /> + <xs:enumeration value="LN3" /> + <xs:enumeration value="LN4" /> + <xs:enumeration value="PSB" /> + <xs:enumeration value="REX" /> + <xs:enumeration value="SPS" /> + <xs:enumeration value="TST" /> </xs:restriction> </xs:simpleType> - + <xs:complexType name="PLCBaseType"> <xs:sequence> <xs:element name="Device" type="DeviceType" maxOccurs="unbounded" /> @@ -496,9 +493,6 @@ </xs:complexContent> </xs:complexType> - <!-- No support for this type in CERN codegen so far <xs:complexType name="BeckhoffRIOType"> <xs:attribute name="system" type="BeckhoffSystemType" use="required"> <xs:annotation> <xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation> <xs:appinfo> <doc> System infrastructure used to develop and/or configure the Controller software. </doc> </xs:appinfo> </xs:annotation> </xs:attribute> <xs:attribute name="model" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="BK9000"/> <xs:enumeration value="BK9050"/> <xs:enumeration value="BK9100"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="io-base-address" type="xs:unsignedInt" use="required"> <xs:annotation> <xs:documentation>Start address of the Remote IO modules (can be 0 if not required). Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).</xs:documentation> <xs:appinfo> <doc> - Start address of the Remote IO modules (can be 0 if not required). <br>Attention: 16bit address value is expected independently from the HW model (16 or 32 bit). </doc> </xs:appinfo> </xs:annotation> </xs:attribute> </xs:complexType> --> - <xs:complexType name="RabbituCType"> <xs:complexContent> <xs:extension base="PLCBaseType"> @@ -560,19 +554,15 @@ </xs:complexContent> </xs:complexType> - <xs:complexType name="VirtualControllerType"> + <xs:complexType name="PC-ControllerType"> <xs:complexContent> <xs:extension base="PLCBaseType"> <xs:attribute name="system" type="PCSystemType" use="required"> <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> + <xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation> <xs:appinfo> <doc> - System infrastructure used to develop and/or configure the - Controller - software. + System infrastructure used to develop and/or configure the Controller software. </doc> </xs:appinfo> </xs:annotation> @@ -580,39 +570,28 @@ <xs:attribute name="model" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> - <xs:enumeration value="SIMATIC_S7-VIRTUAL" /> + <xs:enumeration value="S7_virtual_controller" /> + <xs:enumeration value="MODBUS_virtual_controller" /> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="protocol" type="BothProtocolType" use="required"> <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> + <xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation> <xs:appinfo> <doc> - DEVICE_MODE: One C struct field per class/device - ([class-name]_[device-label|id]), <br>containing the - corresponding ordered list of Blocks - <br>BLOCK_MODE: One C - struct field per class/block ([class-name]_[block-name]), - <br>containing array of corresponding Block, one element per - device + DEVICE_MODE: One C struct field per class/device ([class-name]_[device-label|id]), <br>containing the corresponding ordered list of Blocks + <br>BLOCK_MODE: One C struct field per class/block ([class-name]_[block-name]), <br>containing array of corresponding Block, one element per device </doc> </xs:appinfo> </xs:annotation> </xs:attribute> - <xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required"> + <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> <xs:annotation> - <xs:documentation>Number of the diagnostic DB that is the first one - of the global configuration (corresponds to the common SilecsHeader - data-block). - </xs:documentation> + <xs:documentation>Start address of the entire SILECS configuration interpreted as 16bit address.</xs:documentation> <xs:appinfo> <doc> - Number of the diagnostic DB that is the first one of the - global - configuration ( >=1) + Start address of the entire SILECS configuration interpreted as 16bit address. </doc> </xs:appinfo> </xs:annotation>