|
UniSet
2.6.0
|
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 uniset 00022 { 00023 // ------------------------------------------------------------------------- 00024 namespace ModbusRTU 00025 { 00026 // Базовые типы 00027 typedef uint8_t ModbusByte; 00028 const size_t BitsPerByte = 8; 00029 typedef uint8_t ModbusAddr; 00030 typedef uint16_t ModbusData; 00031 const size_t BitsPerData = 16; 00032 typedef uint16_t ModbusCRC; 00034 // --------------------------------------------------------------------- 00036 enum SlaveFunctionCode 00037 { 00038 fnUnknown = 0x00, 00039 fnReadCoilStatus = 0x01, 00040 fnReadInputStatus = 0x02, 00041 fnReadOutputRegisters = 0x03, 00042 fnReadInputRegisters = 0x04, 00043 fnForceSingleCoil = 0x05, 00044 fnWriteOutputSingleRegister = 0x06, 00045 fnDiagnostics = 0x08, 00046 fnForceMultipleCoils = 0x0F, 00047 fnWriteOutputRegisters = 0x10, 00048 fnReadFileRecord = 0x14, 00049 fnWriteFileRecord = 0x15, 00050 fnMEI = 0x2B, 00051 fnSetDateTime = 0x50, 00052 fnRemoteService = 0x53, 00053 fnJournalCommand = 0x65, 00054 fnFileTransfer = 0x66 00055 }; 00056 00058 enum DiagnosticsSubFunction 00059 { 00060 subEcho = 0x00, 00061 dgRestartComm = 0x01, 00062 dgDiagReg = 0x02, 00063 dgChangeASCII = 0x03, 00064 dgForceListen = 0x04, 00065 // 05.. 09 RESERVED 00066 dgClearCounters = 0x0A, 00067 dgBusMsgCount = 0x0B, 00068 dgBusErrCount = 0x0C, 00069 dgBusExceptCount = 0x0D, 00070 dgMsgSlaveCount = 0x0E, 00071 dgNoNoResponseCount = 0x0F, 00072 dgSlaveNAKCount = 0x10, 00073 dgSlaveBusyCount = 0x11, 00074 dgBusCharOverrunCount = 0x12, 00075 // = 0x13, /*!< RESERVED */ 00076 dgClearOverrunCounter = 0x14 00077 // 21 ...65535 RESERVED 00078 }; 00079 00080 00081 typedef unsigned long RegID; 00082 00089 RegID genRegID( const ModbusRTU::ModbusData r, const int fn ); 00090 00091 // определение размера данных в зависимости от типа сообщения 00092 // возвращает -1 - если динамический размер сообщения или размер неизвестен 00093 ssize_t szRequestDiagnosticData( DiagnosticsSubFunction f ); 00094 00096 enum RDIObjectID 00097 { 00098 rdiVendorName = 0x0, 00099 rdiProductCode = 0x1, 00100 rdiMajorMinorRevision = 0x2, 00101 rdiVendorURL = 0x3, 00102 rdiProductName = 0x4, 00103 rdiModelName = 0x5, 00104 rdiUserApplicationName = 0x6 00105 // 0x07 .. 0x7F - reserved 00106 // 0x80 .. 0xFF - optionaly defined (product dependant) 00107 }; 00108 00110 enum RDIRequestDeviceID 00111 { 00112 rdevMinNum = 0, 00113 rdevBasicDevice = 0x1, // request to get the basic device identification (stream access) 00114 rdevRegularDevice = 0x2, // request to get the regular device identification (stream access) 00115 rdevExtentedDevice = 0x3, // request to get the extended device identification (stream access) 00116 rdevSpecificDevice = 0x4, // request to get the extended device identification (stream access) 00117 rdevMaxNum = 0x5 00118 }; 00119 00120 std::string rdi2str( int id ); 00121 // ----------------------------------------------------------------------- 00122 00124 enum 00125 { 00127 MAXLENPACKET = 508, 00128 BroadcastAddr = 255, 00129 MAXPDULEN = 253, // 255 - 2(CRC) 00130 MAXDATALEN = 125 00134 }; 00135 00136 const unsigned char MBErrMask = 0x80; 00137 // --------------------------------------------------------------------- 00138 uint16_t SWAPSHORT( uint16_t x ); 00139 // --------------------------------------------------------------------- 00141 ModbusCRC checkCRC( ModbusByte* start, size_t len ); 00142 const size_t szCRC = sizeof(ModbusCRC); 00143 // --------------------------------------------------------------------- 00145 std::ostream& mbPrintMessage(std::ostream& os, ModbusByte* b, size_t len ); 00146 // ------------------------------------------------------------------------- 00147 ModbusAddr str2mbAddr( const std::string& val ); 00148 ModbusData str2mbData( const std::string& val ); 00149 std::string dat2str( const ModbusData dat ); 00150 std::string addr2str( const ModbusAddr addr ); 00151 std::string b2str( const ModbusByte b ); 00152 // ------------------------------------------------------------------------- 00153 float dat2f( const ModbusData dat1, const ModbusData dat2 ); 00154 // ------------------------------------------------------------------------- 00155 bool isWriteFunction( SlaveFunctionCode c ); 00156 bool isReadFunction( SlaveFunctionCode c ); 00157 // ------------------------------------------------------------------------- 00159 struct ModbusHeader 00160 { 00161 ModbusAddr addr; 00162 ModbusByte func; 00164 ModbusHeader(): addr(0), func(0) {} 00165 } __attribute__((packed)); 00166 00167 const size_t szModbusHeader = sizeof(ModbusHeader); 00168 00169 std::ostream& operator<<(std::ostream& os, const ModbusHeader& m ); 00170 std::ostream& operator<<(std::ostream& os, const ModbusHeader* m ); 00171 // ----------------------------------------------------------------------- 00172 struct ADUHeader 00173 { 00174 ModbusRTU::ModbusData tID; 00175 ModbusRTU::ModbusData pID; 00176 ModbusRTU::ModbusData len; 00178 ADUHeader(): tID(0), pID(0), len(0) {} 00179 00180 void swapdata(); 00181 00182 } __attribute__((packed)); 00183 00184 std::ostream& operator<<(std::ostream& os, const ADUHeader& m ); 00185 // ----------------------------------------------------------------------- 00186 00190 struct ModbusMessage 00191 { 00192 ModbusMessage(); 00193 00194 ModbusMessage( ModbusMessage&& ) = default; 00195 ModbusMessage& operator=(ModbusMessage&& ) = default; 00196 ModbusMessage( const ModbusMessage& ) = default; 00197 ModbusMessage& operator=(const ModbusMessage& ) = default; 00198 00199 inline ModbusByte func() const 00200 { 00201 return pduhead.func; 00202 } 00203 inline ModbusAddr addr() const 00204 { 00205 return pduhead.addr; 00206 } 00207 inline ModbusRTU::ModbusData tID() const 00208 { 00209 return aduhead.tID; 00210 } 00211 inline ModbusRTU::ModbusData pID() const 00212 { 00213 return aduhead.pID; 00214 } 00215 inline ModbusRTU::ModbusData aduLen() const 00216 { 00217 return aduhead.len; 00218 } 00219 00220 unsigned char* buf(); 00221 ModbusRTU::ModbusData len() const; 00222 void swapHead(); 00223 void makeHead( ModbusRTU::ModbusData tID, bool noCRC = true, ModbusRTU::ModbusData pID = 0 ); 00224 00225 ModbusRTU::ModbusData pduLen() const; 00226 ModbusCRC pduCRC( size_t len ) const; 00227 static size_t maxSizeOfMessage(); 00228 00229 void clear(); 00230 00231 ADUHeader aduhead; 00232 ModbusHeader pduhead; 00233 ModbusByte data[MAXLENPACKET + szCRC]; 00235 // Это поле вспомогательное и игнорируется при пересылке 00236 size_t dlen = { 0 }; 00237 } __attribute__((packed)); 00238 00239 std::ostream& operator<<(std::ostream& os, const ModbusMessage& m ); 00240 std::ostream& operator<<(std::ostream& os, const ModbusMessage* m ); 00241 // ----------------------------------------------------------------------- 00243 struct ErrorRetMessage: 00244 public ModbusHeader 00245 { 00246 ModbusByte ecode = { erNoError }; 00247 ModbusCRC crc = { 0 }; 00248 00249 // ------- from slave ------- 00250 ErrorRetMessage( const ModbusMessage& m ); 00251 ErrorRetMessage& operator=( const ModbusMessage& m ); 00252 void init( const ModbusMessage& m ); 00253 00254 // ------- to master ------- 00255 ErrorRetMessage( ModbusAddr _from, ModbusByte _func, ModbusByte ecode ); 00256 00258 ModbusMessage transport_msg(); 00259 00263 inline static size_t szData() 00264 { 00265 return sizeof(ModbusByte) + szCRC; 00266 } 00267 }; 00268 00269 std::ostream& operator<<(std::ostream& os, ErrorRetMessage& m ); 00270 std::ostream& operator<<(std::ostream& os, ErrorRetMessage* m ); 00271 // ----------------------------------------------------------------------- 00272 struct DataBits 00273 { 00274 DataBits( ModbusByte b ); 00275 DataBits( std::string s ); // example "10001111" 00276 DataBits(); 00277 00278 const DataBits& operator=(const ModbusByte& r); 00279 00280 operator ModbusByte(); 00281 ModbusByte mbyte(); 00282 00283 bool operator[]( const size_t i ) 00284 { 00285 return b[i]; 00286 } 00287 void set( int n, bool s ) 00288 { 00289 b.set(n, s); 00290 } 00291 00292 std::bitset<BitsPerByte> b; 00293 }; 00294 00295 std::ostream& operator<<(std::ostream& os, DataBits& m ); 00296 std::ostream& operator<<(std::ostream& os, DataBits* m ); 00297 // ----------------------------------------------------------------------- 00298 struct DataBits16 00299 { 00300 DataBits16( ModbusData d ); 00301 DataBits16( const std::string& s ); // example "1000111110001111" 00302 DataBits16(); 00303 00304 const DataBits16& operator=(const ModbusData& r); 00305 00306 operator ModbusData(); 00307 ModbusData mdata() const; 00308 00309 bool operator[]( const size_t i ) 00310 { 00311 return b[i]; 00312 } 00313 void set( int n, bool s ) 00314 { 00315 b.set(n, s); 00316 } 00317 00318 std::bitset<BitsPerData> b; 00319 }; 00320 00321 std::ostream& operator<<(std::ostream& os, DataBits16& m ); 00322 std::ostream& operator<<(std::ostream& os, DataBits16* m ); 00323 // ----------------------------------------------------------------------- 00325 struct ReadCoilMessage: 00326 public ModbusHeader 00327 { 00328 ModbusData start = { 0 }; 00329 ModbusData count = { 0 }; 00330 ModbusCRC crc = { 0 }; 00331 00332 // ------- to slave ------- 00333 ReadCoilMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00335 ModbusMessage transport_msg(); 00336 00337 // ------- from master ------- 00338 ReadCoilMessage( const ModbusMessage& m ); 00339 ReadCoilMessage& operator=( const ModbusMessage& m ); 00340 void init( const ModbusMessage& m ); 00341 00343 inline static size_t szData() 00344 { 00345 return sizeof(ModbusData) * 2 + szCRC; 00346 } 00347 00348 } __attribute__((packed)); 00349 00350 std::ostream& operator<<(std::ostream& os, ReadCoilMessage& m ); 00351 std::ostream& operator<<(std::ostream& os, ReadCoilMessage* m ); 00352 00353 // ----------------------------------------------------------------------- 00354 00356 struct ReadCoilRetMessage: 00357 public ModbusHeader 00358 { 00359 ModbusByte bcnt = { 0 }; 00360 ModbusByte data[MAXLENPACKET]; 00362 // ------- from slave ------- 00363 ReadCoilRetMessage( const ModbusMessage& m ); 00364 ReadCoilRetMessage& operator=( const ModbusMessage& m ); 00365 void init( const ModbusMessage& m ); 00366 00370 static inline int szHead() 00371 { 00372 return sizeof(ModbusByte); // bcnt 00373 } 00374 00376 static size_t getDataLen( const ModbusMessage& m ); 00377 ModbusCRC crc = { 0 }; 00378 00379 // ------- to master ------- 00380 ReadCoilRetMessage( ModbusAddr _from ); 00381 00386 bool addData( DataBits d ); 00387 00395 bool setBit( unsigned char dnum, unsigned char bnum, bool state ); 00396 00403 bool getData( unsigned char bnum, DataBits& d ) const; 00404 00406 void clear(); 00407 00409 inline bool isFull() const 00410 { 00411 return ( (int)bcnt >= MAXPDULEN ); 00412 } 00413 00415 size_t szData() const; 00416 00418 ModbusMessage transport_msg(); 00419 }; 00420 00421 std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage& m ); 00422 std::ostream& operator<<(std::ostream& os, ReadCoilRetMessage* m ); 00423 // ----------------------------------------------------------------------- 00425 struct ReadInputStatusMessage: 00426 public ModbusHeader 00427 { 00428 ModbusData start = { 0 }; 00429 ModbusData count = { 0 }; 00430 ModbusCRC crc = { 0 }; 00431 00432 // ------- to slave ------- 00433 ReadInputStatusMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00434 00436 ModbusMessage transport_msg(); 00437 00438 // ------- from master ------- 00439 ReadInputStatusMessage( const ModbusMessage& m ); 00440 ReadInputStatusMessage& operator=( const ModbusMessage& m ); 00441 00442 void init( const ModbusMessage& m ); 00443 00445 inline static size_t szData() 00446 { 00447 return sizeof(ModbusData) * 2 + szCRC; 00448 } 00449 00450 } __attribute__((packed)); 00451 00452 std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage& m ); 00453 std::ostream& operator<<(std::ostream& os, ReadInputStatusMessage* m ); 00454 // ----------------------------------------------------------------------- 00456 struct ReadInputStatusRetMessage: 00457 public ModbusHeader 00458 { 00459 ModbusByte bcnt = { 0 }; 00460 ModbusByte data[MAXLENPACKET]; 00462 // ------- from slave ------- 00463 ReadInputStatusRetMessage( const ModbusMessage& m ); 00464 ReadInputStatusRetMessage& operator=( const ModbusMessage& m ); 00465 void init( const ModbusMessage& m ); 00466 00470 static inline size_t szHead() 00471 { 00472 return sizeof(ModbusByte); // bcnt 00473 } 00474 00476 static size_t getDataLen( const ModbusMessage& m ); 00477 ModbusCRC crc = { 0 }; 00478 00479 // ------- to master ------- 00480 ReadInputStatusRetMessage( ModbusAddr _from ); 00481 00486 bool addData( DataBits d ); 00487 00495 bool setBit( unsigned char dnum, unsigned char bnum, bool state ); 00496 00503 bool getData( unsigned char dnum, DataBits& d ) const; 00504 00506 void clear(); 00507 00509 inline bool isFull() const 00510 { 00511 return ( (int)bcnt >= MAXPDULEN ); 00512 } 00513 00515 size_t szData() const; 00516 00518 ModbusMessage transport_msg(); 00519 }; 00520 00521 std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage& m ); 00522 std::ostream& operator<<(std::ostream& os, ReadInputStatusRetMessage* m ); 00523 // ----------------------------------------------------------------------- 00524 00526 struct ReadOutputMessage: 00527 public ModbusHeader 00528 { 00529 ModbusData start = { 0 }; 00530 ModbusData count = { 0 }; 00531 ModbusCRC crc = { 0 }; 00532 00533 // ------- to slave ------- 00534 ReadOutputMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00536 ModbusMessage transport_msg(); 00537 00538 // ------- from master ------- 00539 ReadOutputMessage( const ModbusMessage& m ); 00540 ReadOutputMessage& operator=( const ModbusMessage& m ); 00541 void init( const ModbusMessage& m ); 00542 00544 inline static size_t szData() 00545 { 00546 return sizeof(ModbusData) * 2 + szCRC; 00547 } 00548 00549 } __attribute__((packed)); 00550 00551 std::ostream& operator<<(std::ostream& os, ReadOutputMessage& m ); 00552 std::ostream& operator<<(std::ostream& os, ReadOutputMessage* m ); 00553 // ----------------------------------------------------------------------- 00555 struct ReadOutputRetMessage: 00556 public ModbusHeader 00557 { 00558 ModbusByte bcnt = { 0 }; 00559 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 00561 // ------- from slave ------- 00562 ReadOutputRetMessage( const ModbusMessage& m ); 00563 ReadOutputRetMessage& operator=( const ModbusMessage& m ); 00564 void init( const ModbusMessage& m ); 00568 static inline size_t szHead() 00569 { 00570 // bcnt 00571 return sizeof(ModbusByte); 00572 } 00573 00575 static size_t getDataLen( const ModbusMessage& m ); 00576 ModbusCRC crc = { 0 }; 00577 00578 // ------- to master ------- 00579 ReadOutputRetMessage( ModbusAddr _from ); 00580 00585 bool addData( ModbusData d ); 00586 00588 void clear(); 00589 00591 inline bool isFull() const 00592 { 00593 return ( count * sizeof(ModbusData) >= MAXLENPACKET ); 00594 } 00595 00597 size_t szData() const; 00598 00600 ModbusMessage transport_msg(); 00601 00602 // Это поле не входит в стандарт modbus 00603 // оно вспомогательное и игнорируется при 00604 // преобразовании в ModbusMessage. 00605 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 00606 // Используйте специальную функцию transport_msg() 00607 size_t count = { 0 }; 00608 }; 00609 00610 std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage& m ); 00611 std::ostream& operator<<(std::ostream& os, ReadOutputRetMessage* m ); 00612 // ----------------------------------------------------------------------- 00614 struct ReadInputMessage: 00615 public ModbusHeader 00616 { 00617 ModbusData start = { 0 }; 00618 ModbusData count = { 0 }; 00619 ModbusCRC crc = { 0 }; 00620 00621 // ------- to slave ------- 00622 ReadInputMessage( ModbusAddr addr, ModbusData start, ModbusData count ); 00624 ModbusMessage transport_msg(); 00625 00626 // ------- from master ------- 00627 ReadInputMessage( const ModbusMessage& m ); 00628 ReadInputMessage& operator=( const ModbusMessage& m ); 00629 void init( const ModbusMessage& m ); 00630 00632 inline static size_t szData() 00633 { 00634 return sizeof(ModbusData) * 2 + szCRC; 00635 } 00636 00637 } __attribute__((packed)); 00638 00639 std::ostream& operator<<(std::ostream& os, ReadInputMessage& m ); 00640 std::ostream& operator<<(std::ostream& os, ReadInputMessage* m ); 00641 // ----------------------------------------------------------------------- 00642 00644 struct ReadInputRetMessage: 00645 public ModbusHeader 00646 { 00647 ModbusByte bcnt = { 0 }; 00648 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 00650 // ------- from slave ------- 00651 ReadInputRetMessage( const ModbusMessage& m ); 00652 ReadInputRetMessage& operator=( const ModbusMessage& m ); 00653 void init( const ModbusMessage& m ); 00657 static inline size_t szHead() 00658 { 00659 // bcnt 00660 return sizeof(ModbusByte); 00661 } 00662 00664 static size_t getDataLen( const ModbusMessage& m ); 00665 ModbusCRC crc = { 0 }; 00666 00667 // ------- to master ------- 00668 ReadInputRetMessage( ModbusAddr _from ); 00669 00674 bool addData( ModbusData d ); 00675 00677 void clear(); 00678 00680 inline bool isFull() const 00681 { 00682 return ( count * sizeof(ModbusData) >= MAXLENPACKET ); 00683 } 00684 00685 void swapData(); 00686 00688 size_t szData(); 00689 00691 ModbusMessage transport_msg(); 00692 00693 // Это поле не входит в стандарт modbus 00694 // оно вспомогательное и игнорируется при 00695 // преобразовании в ModbusMessage. 00696 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 00697 // Используйте специальную функцию transport_msg() 00698 size_t count = { 0 }; 00699 }; 00700 00701 std::ostream& operator<<(std::ostream& os, ReadInputRetMessage& m ); 00702 std::ostream& operator<<(std::ostream& os, ReadInputRetMessage* m ); 00703 // ----------------------------------------------------------------------- 00705 struct ForceCoilsMessage: 00706 public ModbusHeader 00707 { 00708 ModbusData start = { 0 }; 00709 ModbusData quant = { 0 }; 00710 ModbusByte bcnt = { 0 }; 00712 ModbusByte data[MAXLENPACKET - sizeof(ModbusData) * 2 - sizeof(ModbusByte)]; 00713 ModbusCRC crc = { 0 }; 00715 // ------- to slave ------- 00716 ForceCoilsMessage( ModbusAddr addr, ModbusData start ); 00718 ModbusMessage transport_msg(); 00719 00724 bool addData( DataBits d ); 00725 00726 // return number of bit 00727 // -1 - error 00728 int addBit( bool state ); 00729 00730 bool setBit( int nbit, bool state ); 00731 00732 inline size_t last() const 00733 { 00734 return quant; 00735 } 00736 00743 bool getData( unsigned char dnum, DataBits& d ); 00744 00745 bool getBit( unsigned char bnum ); 00746 00747 void clear(); 00748 inline bool isFull() const 00749 { 00750 return ( (int)bcnt >= MAXPDULEN ); 00751 } 00752 00753 // ------- from master ------- 00754 ForceCoilsMessage( const ModbusMessage& m ); 00755 ForceCoilsMessage& operator=( const ModbusMessage& m ); 00756 void init( const ModbusMessage& m ); 00757 00759 size_t szData() const; 00760 00764 static inline size_t szHead() 00765 { 00766 // start + quant + count 00767 return sizeof(ModbusData) * 2 + sizeof(ModbusByte); 00768 } 00769 00771 static size_t getDataLen( const ModbusMessage& m ); 00772 00776 bool checkFormat() const; 00777 00778 } __attribute__((packed)); 00779 00780 std::ostream& operator<<(std::ostream& os, ForceCoilsMessage& m ); 00781 std::ostream& operator<<(std::ostream& os, ForceCoilsMessage* m ); 00782 // ----------------------------------------------------------------------- 00784 struct ForceCoilsRetMessage: 00785 public ModbusHeader 00786 { 00787 ModbusData start = { 0 }; 00788 ModbusData quant = { 0 }; 00789 ModbusCRC crc = { 0 }; 00790 00791 // ------- from slave ------- 00792 ForceCoilsRetMessage( const ModbusMessage& m ); 00793 ForceCoilsRetMessage& operator=( const ModbusMessage& m ); 00794 void init( const ModbusMessage& m ); 00795 00796 // ------- to master ------- 00802 ForceCoilsRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 ); 00803 00805 void set( ModbusData start, ModbusData quant ); 00806 00808 ModbusMessage transport_msg(); 00809 00813 inline static size_t szData() 00814 { 00815 return sizeof(ModbusData) * 2 + sizeof(ModbusCRC); 00816 } 00817 }; 00818 00819 std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage& m ); 00820 std::ostream& operator<<(std::ostream& os, ForceCoilsRetMessage* m ); 00821 // ----------------------------------------------------------------------- 00822 00824 struct WriteOutputMessage: 00825 public ModbusHeader 00826 { 00827 ModbusData start = { 0 }; 00828 ModbusData quant = { 0 }; 00829 ModbusByte bcnt = { 0 }; 00831 ModbusData data[MAXLENPACKET / sizeof(ModbusData) - sizeof(ModbusData) * 2 - sizeof(ModbusByte)]; 00832 ModbusCRC crc = { 0 }; 00834 // ------- to slave ------- 00835 WriteOutputMessage( ModbusAddr addr, ModbusData start ); 00837 ModbusMessage transport_msg(); 00838 00839 bool addData( ModbusData d ); 00840 void clear(); 00841 inline bool isFull() const 00842 { 00843 return ( quant >= MAXDATALEN ); 00844 } 00845 00846 // ------- from master ------- 00847 WriteOutputMessage( const ModbusMessage& m ); 00848 WriteOutputMessage& operator=( const ModbusMessage& m ); 00849 void init( const ModbusMessage& m ); 00850 00852 size_t szData() const; 00853 00857 static inline size_t szHead() 00858 { 00859 // start + quant + count 00860 return sizeof(ModbusData) * 2 + sizeof(ModbusByte); 00861 } 00862 00864 static size_t getDataLen( const ModbusMessage& m ); 00865 00869 bool checkFormat() const; 00870 00871 } __attribute__((packed)); 00872 00873 00874 std::ostream& operator<<(std::ostream& os, WriteOutputMessage& m ); 00875 std::ostream& operator<<(std::ostream& os, WriteOutputMessage* m ); 00876 00878 struct WriteOutputRetMessage: 00879 public ModbusHeader 00880 { 00881 ModbusData start = { 0 }; 00882 ModbusData quant = { 0 }; 00884 // ------- from slave ------- 00885 WriteOutputRetMessage( const ModbusMessage& m ); 00886 WriteOutputRetMessage& operator=( const ModbusMessage& m ); 00887 void init( const ModbusMessage& m ); 00888 ModbusCRC crc = { 0 }; 00889 00890 // ------- to master ------- 00896 WriteOutputRetMessage( ModbusAddr _from, ModbusData start = 0, ModbusData quant = 0 ); 00897 00899 void set( ModbusData start, ModbusData quant ); 00900 00902 ModbusMessage transport_msg(); 00903 00907 inline static size_t szData() 00908 { 00909 return sizeof(ModbusData) * 2 + sizeof(ModbusCRC); 00910 } 00911 }; 00912 00913 std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage& m ); 00914 std::ostream& operator<<(std::ostream& os, WriteOutputRetMessage* m ); 00915 // ----------------------------------------------------------------------- 00917 struct ForceSingleCoilMessage: 00918 public ModbusHeader 00919 { 00920 ModbusData start = { 0 }; 00921 ModbusData data = { 0 }; 00922 ModbusCRC crc = { 0 }; 00925 inline bool cmd() 00926 { 00927 return (data & 0xFF00); 00928 } 00929 00930 // ------- to slave ------- 00931 ForceSingleCoilMessage( ModbusAddr addr, ModbusData reg, bool state ); 00933 ModbusMessage transport_msg(); 00934 00935 // ------- from master ------- 00936 ForceSingleCoilMessage( const ModbusMessage& m ); 00937 ForceSingleCoilMessage& operator=( const ModbusMessage& m ); 00938 void init( const ModbusMessage& m ); 00939 00941 size_t szData() const; 00942 00946 static inline size_t szHead() 00947 { 00948 return sizeof(ModbusData); 00949 } 00950 00954 static size_t getDataLen( const ModbusMessage& m ); 00955 00959 bool checkFormat() const; 00960 } __attribute__((packed)); 00961 00962 00963 std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage& m ); 00964 std::ostream& operator<<(std::ostream& os, ForceSingleCoilMessage* m ); 00965 // ----------------------------------------------------------------------- 00966 00968 struct ForceSingleCoilRetMessage: 00969 public ModbusHeader 00970 { 00971 ModbusData start = { 0 }; 00972 ModbusData data = { 0 }; 00973 ModbusCRC crc = { 0 }; 00974 00976 inline bool cmd() const 00977 { 00978 return (data & 0xFF00); 00979 } 00980 00981 // ------- from slave ------- 00982 ForceSingleCoilRetMessage( const ModbusMessage& m ); 00983 ForceSingleCoilRetMessage& operator=( const ModbusMessage& m ); 00984 void init( const ModbusMessage& m ); 00985 00986 // ------- to master ------- 00991 ForceSingleCoilRetMessage( ModbusAddr _from ); 00992 00994 void set( ModbusData start, bool cmd ); 00995 00997 ModbusMessage transport_msg(); 00998 01002 inline static size_t szData() 01003 { 01004 return 2 * sizeof(ModbusData) + sizeof(ModbusCRC); 01005 } 01006 }; 01007 01008 std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage& m ); 01009 std::ostream& operator<<(std::ostream& os, ForceSingleCoilRetMessage* m ); 01010 // ----------------------------------------------------------------------- 01011 01013 struct WriteSingleOutputMessage: 01014 public ModbusHeader 01015 { 01016 ModbusData start = { 0 }; 01017 ModbusData data = { 0 }; 01018 ModbusCRC crc = { 0 }; 01021 // ------- to slave ------- 01022 WriteSingleOutputMessage( ModbusAddr addr, ModbusData reg = 0, ModbusData data = 0 ); 01024 ModbusMessage transport_msg(); 01025 01026 // ------- from master ------- 01027 WriteSingleOutputMessage( const ModbusMessage& m ); 01028 WriteSingleOutputMessage& operator=( const ModbusMessage& m ); 01029 void init( const ModbusMessage& m ); 01030 01032 size_t szData() const; 01033 01037 static inline size_t szHead() 01038 { 01039 return sizeof(ModbusData); 01040 } 01041 01045 static size_t getDataLen( const ModbusMessage& m ); 01046 01050 bool checkFormat(); 01051 } __attribute__((packed)); 01052 01053 01054 std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage& m ); 01055 std::ostream& operator<<(std::ostream& os, WriteSingleOutputMessage* m ); 01056 // ----------------------------------------------------------------------- 01057 01059 struct WriteSingleOutputRetMessage: 01060 public ModbusHeader 01061 { 01062 ModbusData start = { 0 }; 01063 ModbusData data = { 0 }; 01064 ModbusCRC crc = { 0 }; 01065 01066 01067 // ------- from slave ------- 01068 WriteSingleOutputRetMessage( const ModbusMessage& m ); 01069 WriteSingleOutputRetMessage& operator=( const ModbusMessage& m ); 01070 void init( const ModbusMessage& m ); 01071 01072 // ------- to master ------- 01077 WriteSingleOutputRetMessage( ModbusAddr _from, ModbusData start = 0 ); 01078 01080 void set( ModbusData start, ModbusData data ); 01081 01083 ModbusMessage transport_msg(); 01084 01088 inline static size_t szData() 01089 { 01090 return 2 * sizeof(ModbusData) + sizeof(ModbusCRC); 01091 } 01092 }; 01093 01094 std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage& m ); 01095 std::ostream& operator<<(std::ostream& os, WriteSingleOutputRetMessage* m ); 01096 // ----------------------------------------------------------------------- 01098 struct DiagnosticMessage: 01099 public ModbusHeader 01100 { 01101 ModbusData subf = { 0 }; 01102 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 01104 // ------- from slave ------- 01105 DiagnosticMessage( const ModbusMessage& m ); 01106 DiagnosticMessage& operator=( const ModbusMessage& m ); 01107 void init( const ModbusMessage& m ); 01111 static inline size_t szHead() 01112 { 01113 return sizeof(ModbusData); // subf 01114 } 01115 01117 static size_t getDataLen( const ModbusMessage& m ); 01118 ModbusCRC crc = { 0 }; 01119 01120 // ------- to master ------- 01121 DiagnosticMessage( ModbusAddr _from, DiagnosticsSubFunction subf, ModbusData d = 0 ); 01122 01127 bool addData( ModbusData d ); 01128 01130 void clear(); 01131 01133 inline bool isFull() const 01134 { 01135 // (1)subf + data count 01136 return ( 1 + count >= MAXDATALEN ); 01137 } 01138 01140 size_t szData() const; 01141 01143 ModbusMessage transport_msg(); 01144 01145 // Это поле не входит в стандарт modbus 01146 // оно вспомогательное и игнорируется при 01147 // преобразовании в ModbusMessage. 01148 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 01149 // Используйте специальную функцию transport_msg() 01150 size_t count = { 0 }; 01151 }; 01152 std::ostream& operator<<(std::ostream& os, DiagnosticMessage& m ); 01153 std::ostream& operator<<(std::ostream& os, DiagnosticMessage* m ); 01154 // ----------------------------------------------------------------------- 01156 struct DiagnosticRetMessage: 01157 public DiagnosticMessage 01158 { 01159 DiagnosticRetMessage( const ModbusMessage& m ); 01160 DiagnosticRetMessage( const DiagnosticMessage& m ); 01161 DiagnosticRetMessage( ModbusAddr a, DiagnosticsSubFunction subf, ModbusData d = 0 ); 01162 }; 01163 01164 std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage& m ); 01165 std::ostream& operator<<(std::ostream& os, DiagnosticRetMessage* m ); 01166 // ----------------------------------------------------------------------- 01168 struct MEIMessageRDI: 01169 public ModbusHeader 01170 { 01171 ModbusByte type; 01172 ModbusByte devID; 01173 ModbusByte objID; 01175 ModbusCRC crc = { 0 }; 01177 // ------- to slave ------- 01178 MEIMessageRDI( ModbusAddr addr, ModbusByte devID, ModbusByte objID ); 01180 ModbusMessage transport_msg(); 01181 01182 // ------- from master ------- 01183 MEIMessageRDI( const ModbusMessage& m ); 01184 MEIMessageRDI& operator=( const ModbusMessage& m ); 01185 void init( const ModbusMessage& m ); 01186 01190 static inline size_t szHead() 01191 { 01192 return sizeof(ModbusByte) * 3; 01193 } 01194 01196 static inline size_t szData() 01197 { 01198 return sizeof(ModbusByte) * 3 + szCRC; 01199 } 01200 01201 // вспомогательные функции 01202 bool checkFormat() const; 01203 01204 } __attribute__((packed)); 01205 // ----------------------------------------------------------------------- 01206 std::ostream& operator<<(std::ostream& os, MEIMessageRDI& m ); 01207 std::ostream& operator<<(std::ostream& os, MEIMessageRDI* m ); 01208 // ----------------------------------------------------------------------- 01209 01210 struct RDIObjectInfo 01211 { 01212 RDIObjectInfo(): id(0), val("") {} 01213 RDIObjectInfo( ModbusByte id, const std::string& v ): id(id), val(v) {} 01214 RDIObjectInfo( ModbusByte id, const ModbusByte* dat, ModbusByte len ); 01215 01216 ModbusByte id; 01217 std::string val; 01218 }; 01219 01220 typedef std::list<RDIObjectInfo> RDIObjectList; 01221 01223 struct MEIMessageRetRDI: 01224 public ModbusHeader 01225 { 01226 ModbusByte type; 01227 ModbusByte devID; 01228 ModbusByte conformity; 01229 ModbusByte mf; 01230 ModbusByte objID; 01231 ModbusByte objNum; 01233 RDIObjectList dlist; 01234 ModbusCRC crc = { 0 }; 01235 01236 // ------- from slave ------- 01237 MEIMessageRetRDI(); 01238 MEIMessageRetRDI( const ModbusMessage& m ); 01239 MEIMessageRetRDI& operator=( const ModbusMessage& m ); 01240 void init( const ModbusMessage& m ); 01241 01242 // предварительная инициализации, только заголовочной части, без данных 01243 void pre_init( const ModbusMessage& m ); 01244 01246 static inline size_t szHead() 01247 { 01248 return sizeof(ModbusByte) * 6; 01249 } 01250 01251 // /*! узнать длину данных следующих за предварительным заголовком ( в байтах ) */ 01252 // static int getDataLen( ModbusMessage& m ); 01253 01254 // ------- to master ------- 01255 MEIMessageRetRDI( ModbusAddr _from, ModbusByte devID, ModbusByte conformity, ModbusByte mf, ModbusByte objID ); 01256 01261 bool addData( ModbusByte id, const std::string& value ); 01262 bool addData( RDIObjectInfo& dat ); 01263 01265 void clear(); 01266 01268 inline bool isFull() const 01269 { 01270 return ( bcnt >= MAXPDULEN ); 01271 } 01272 01274 size_t szData() const; 01275 01277 ModbusMessage transport_msg(); 01278 01279 size_t bcnt = { 0 }; 01280 }; 01281 01282 std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI& m ); 01283 std::ostream& operator<<(std::ostream& os, MEIMessageRetRDI* m ); 01284 std::ostream& operator<<(std::ostream& os, RDIObjectList& dl ); 01285 std::ostream& operator<<(std::ostream& os, RDIObjectList* dl ); 01286 // ----------------------------------------------------------------------- 01287 // ----------------------------------------------------------------------- 01288 01290 struct JournalCommandMessage: 01291 public ModbusHeader 01292 { 01293 ModbusData cmd = { 0 }; 01294 ModbusData num = { 0 }; 01295 ModbusCRC crc = { 0 }; 01296 01297 // ------------- 01298 JournalCommandMessage( const ModbusMessage& m ); 01299 JournalCommandMessage& operator=( const ModbusMessage& m ); 01300 01302 inline static size_t szData() 01303 { 01304 return sizeof(ModbusByte) * 4 + szCRC; 01305 } 01306 01307 } __attribute__((packed)); 01308 01309 std::ostream& operator<<(std::ostream& os, JournalCommandMessage& m ); 01310 std::ostream& operator<<(std::ostream& os, JournalCommandMessage* m ); 01311 // ----------------------------------------------------------------------- 01313 struct JournalCommandRetMessage: 01314 public ModbusHeader 01315 { 01316 ModbusByte bcnt = { 0 }; 01317 // ModbusByte data[MAXLENPACKET-1]; /*!< данные */ 01318 01319 // В связи со спецификой реализации ответной части (т.е. modbus master) 01320 // данные приходится делать не байтовым потоком, а "словами" 01321 // которые в свою очередь будут перевёрнуты при посылке... 01322 ModbusData data[MAXLENPACKET / sizeof(ModbusData)]; 01324 // ------------- 01325 JournalCommandRetMessage( ModbusAddr _from ); 01326 01333 bool setData( ModbusByte* b, int len ); 01334 01336 void clear(); 01337 01339 inline bool isFull() const 01340 { 01341 return ( count >= MAXDATALEN ); 01342 } 01343 01345 size_t szData() const; 01346 01348 ModbusMessage transport_msg(); 01349 01350 // Это поле не входит в стандарт modbus 01351 // оно вспомогательное и игнорируется при 01352 // преобразовании в ModbusMessage. 01353 // Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно. 01354 // Используйте специальную функцию transport_msg() 01355 size_t count = { 0 }; 01356 }; 01357 01358 std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage& m ); 01359 std::ostream& operator<<(std::ostream& os, JournalCommandRetMessage* m ); 01360 // ----------------------------------------------------------------------- 01364 struct JournalCommandRetOK: 01365 public JournalCommandRetMessage 01366 { 01367 // ------------- 01368 JournalCommandRetOK( ModbusAddr _from ); 01369 void set( ModbusData cmd, ModbusData ecode ); 01370 static void set( JournalCommandRetMessage& m, ModbusData cmd, ModbusData ecode ); 01371 }; 01372 01373 std::ostream& operator<<(std::ostream& os, JournalCommandRetOK& m ); 01374 std::ostream& operator<<(std::ostream& os, JournalCommandRetOK* m ); 01375 // ----------------------------------------------------------------------- 01376 01378 struct SetDateTimeMessage: 01379 public ModbusHeader 01380 { 01381 ModbusByte hour = { 0 }; 01382 ModbusByte min = { 0 }; 01383 ModbusByte sec = { 0 }; 01384 ModbusByte day = { 1 }; 01385 ModbusByte mon = { 1 }; 01386 ModbusByte year = { 0 }; 01387 ModbusByte century = { 20 }; 01389 ModbusCRC crc = { 0 }; 01390 01391 // ------- to slave ------- 01392 SetDateTimeMessage( ModbusAddr addr ); 01394 ModbusMessage transport_msg(); 01395 01396 // ------- from master ------- 01397 SetDateTimeMessage( const ModbusMessage& m ); 01398 SetDateTimeMessage& operator=( const ModbusMessage& m ); 01399 SetDateTimeMessage(); 01400 01401 bool checkFormat() const; 01402 01404 inline static size_t szData() 01405 { 01406 return sizeof(ModbusByte) * 7 + szCRC; 01407 } 01408 01409 } __attribute__((packed)); 01410 01411 std::ostream& operator<<(std::ostream& os, SetDateTimeMessage& m ); 01412 std::ostream& operator<<(std::ostream& os, SetDateTimeMessage* m ); 01413 // ----------------------------------------------------------------------- 01414 01416 struct SetDateTimeRetMessage: 01417 public SetDateTimeMessage 01418 { 01419 01420 // ------- from slave ------- 01421 SetDateTimeRetMessage( const ModbusMessage& m ); 01422 SetDateTimeRetMessage& operator=( const ModbusMessage& m ); 01423 void init( const ModbusMessage& m ); 01424 01425 // ------- to master ------- 01426 SetDateTimeRetMessage( ModbusAddr _from ); 01427 SetDateTimeRetMessage( const SetDateTimeMessage& query ); 01428 static void cpy( SetDateTimeRetMessage& reply, const SetDateTimeMessage& query ); 01429 01431 ModbusMessage transport_msg(); 01432 }; 01433 // ----------------------------------------------------------------------- 01434 01436 struct RemoteServiceMessage: 01437 public ModbusHeader 01438 { 01439 ModbusByte bcnt = { 0 }; 01442 ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)]; 01443 ModbusCRC crc = { 0 }; 01445 // ----------- 01446 RemoteServiceMessage( const ModbusMessage& m ); 01447 RemoteServiceMessage& operator=( const ModbusMessage& m ); 01448 void init( const ModbusMessage& m ); 01449 01451 size_t szData() const; 01452 01456 static inline size_t szHead() 01457 { 01458 return sizeof(ModbusByte); // bcnt 01459 } 01460 01462 static size_t getDataLen( const ModbusMessage& m ); 01463 01464 } __attribute__((packed)); 01465 01466 std::ostream& operator<<(std::ostream& os, RemoteServiceMessage& m ); 01467 std::ostream& operator<<(std::ostream& os, RemoteServiceMessage* m ); 01468 // ----------------------------------------------------------------------- 01469 struct RemoteServiceRetMessage: 01470 public ModbusHeader 01471 { 01472 ModbusByte bcnt = { 0 }; 01474 ModbusByte data[MAXLENPACKET - sizeof(ModbusByte)]; 01475 01476 RemoteServiceRetMessage( ModbusAddr _from ); 01477 01484 bool setData( ModbusByte* b, int len ); 01485 01487 void clear(); 01488 01490 inline bool isFull() const 01491 { 01492 return ( count >= sizeof(data) ); 01493 } 01494 01496 size_t szData() const; 01497 01499 ModbusMessage transport_msg(); 01500 01501 // Это поле не входит в стандарт modbus 01502 // оно вспомогательное и игнорируется при 01503 // преобразовании в ModbusMessage. 01504 size_t count = { 0 }; 01505 }; 01506 // ----------------------------------------------------------------------- 01507 01508 struct ReadFileRecordMessage: 01509 public ModbusHeader 01510 { 01511 struct SubRequest 01512 { 01513 ModbusByte reftype; 01514 ModbusData numfile; 01515 ModbusData numrec; 01516 ModbusData reglen; 01517 } __attribute__((packed)); 01518 01519 ModbusByte bcnt = { 0 }; 01522 SubRequest data[MAXLENPACKET / sizeof(SubRequest) - sizeof(ModbusByte)]; 01523 ModbusCRC crc = { 0 }; 01525 // ----------- 01526 ReadFileRecordMessage( const ModbusMessage& m ); 01527 ReadFileRecordMessage& operator=( const ModbusMessage& m ); 01528 void init( const ModbusMessage& m ); 01529 01531 size_t szData() const; 01532 01536 static inline size_t szHead() 01537 { 01538 return sizeof(ModbusByte); // bcnt 01539 } 01540 01542 static size_t getDataLen( const ModbusMessage& m ); 01543 01545 bool checkFormat() const; 01546 01547 // это поле служебное и не используется в релальном обмене 01548 size_t count = { 0 }; 01549 }; 01550 01551 std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage& m ); 01552 std::ostream& operator<<(std::ostream& os, ReadFileRecordMessage* m ); 01553 // ----------------------------------------------------------------------- 01554 01555 struct FileTransferMessage: 01556 public ModbusHeader 01557 { 01558 ModbusData numfile = { 0 }; 01559 ModbusData numpacket = { 0 }; 01560 ModbusCRC crc = { 0 }; 01562 // ------- to slave ------- 01563 FileTransferMessage( ModbusAddr addr, ModbusData numfile, ModbusData numpacket ); 01564 ModbusMessage transport_msg(); 01566 // ------- from master ------- 01567 FileTransferMessage( const ModbusMessage& m ); 01568 FileTransferMessage& operator=( const ModbusMessage& m ); 01569 void init( const ModbusMessage& m ); 01570 01572 static inline size_t szData() 01573 { 01574 return sizeof(ModbusData) * 2 + szCRC; 01575 } 01576 01577 } __attribute__((packed)); 01578 01579 std::ostream& operator<<(std::ostream& os, FileTransferMessage& m ); 01580 std::ostream& operator<<(std::ostream& os, FileTransferMessage* m ); 01581 // ----------------------------------------------------------------------- 01582 01583 struct FileTransferRetMessage: 01584 public ModbusHeader 01585 { 01586 // 255 - max of bcnt...(1 byte) 01587 // static const int MaxDataLen = 255 - szCRC - szModbusHeader - sizeof(ModbusData)*3 - sizeof(ModbusByte)*2; 01588 static const size_t MaxDataLen = MAXLENPACKET - sizeof(ModbusData) * 3 - sizeof(ModbusByte) * 2; 01589 01590 ModbusByte bcnt; 01591 ModbusData numfile; 01592 ModbusData numpacks; 01593 ModbusData packet; 01594 ModbusByte dlen; 01595 ModbusByte data[MaxDataLen]; 01596 01597 01598 // ------- from slave ------- 01599 FileTransferRetMessage( const ModbusMessage& m ); 01600 FileTransferRetMessage& operator=( const ModbusMessage& m ); 01601 void init( const ModbusMessage& m ); 01602 ModbusCRC crc = { 0 }; 01603 static size_t szHead() 01604 { 01605 return sizeof(ModbusByte); 01606 } 01607 static size_t getDataLen( const ModbusMessage& m ); 01608 01609 // ------- to master ------- 01610 FileTransferRetMessage( ModbusAddr _from ); 01611 01615 bool set( ModbusData numfile, ModbusData file_num_packets, ModbusData packet, ModbusByte* b, ModbusByte len ); 01616 01618 void clear(); 01619 01621 size_t szData() const; 01622 01624 ModbusMessage transport_msg(); 01625 }; 01626 01627 std::ostream& operator<<(std::ostream& os, FileTransferRetMessage& m ); 01628 std::ostream& operator<<(std::ostream& os, FileTransferRetMessage* m ); 01629 // ----------------------------------------------------------------------- 01630 } // end of ModbusRTU namespace 01631 // ------------------------------------------------------------------------- 01632 } // end of namespace uniset 01633 // --------------------------------------------------------------------------- 01634 #endif // ModbusTypes_H_ 01635 // ---------------------------------------------------------------------------
1.7.6.1