|
UniSet
2.2.1
|
00001 // ------------------------------------------------------------------------- 00002 #ifndef ModbusTypes_H_ 00003 #define ModbusTypes_H_ 00004 // ------------------------------------------------------------------------- 00005 #include <ostream> 00006 #include <bitset> 00007 #include <string> 00008 #include <list> 00009 #include "ModbusRTUErrors.h" 00010 // ------------------------------------------------------------------------- 00011 /* Основные предположения: 00012 * - младший и старший байт переворачиваются только в CRC 00013 * - В случае неправильного формата пакета(запроса), логической ошибки и т.п 00014 * ОТВЕТ просто не посылается, а пакет отбрасывается... 00015 * - CRC считается по всей посылке (с начальным адресом) 00016 * - CRC инициализируется значением 0xffff 00017 * - CRC не переворачивается 00018 * - Все двухбайтовые слова переворачиваются. Порядок байт: старший младший 00019 */ 00020 // ------------------------------------------------------------------------- 00021 namespace ModbusRTU 00022 { 00023 // Базовые типы 00024 typedef unsigned char ModbusByte; 00025 const unsigned short BitsPerByte = 8; 00026 typedef unsigned char ModbusAddr; 00027 typedef unsigned short ModbusData; 00028 const unsigned short BitsPerData = 16; 00029 typedef unsigned short ModbusCRC; 00031 // --------------------------------------------------------------------- 00033 enum SlaveFunctionCode 00034 { 00035 fnUnknown = 0x00, 00036 fnReadCoilStatus = 0x01, 00037 fnReadInputStatus = 0x02, 00038 fnReadOutputRegisters = 0x03, 00039 fnReadInputRegisters = 0x04, 00040 fnForceSingleCoil = 0x05, 00041 fnWriteOutputSingleRegister = 0x06, 00042 fnDiagnostics = 0x08, 00043 fnForceMultipleCoils = 0x0F, 00044 fnWriteOutputRegisters = 0x10, 00045 fnReadFileRecord = 0x14, 00046 fnWriteFileRecord = 0x15, 00047 fnMEI = 0x2B, 00048 fnSetDateTime = 0x50, 00049 fnRemoteService = 0x53, 00050 fnJournalCommand = 0x65, 00051 fnFileTransfer = 0x66 00052 }; 00053 00055 enum DiagnosticsSubFunction 00056 { 00057 subEcho = 0x00, 00058 dgRestartComm = 0x01, 00059 dgDiagReg = 0x02, 00060 dgChangeASCII = 0x03, 00061 dgForceListen = 0x04, 00062 // 05.. 09 RESERVED 00063 dgClearCounters = 0x0A, 00064 dgBusMsgCount = 0x0B, 00065 dgBusErrCount = 0x0C, 00066 dgBusExceptCount = 0x0D, 00067 dgMsgSlaveCount = 0x0E, 00068 dgNoNoResponseCount = 0x0F, 00069 dgSlaveNAKCount = 0x10, 00070 dgSlaveBusyCount = 0x11, 00071 dgBusCharOverrunCount = 0x12, 00072 // = 0x13, /*!< RESERVED */ 00073 dgClearOverrunCounter = 0x14 00074 // 21 ...65535 RESERVED 00075 }; 00076 00077 00078 typedef unsigned long RegID; 00079 00086 RegID genRegID( const ModbusRTU::ModbusData r, const int fn ); 00087 00088 // определение размера данных в зависимости от типа сообщения 00089 // возвращает -1 - если динамический размер сообщения или размер неизвестен 00090 int szRequestDiagnosticData( DiagnosticsSubFunction f ); 00091 00093 enum RDIObjectID 00094 { 00095 rdiVendorName = 0x0, 00096 rdiProductCode = 0x1, 00097 rdiMajorMinorRevision = 0x2, 00098 rdiVendorURL = 0x3, 00099 rdiProductName = 0x4, 00100 rdiModelName = 0x5, 00101 rdiUserApplicationName = 0x6 00102 // 0x07 .. 0x7F - reserved 00103 // 0x80 .. 0xFF - optionaly defined (product dependant) 00104 }; 00105 00107 enum RDIRequestDeviceID 00108 { 00109 rdevMinNum = 0, 00110 rdevBasicDevice = 0x1, // request to get the basic device identification (stream access) 00111 rdevRegularDevice = 0x2, // request to get the regular device identification (stream access) 00112 rdevExtentedDevice = 0x3, // request to get the extended device identification (stream access) 00113 rdevSpecificDevice = 0x4, // request to get the extended device identification (stream access) 00114 rdevMaxNum = 0x5 00115 }; 00116 00117 std::string rdi2str( int id ); 00118 // ----------------------------------------------------------------------- 00119 00121 enum 00122 { 00124 MAXLENPACKET = 508, 00125 BroadcastAddr = 255, 00126 MAXPDULEN = 253, // 255 - 2(CRC) 00127 MAXDATALEN = 125 00131 }; 00132 00133 const unsigned char MBErrMask = 0x80; 00134 // --------------------------------------------------------------------- 00135 unsigned short SWAPSHORT(unsigned short x); 00136 // --------------------------------------------------------------------- 00138 ModbusCRC checkCRC( ModbusByte* start, int len ); 00139 const int szCRC = sizeof(ModbusCRC); 00140 // --------------------------------------------------------------------- 00142 std::ostream& mbPrintMessage( std::ostream& os, ModbusByte* b, int len ); 00143 // ------------------------------------------------------------------------- 00144 ModbusAddr str2mbAddr( const std::string& val ); 00145 ModbusData str2mbData( const std::string& val ); 00146 std::string dat2str( const ModbusData dat ); 00147 std::string addr2str( const ModbusAddr addr ); 00148 std::string b2str( const ModbusByte b ); 00149 // ------------------------------------------------------------------------- 00150 float dat2f( const ModbusData dat1, const ModbusData dat2 ); 00151 // ------------------------------------------------------------------------- 00152 bool isWriteFunction( SlaveFunctionCode c ); 00153 // ------------------------------------------------------------------------- 00155 struct ModbusHeader 00156 { 00157 ModbusAddr addr; 00158 ModbusByte func; 00160 ModbusHeader(): addr(0), func(0) {} 00161 } __attribute__((packed)); 00162 00163 const int szModbusHeader = sizeof(ModbusHeader); 00164 std::ostream& operator<<(std::ostream& os, ModbusHeader& m ); 00165 std::ostream& operator<<(std::ostream& os, ModbusHeader* m ); 00166 // ----------------------------------------------------------------------- 00167 00171 struct ModbusMessage: 00172 public ModbusHeader 00173 { 00174 ModbusMessage(); 00175 ModbusByte data[MAXLENPACKET + szCRC]; 00177 // Это поле вспомогательное и игнорируется при пересылке 00178 size_t len; 00179 } __attribute__((packed)); 00180 00181 std::ostream& operator<<(std::ostream& os, ModbusMessage& m ); 00182 std::ostream& operator<<(std::ostream& os, ModbusMessage* m ); 00183 // ----------------------------------------------------------------------- 00185 struct ErrorRetMessage: 00186 public ModbusHeader 00187 { 00188 ModbusByte ecode = { erNoError }; 00189 ModbusCRC crc = { 0 }; 00190 00191 // ------- from slave ------- 00192 ErrorRetMessage( ModbusMessage& m ); 00193 ErrorRetMessage& operator=( ModbusMessage& m ); 00194 void init( ModbusMessage& m ); 00195 00196 // ------- to master ------- 00197 ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode ); 00198 00200 ModbusMessage transport_msg(); 00201 00205 inline static int szData() 00206 { 00207 return sizeof(ModbusByte) + szCRC; 00208 } 00209 }; 00210 00211 std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m ); 00212 std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m ); 00213 // ----------------------------------------------------------------------- 00214 struct DataBits 00215 { 00216 DataBits( ModbusByte b ); 00217 DataBits( std::string s ); // example "10001111" 00218 DataBits(); 00219 00220 const DataBits& operator=(const ModbusByte& r); 00221 00222 operator ModbusByte(); 00223 ModbusByte mbyte(); 00224 00225 bool operator[]( const size_t i ) 00226 { 00227 return b[i]; 00228 } 00229 void set( int n, bool s ) 00230 { 00231 b.set(n, s); 00232 } 00233 00234 std::bitset<BitsPerByte> b; 00235 }; 00236 00237 std::ostream& operator<<(std::ostream& os, DataBits& m ); 00238 std::ostream& operator<<(std::ostream& os, DataBits* m ); 00239 // ----------------------------------------------------------------------- 00240 struct DataBits16 00241 { 00242 DataBits16( ModbusData d ); 00243 DataBits16( const std::string& s ); // example "1000111110001111" 00244 DataBits16(); 00245 00246 const DataBits16& operator=(const ModbusData& r); 00247 00248 operator ModbusData(); 00249 ModbusData mdata(); 00250 00251 bool operator[]( const size_t i ) 00252 { 00253 return b[i]; 00254 } 00255 void set( int n, bool s ) 00256 { 00257 b.set(n, s); 00258 } 00259 00260 std::bitset<BitsPerData> b; 00261 }; 00262 00263 std::ostream& operator<<(std::ostream& os, DataBits16& m ); 00264 std::ostream& operator<<(std::ostream& os, DataBits16* m ); 00265 // ----------------------------------------------------------------------- 00267 struct ReadCoilMessage: 00268 public ModbusHeader 00269 { 00270 ModbusData start = { 0 }; 00271 ModbusData count = { 0 }; 00272 ModbusCRC crc = { 0 }; 00273 00274 // ------- to slave ------- 00275 ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00277 ModbusMessage transport_msg(); 00278 00279 // ------- from master ------- 00280 ReadCoilMessage( ModbusMessage& m ); 00281 ReadCoilMessage& operator=( ModbusMessage& m ); 00282 void init( ModbusMessage& m ); 00283 00285 inline static int szData() 00286 { 00287 return sizeof(ModbusData) * 2 + szCRC; 00288 } 00289 00290 } __attribute__((packed)); 00291 00292 std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m ); 00293 std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m ); 00294 00295 // ----------------------------------------------------------------------- 00296 00298 struct ReadCoilRetMessage: 00299 public ModbusHeader 00300 { 00301 ModbusByte bcnt = { 0 }; 00302 ModbusByte data[MAXLENPACKET]; 00304 // ------- from slave ------- 00305 ReadCoilRetMessage( ModbusMessage& m ); 00306 ReadCoilRetMessage& operator=( ModbusMessage& m ); 00307 void init( ModbusMessage& m ); 00311 static inline int szHead() 00312 { 00313 return sizeof(ModbusByte); // bcnt 00314 } 00315 00317 static int getDataLen( ModbusMessage& m ); 00318 ModbusCRC crc = { 0 }; 00319 00320 // ------- to master ------- 00321 ReadCoilRetMessage( ModbusAddr _from ); 00322 00327 bool addData( DataBits d ); 00328 00336 bool setBit( unsigned char dnum, unsigned char bnum, bool state ); 00337 00344 bool getData( unsigned char bnum, DataBits& d ); 00345 00347 void clear(); 00348 00350 inline bool isFull() 00351 { 00352 return ( (int)bcnt >= MAXPDULEN ); 00353 } 00354 00356 size_t szData(); 00357 00359 ModbusMessage transport_msg(); 00360 }; 00361 00362 std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m ); 00363 std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m ); 00364 // ----------------------------------------------------------------------- 00366 struct ReadInputStatusMessage: 00367 public ModbusHeader 00368 { 00369 ModbusData start = { 0 }; 00370 ModbusData count = { 0 }; 00371 ModbusCRC crc = { 0 }; 00372 00373 // ------- to slave ------- 00374 ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00376 ModbusMessage transport_msg(); 00377 00378 // ------- from master ------- 00379 ReadInputStatusMessage( ModbusMessage& m ); 00380 ReadInputStatusMessage& operator=( ModbusMessage& m ); 00381 void init( ModbusMessage& m ); 00382 00384 inline static int szData() 00385 { 00386 return sizeof(ModbusData) * 2 + szCRC; 00387 } 00388 00389 } __attribute__((packed)); 00390 00391 std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m ); 00392 std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m ); 00393 // ----------------------------------------------------------------------- 00395 struct ReadInputStatusRetMessage: 00396 public ModbusHeader 00397 { 00398 ModbusByte bcnt = { 0 }; 00399 ModbusByte data[MAXLENPACKET]; 00401 // ------- from slave ------- 00402 ReadInputStatusRetMessage( ModbusMessage& m ); 00403 ReadInputStatusRetMessage& operator=( ModbusMessage& m ); 00404 void init( ModbusMessage& m ); 00408 static inline int szHead() 00409 { 00410 return sizeof(ModbusByte); // bcnt 00411 } 00412 00414 static int getDataLen( ModbusMessage& m ); 00415 ModbusCRC crc = { 0 }; 00416 00417 // ------- to master ------- 00418 ReadInputStatusRetMessage( ModbusAddr _from ); 00419 00424 bool addData( DataBits d ); 00425 00433 bool setBit( unsigned char dnum, unsigned char bnum, bool state ); 00434 00441 bool getData( unsigned char dnum, DataBits& d ); 00442 00444 void clear(); 00445 00447 inline bool isFull() 00448 { 00449 return ( (int)bcnt >= MAXPDULEN ); 00450 } 00451 00453 size_t szData(); 00454 00456 ModbusMessage transport_msg(); 00457 }; 00458 00459 std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m ); 00460 std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m ); 00461 // ----------------------------------------------------------------------- 00462 00464 struct ReadOutputMessage: 00465 public ModbusHeader 00466 { 00467 ModbusData start = { 0 }; 00468 ModbusData count = { 0 }; 00469 ModbusCRC crc = { 0 }; 00470 00471 // ------- to slave ------- 00472 ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00474 ModbusMessage transport_msg(); 00475 00476 // ------- from master ------- 00477 ReadOutputMessage( ModbusMessage& m ); 00478 ReadOutputMessage& operator=( ModbusMessage& m ); 00479 void init( ModbusMessage& m ); 00480 00482 inline static int szData() 00483 { 00484 return sizeof(ModbusData) * 2 + szCRC; 00485 } 00486 00487 } __attribute__((packed)); 00488 00489 std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m ); 00490 std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m ); 00491 // ----------------------------------------------------------------------- 00493 struct ReadOutputRetMessage: 00494 public ModbusHeader 00495 { 00496 ModbusByte bcnt = { 0 }; 00497 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 00499 // ------- from slave ------- 00500 ReadOutputRetMessage( ModbusMessage& m ); 00501 ReadOutputRetMessage& operator=( ModbusMessage& m ); 00502 void init( ModbusMessage& m ); 00506 static inline int szHead() 00507 { 00508 // bcnt 00509 return sizeof(ModbusByte); 00510 } 00511 00513 static int getDataLen( ModbusMessage& m ); 00514 ModbusCRC crc = { 0 }; 00515 00516 // ------- to master ------- 00517 ReadOutputRetMessage( ModbusAddr _from ); 00518 00523 bool addData( ModbusData d ); 00524 00526 void clear(); 00527 00529 inline bool isFull() 00530 { 00531 return ( count * sizeof(ModbusData) >= MAXLENPACKET ); 00532 } 00533 00535 size_t szData(); 00536 00538 ModbusMessage transport_msg(); 00539 00540 // Это поле не входит в стандарт modbus 00541 // оно вспомогательное и игнорируется при 00542 // преобразовании в ModbusMessage. 00543 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 00544 // Используйте специальную функцию transport_msg() 00545 size_t count = { 0 }; 00546 }; 00547 00548 std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m ); 00549 std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m ); 00550 // ----------------------------------------------------------------------- 00552 struct ReadInputMessage: 00553 public ModbusHeader 00554 { 00555 ModbusData start = { 0 }; 00556 ModbusData count = { 0 }; 00557 ModbusCRC crc = { 0 }; 00558 00559 // ------- to slave ------- 00560 ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00562 ModbusMessage transport_msg(); 00563 00564 // ------- from master ------- 00565 ReadInputMessage( ModbusMessage& m ); 00566 ReadInputMessage& operator=( ModbusMessage& m ); 00567 void init( ModbusMessage& m ); 00568 00570 inline static int szData() 00571 { 00572 return sizeof(ModbusData) * 2 + szCRC; 00573 } 00574 00575 } __attribute__((packed)); 00576 00577 std::ostream& operator<<(std::ostream& os, ReadInputMessage& m ); 00578 std::ostream& operator<<(std::ostream& os, ReadInputMessage* m ); 00579 // ----------------------------------------------------------------------- 00580 00582 struct ReadInputRetMessage: 00583 public ModbusHeader 00584 { 00585 ModbusByte bcnt = { 0 }; 00586 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 00588 // ------- from slave ------- 00589 ReadInputRetMessage( ModbusMessage& m ); 00590 ReadInputRetMessage& operator=( ModbusMessage& m ); 00591 void init( ModbusMessage& m ); 00595 static inline int szHead() 00596 { 00597 // bcnt 00598 return sizeof(ModbusByte); 00599 } 00600 00602 static int getDataLen( ModbusMessage& m ); 00603 ModbusCRC crc = { 0 }; 00604 00605 // ------- to master ------- 00606 ReadInputRetMessage( ModbusAddr _from ); 00607 00612 bool addData( ModbusData d ); 00613 00615 void clear(); 00616 00618 inline bool isFull() 00619 { 00620 return ( count * sizeof(ModbusData) >= MAXLENPACKET ); 00621 } 00622 00623 void swapData(); 00624 00626 size_t szData(); 00627 00629 ModbusMessage transport_msg(); 00630 00631 // Это поле не входит в стандарт modbus 00632 // оно вспомогательное и игнорируется при 00633 // преобразовании в ModbusMessage. 00634 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 00635 // Используйте специальную функцию transport_msg() 00636 size_t count = { 0 }; 00637 }; 00638 00639 std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m ); 00640 std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m ); 00641 // ----------------------------------------------------------------------- 00643 struct ForceCoilsMessage: 00644 public ModbusHeader 00645 { 00646 ModbusData start = { 0 }; 00647 ModbusData quant = { 0 }; 00648 ModbusByte bcnt = { 0 }; 00650 ModbusByte data[MAXLENPACKET - sizeof(ModbusData) * 2 - sizeof(ModbusByte)]; 00651 ModbusCRC crc = { 0 }; 00653 // ------- to slave ------- 00654 ForceCoilsMessage( ModbusAddr addr, ModbusData start ); 00656 ModbusMessage transport_msg(); 00657 00662 bool addData( DataBits d ); 00663 00664 // return number of bit 00665 // -1 - error 00666 int addBit( bool state ); 00667 00668 bool setBit( int nbit, bool state ); 00669 00670 inline int last() 00671 { 00672 return quant; 00673 } 00674 00681 bool getData( unsigned char dnum, DataBits& d ); 00682 00683 bool getBit( unsigned char bnum ); 00684 00685 void clear(); 00686 inline bool isFull() 00687 { 00688 return ( (int)bcnt >= MAXPDULEN ); 00689 } 00690 00691 // ------- from master ------- 00692 ForceCoilsMessage( ModbusMessage& m ); 00693 ForceCoilsMessage& operator=( ModbusMessage& m ); 00694 void init( ModbusMessage& m ); 00695 00697 size_t szData(); 00698 00702 static inline int szHead() 00703 { 00704 // start + quant + count 00705 return sizeof(ModbusData) * 2 + sizeof(ModbusByte); 00706 } 00707 00709 static int getDataLen( ModbusMessage& m ); 00710 00714 bool checkFormat(); 00715 00716 } __attribute__((packed)); 00717 00718 std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m ); 00719 std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m ); 00720 // ----------------------------------------------------------------------- 00722 struct ForceCoilsRetMessage: 00723 public ModbusHeader 00724 { 00725 ModbusData start = { 0 }; 00726 ModbusData quant = { 0 }; 00727 ModbusCRC crc = { 0 }; 00728 00729 // ------- from slave ------- 00730 ForceCoilsRetMessage( ModbusMessage& m ); 00731 ForceCoilsRetMessage& operator=( ModbusMessage& m ); 00732 void init( ModbusMessage& m ); 00733 00734 // ------- to master ------- 00740 ForceCoilsRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 ); 00741 00743 void set( ModbusData start, ModbusData quant ); 00744 00746 ModbusMessage transport_msg(); 00747 00751 inline static int szData() 00752 { 00753 return sizeof(ModbusData) * 2 + sizeof(ModbusCRC); 00754 } 00755 }; 00756 00757 std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m ); 00758 std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m ); 00759 // ----------------------------------------------------------------------- 00760 00762 struct WriteOutputMessage: 00763 public ModbusHeader 00764 { 00765 ModbusData start = { 0 }; 00766 ModbusData quant = { 0 }; 00767 ModbusByte bcnt = { 0 }; 00769 ModbusData data[MAXLENPACKET / sizeof(ModbusData) - sizeof(ModbusData) * 2 - sizeof(ModbusByte)]; 00770 ModbusCRC crc = { 0 }; 00772 // ------- to slave ------- 00773 WriteOutputMessage( ModbusAddr addr, ModbusData start ); 00775 ModbusMessage transport_msg(); 00776 00777 bool addData( ModbusData d ); 00778 void clear(); 00779 inline bool isFull() 00780 { 00781 return ( quant >= MAXDATALEN ); 00782 } 00783 00784 // ------- from master ------- 00785 WriteOutputMessage( ModbusMessage& m ); 00786 WriteOutputMessage& operator=( ModbusMessage& m ); 00787 void init( ModbusMessage& m ); 00788 00790 size_t szData(); 00791 00795 static inline int szHead() 00796 { 00797 // start + quant + count 00798 return sizeof(ModbusData) * 2 + sizeof(ModbusByte); 00799 } 00800 00802 static int getDataLen( ModbusMessage& m ); 00803 00807 bool checkFormat(); 00808 00809 } __attribute__((packed)); 00810 00811 00812 std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m ); 00813 std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m ); 00814 00816 struct WriteOutputRetMessage: 00817 public ModbusHeader 00818 { 00819 ModbusData start = { 0 }; 00820 ModbusData quant = { 0 }; 00822 // ------- from slave ------- 00823 WriteOutputRetMessage( ModbusMessage& m ); 00824 WriteOutputRetMessage& operator=( ModbusMessage& m ); 00825 void init( ModbusMessage& m ); 00826 ModbusCRC crc = { 0 }; 00827 00828 // ------- to master ------- 00834 WriteOutputRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 ); 00835 00837 void set( ModbusData start, ModbusData quant ); 00838 00840 ModbusMessage transport_msg(); 00841 00845 inline static int szData() 00846 { 00847 return sizeof(ModbusData) * 2 + sizeof(ModbusCRC); 00848 } 00849 }; 00850 00851 std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m ); 00852 std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m ); 00853 // ----------------------------------------------------------------------- 00855 struct ForceSingleCoilMessage: 00856 public ModbusHeader 00857 { 00858 ModbusData start = { 0 }; 00859 ModbusData data = { 0 }; 00860 ModbusCRC crc = { 0 }; 00863 inline bool cmd() 00864 { 00865 return (data & 0xFF00); 00866 } 00867 00868 00869 // ------- to slave ------- 00870 ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state ); 00872 ModbusMessage transport_msg(); 00873 00874 // ------- from master ------- 00875 ForceSingleCoilMessage( ModbusMessage& m ); 00876 ForceSingleCoilMessage& operator=( ModbusMessage& m ); 00877 void init( ModbusMessage& m ); 00878 00880 size_t szData(); 00881 00885 static inline int szHead() 00886 { 00887 return sizeof(ModbusData); 00888 } 00889 00893 static int getDataLen( ModbusMessage& m ); 00894 00898 bool checkFormat(); 00899 } __attribute__((packed)); 00900 00901 00902 std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m ); 00903 std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m ); 00904 // ----------------------------------------------------------------------- 00905 00907 struct ForceSingleCoilRetMessage: 00908 public ModbusHeader 00909 { 00910 ModbusData start = { 0 }; 00911 ModbusData data = { 0 }; 00912 ModbusCRC crc = { 0 }; 00913 00915 inline bool cmd() 00916 { 00917 return (data & 0xFF00); 00918 } 00919 00920 // ------- from slave ------- 00921 ForceSingleCoilRetMessage( ModbusMessage& m ); 00922 ForceSingleCoilRetMessage& operator=( ModbusMessage& m ); 00923 void init( ModbusMessage& m ); 00924 00925 // ------- to master ------- 00930 ForceSingleCoilRetMessage( ModbusAddr _from ); 00931 00933 void set( ModbusData start, bool cmd ); 00934 00936 ModbusMessage transport_msg(); 00937 00941 inline static int szData() 00942 { 00943 return 2 * sizeof(ModbusData) + sizeof(ModbusCRC); 00944 } 00945 }; 00946 00947 std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m ); 00948 std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m ); 00949 // ----------------------------------------------------------------------- 00950 00952 struct WriteSingleOutputMessage: 00953 public ModbusHeader 00954 { 00955 ModbusData start = { 0 }; 00956 ModbusData data = { 0 }; 00957 ModbusCRC crc = { 0 }; 00960 // ------- to slave ------- 00961 WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg = 0, ModbusData data = 0 ); 00963 ModbusMessage transport_msg(); 00964 00965 // ------- from master ------- 00966 WriteSingleOutputMessage( ModbusMessage& m ); 00967 WriteSingleOutputMessage& operator=( ModbusMessage& m ); 00968 void init( ModbusMessage& m ); 00969 00971 size_t szData(); 00972 00976 static inline int szHead() 00977 { 00978 return sizeof(ModbusData); 00979 } 00980 00984 static int getDataLen( ModbusMessage& m ); 00985 00989 bool checkFormat(); 00990 } __attribute__((packed)); 00991 00992 00993 std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m ); 00994 std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m ); 00995 // ----------------------------------------------------------------------- 00996 00998 struct WriteSingleOutputRetMessage: 00999 public ModbusHeader 01000 { 01001 ModbusData start = { 0 }; 01002 ModbusData data = { 0 }; 01003 ModbusCRC crc = { 0 }; 01004 01005 01006 // ------- from slave ------- 01007 WriteSingleOutputRetMessage( ModbusMessage& m ); 01008 WriteSingleOutputRetMessage& operator=( ModbusMessage& m ); 01009 void init( ModbusMessage& m ); 01010 01011 // ------- to master ------- 01016 WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start = 0 ); 01017 01019 void set( ModbusData start, ModbusData data ); 01020 01022 ModbusMessage transport_msg(); 01023 01027 inline static int szData() 01028 { 01029 return 2 * sizeof(ModbusData) + sizeof(ModbusCRC); 01030 } 01031 }; 01032 01033 std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m ); 01034 std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m ); 01035 // ----------------------------------------------------------------------- 01037 struct DiagnosticMessage: 01038 public ModbusHeader 01039 { 01040 ModbusData subf = { 0 }; 01041 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 01043 // ------- from slave ------- 01044 DiagnosticMessage( ModbusMessage& m ); 01045 DiagnosticMessage& operator=( ModbusMessage& m ); 01046 void init( ModbusMessage& m ); 01050 static inline int szHead() 01051 { 01052 return sizeof(ModbusData); // subf 01053 } 01054 01056 static int getDataLen( ModbusMessage& m ); 01057 ModbusCRC crc = { 0 }; 01058 01059 // ------- to master ------- 01060 DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d = 0 ); 01061 01066 bool addData( ModbusData d ); 01067 01069 void clear(); 01070 01072 inline bool isFull() 01073 { 01074 // (1)subf + data count 01075 return ( 1 + count >= MAXDATALEN ); 01076 } 01077 01079 size_t szData(); 01080 01082 ModbusMessage transport_msg(); 01083 01084 // Это поле не входит в стандарт modbus 01085 // оно вспомогательное и игнорируется при 01086 // преобразовании в ModbusMessage. 01087 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 01088 // Используйте специальную функцию transport_msg() 01089 int count = { 0 }; 01090 }; 01091 std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m ); 01092 std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m ); 01093 // ----------------------------------------------------------------------- 01095 struct DiagnosticRetMessage: 01096 public DiagnosticMessage 01097 { 01098 DiagnosticRetMessage( ModbusMessage& m ); 01099 DiagnosticRetMessage( DiagnosticMessage& m ); 01100 DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d = 0 ); 01101 }; 01102 01103 std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m ); 01104 std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m ); 01105 // ----------------------------------------------------------------------- 01107 struct MEIMessageRDI: 01108 public ModbusHeader 01109 { 01110 ModbusByte type; 01111 ModbusByte devID; 01112 ModbusByte objID; 01114 ModbusCRC crc = { 0 }; 01116 // ------- to slave ------- 01117 MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID ); 01119 ModbusMessage transport_msg(); 01120 01121 // ------- from master ------- 01122 MEIMessageRDI( ModbusMessage& m ); 01123 MEIMessageRDI& operator=( ModbusMessage& m ); 01124 void init( ModbusMessage& m ); 01125 01129 static inline int szHead() 01130 { 01131 return sizeof(ModbusByte) * 3; 01132 } 01133 01135 static inline int szData() 01136 { 01137 return sizeof(ModbusByte) * 3 + szCRC; 01138 } 01139 01140 // вспомогательные функции 01141 bool checkFormat(); 01142 01143 } __attribute__((packed)); 01144 // ----------------------------------------------------------------------- 01145 std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m ); 01146 std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m ); 01147 // ----------------------------------------------------------------------- 01148 01149 struct RDIObjectInfo 01150 { 01151 RDIObjectInfo(): id(0), val("") {} 01152 RDIObjectInfo( ModbusByte id, const std::string& v ): id(id), val(v) {} 01153 RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len ); 01154 01155 ModbusByte id; 01156 std::string val; 01157 }; 01158 01159 typedef std::list<RDIObjectInfo> RDIObjectList; 01160 01162 struct MEIMessageRetRDI: 01163 public ModbusHeader 01164 { 01165 ModbusByte type; 01166 ModbusByte devID; 01167 ModbusByte conformity; 01168 ModbusByte mf; 01169 ModbusByte objID; 01170 ModbusByte objNum; 01172 RDIObjectList dlist; 01173 ModbusCRC crc = { 0 }; 01174 01175 // ------- from slave ------- 01176 MEIMessageRetRDI(); 01177 MEIMessageRetRDI( ModbusMessage& m ); 01178 MEIMessageRetRDI& operator=( ModbusMessage& m ); 01179 void init( ModbusMessage& m ); 01180 01181 // предварительная инициализации, только заголовочной части, без данных 01182 void pre_init( ModbusMessage& m ); 01183 01185 static inline int szHead() 01186 { 01187 return sizeof(ModbusByte) * 6; 01188 } 01189 01190 // /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */ 01191 // static int getDataLen( ModbusMessage& m ); 01192 01193 // ------- to master ------- 01194 MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID ); 01195 01200 bool addData( ModbusByte id, const std::string& value ); 01201 bool addData( RDIObjectInfo& dat ); 01202 01204 void clear(); 01205 01207 inline bool isFull() 01208 { 01209 return ( bcnt >= MAXPDULEN ); 01210 } 01211 01213 size_t szData(); 01214 01216 ModbusMessage transport_msg(); 01217 01218 int bcnt = { 0 }; 01219 }; 01220 01221 std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m ); 01222 std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m ); 01223 std::ostream& operator<<(std::ostream& os, RDIObjectList& dl ); 01224 std::ostream& operator<<(std::ostream& os, RDIObjectList* dl ); 01225 // ----------------------------------------------------------------------- 01226 // ----------------------------------------------------------------------- 01227 01229 struct JournalCommandMessage: 01230 public ModbusHeader 01231 { 01232 ModbusData cmd = { 0 }; 01233 ModbusData num = { 0 }; 01234 ModbusCRC crc = { 0 }; 01235 01236 // ------------- 01237 JournalCommandMessage( ModbusMessage& m ); 01238 JournalCommandMessage& operator=( ModbusMessage& m ); 01239 01241 inline static int szData() 01242 { 01243 return sizeof(ModbusByte) * 4 + szCRC; 01244 } 01245 01246 } __attribute__((packed)); 01247 01248 std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m ); 01249 std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m ); 01250 // ----------------------------------------------------------------------- 01252 struct JournalCommandRetMessage: 01253 public ModbusHeader 01254 { 01255 ModbusByte bcnt = { 0 }; 01256 // ModbusByte data[MAXLENPACKET-1]; /*!< данные */ 01257 01258 // В связи со спецификой реализации ответной части (т.е. modbus master) 01259 // данные приходится делать не байтовым потоком, а "словами" 01260 // которые в свою очередь будут перевёрнуты при посылке... 01261 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 01263 // ------------- 01264 JournalCommandRetMessage( ModbusAddr _from ); 01265 01272 bool setData( ModbusByte* b, int len ); 01273 01275 void clear(); 01276 01278 inline bool isFull() 01279 { 01280 return ( count >= MAXDATALEN ); 01281 } 01282 01284 size_t szData(); 01285 01287 ModbusMessage transport_msg(); 01288 01289 // Это поле не входит в стандарт modbus 01290 // оно вспомогательное и игнорируется при 01291 // преобразовании в ModbusMessage. 01292 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 01293 // Используйте специальную функцию transport_msg() 01294 size_t count = { 0 }; 01295 }; 01296 01297 std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m ); 01298 std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m ); 01299 // ----------------------------------------------------------------------- 01303 struct JournalCommandRetOK: 01304 public JournalCommandRetMessage 01305 { 01306 // ------------- 01307 JournalCommandRetOK( ModbusAddr _from ); 01308 void set( ModbusData cmd, ModbusData ecode ); 01309 static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode ); 01310 }; 01311 01312 std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m ); 01313 std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m ); 01314 // ----------------------------------------------------------------------- 01315 01317 struct SetDateTimeMessage: 01318 public ModbusHeader 01319 { 01320 ModbusByte hour = { 0 }; 01321 ModbusByte min = { 0 }; 01322 ModbusByte sec = { 0 }; 01323 ModbusByte day = { 1 }; 01324 ModbusByte mon = { 1 }; 01325 ModbusByte year = { 0 }; 01326 ModbusByte century = { 20 }; 01328 ModbusCRC crc = { 0 }; 01329 01330 // ------- to slave ------- 01331 SetDateTimeMessage( ModbusAddr addr ); 01333 ModbusMessage transport_msg(); 01334 01335 // ------- from master ------- 01336 SetDateTimeMessage( ModbusMessage& m ); 01337 SetDateTimeMessage& operator=( ModbusMessage& m ); 01338 SetDateTimeMessage(); 01339 01340 bool checkFormat(); 01341 01343 inline static int szData() 01344 { 01345 return sizeof(ModbusByte) * 7 + szCRC; 01346 } 01347 01348 } __attribute__((packed)); 01349 01350 std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m ); 01351 std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m ); 01352 // ----------------------------------------------------------------------- 01353 01355 struct SetDateTimeRetMessage: 01356 public SetDateTimeMessage 01357 { 01358 01359 // ------- from slave ------- 01360 SetDateTimeRetMessage( ModbusMessage& m ); 01361 SetDateTimeRetMessage& operator=( ModbusMessage& m ); 01362 void init( ModbusMessage& m ); 01363 01364 // ------- to master ------- 01365 SetDateTimeRetMessage( ModbusAddr _from ); 01366 SetDateTimeRetMessage( const SetDateTimeMessage& query ); 01367 static void cpy( SetDateTimeRetMessage& reply, SetDateTimeMessage& query ); 01368 01370 ModbusMessage transport_msg(); 01371 }; 01372 // ----------------------------------------------------------------------- 01373 01375 struct RemoteServiceMessage: 01376 public ModbusHeader 01377 { 01378 ModbusByte bcnt = { 0 }; 01381 ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)]; 01382 ModbusCRC crc = { 0 }; 01384 // ----------- 01385 RemoteServiceMessage( ModbusMessage& m ); 01386 RemoteServiceMessage& operator=( ModbusMessage& m ); 01387 void init( ModbusMessage& m ); 01388 01390 size_t szData(); 01391 01395 static inline int szHead() 01396 { 01397 return sizeof(ModbusByte); // bcnt 01398 } 01399 01401 static int getDataLen( ModbusMessage& m ); 01402 01403 } __attribute__((packed)); 01404 01405 std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m ); 01406 std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m ); 01407 // ----------------------------------------------------------------------- 01408 struct RemoteServiceRetMessage: 01409 public ModbusHeader 01410 { 01411 ModbusByte bcnt = { 0 }; 01413 ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)]; 01414 01415 RemoteServiceRetMessage( ModbusAddr _from ); 01416 01423 bool setData( ModbusByte* b, int len ); 01424 01426 void clear(); 01427 01429 inline bool isFull() 01430 { 01431 return ( count >= sizeof(data) ); 01432 } 01433 01435 size_t szData(); 01436 01438 ModbusMessage transport_msg(); 01439 01440 // Это поле не входит в стандарт modbus 01441 // оно вспомогательное и игнорируется при 01442 // преобразовании в ModbusMessage. 01443 size_t count = { 0 }; 01444 }; 01445 // ----------------------------------------------------------------------- 01446 01447 struct ReadFileRecordMessage: 01448 public ModbusHeader 01449 { 01450 struct SubRequest 01451 { 01452 ModbusByte reftype; 01453 ModbusData numfile; 01454 ModbusData numrec; 01455 ModbusData reglen; 01456 } __attribute__((packed)); 01457 01458 ModbusByte bcnt = { 0 }; 01461 SubRequest data[MAXLENPACKET / sizeof(SubRequest) - sizeof(ModbusByte)]; 01462 ModbusCRC crc = { 0 }; 01464 // ----------- 01465 ReadFileRecordMessage( ModbusMessage& m ); 01466 ReadFileRecordMessage& operator=( ModbusMessage& m ); 01467 void init( ModbusMessage& m ); 01468 01470 size_t szData(); 01471 01475 static inline int szHead() 01476 { 01477 return sizeof(ModbusByte); // bcnt 01478 } 01479 01481 static int getDataLen( ModbusMessage& m ); 01482 01484 bool checkFormat(); 01485 01486 // это поле служебное и не используется в релальном обмене 01487 size_t count = { 0 }; 01488 }; 01489 01490 std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m ); 01491 std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m ); 01492 // ----------------------------------------------------------------------- 01493 01494 struct FileTransferMessage: 01495 public ModbusHeader 01496 { 01497 ModbusData numfile = { 0 }; 01498 ModbusData numpacket = { 0 }; 01499 ModbusCRC crc = { 0 }; 01501 // ------- to slave ------- 01502 FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket ); 01503 ModbusMessage transport_msg(); 01505 // ------- from master ------- 01506 FileTransferMessage( ModbusMessage& m ); 01507 FileTransferMessage& operator=( ModbusMessage& m ); 01508 void init( ModbusMessage& m ); 01509 01511 static inline int szData() 01512 { 01513 return sizeof(ModbusData) * 2 + szCRC; 01514 } 01515 01516 } __attribute__((packed)); 01517 01518 std::ostream& operator<<(std::ostream& os, FileTransferMessage& m ); 01519 std::ostream& operator<<(std::ostream& os, FileTransferMessage* m ); 01520 // ----------------------------------------------------------------------- 01521 01522 struct FileTransferRetMessage: 01523 public ModbusHeader 01524 { 01525 // 255 - max of bcnt...(1 byte) 01526 // static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2; 01527 static const int MaxDataLen = MAXLENPACKET - sizeof(ModbusData) * 3 - sizeof(ModbusByte) * 2; 01528 01529 ModbusByte bcnt; 01530 ModbusData numfile; 01531 ModbusData numpacks; 01532 ModbusData packet; 01533 ModbusByte dlen; 01534 ModbusByte data[MaxDataLen]; 01535 01536 01537 // ------- from slave ------- 01538 FileTransferRetMessage( ModbusMessage& m ); 01539 FileTransferRetMessage& operator=( ModbusMessage& m ); 01540 void init( ModbusMessage& m ); 01541 ModbusCRC crc = { 0 }; 01542 static int szHead() 01543 { 01544 return sizeof(ModbusByte); 01545 } 01546 static int getDataLen( ModbusMessage& m ); 01547 01548 // ------- to master ------- 01549 FileTransferRetMessage( ModbusAddr _from ); 01550 01554 bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len ); 01555 01557 void clear(); 01558 01560 size_t szData(); 01561 01563 ModbusMessage transport_msg(); 01564 }; 01565 01566 std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m ); 01567 std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m ); 01568 // ----------------------------------------------------------------------- 01569 } // end of ModbusRTU namespace 01570 // --------------------------------------------------------------------------- 01571 namespace ModbusTCP 01572 { 01573 struct MBAPHeader 01574 { 01575 ModbusRTU::ModbusData tID; 01576 ModbusRTU::ModbusData pID; 01577 ModbusRTU::ModbusData len; 01578 /* ModbusRTU::ModbusByte uID; */ /* <------- see ModbusHeader */ 01579 01580 MBAPHeader(): tID(0), pID(0), len(0) /*,uID(0) */ {} 01581 01582 void swapdata(); 01583 01584 } __attribute__((packed)); 01585 01586 std::ostream& operator<<(std::ostream& os, MBAPHeader& m ); 01587 01588 // ----------------------------------------------------------------------- 01589 } // end of namespace ModbusTCP 01590 // --------------------------------------------------------------------------- 01591 #endif // ModbusTypes_H_ 01592 // ---------------------------------------------------------------------------
1.7.6.1