MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/ModbusRtu.hh

198 lines
5.3 KiB
C++

/*
* ModbusRtu.hh
*
* Created on: 26 àâã. 2020 ã.
* Author: LeonidTitov
*/
#ifndef UMLIBRARY_DRIVER_MODBUSRTU_HH_
#define UMLIBRARY_DRIVER_MODBUSRTU_HH_
#include <cstddef>
#include <stdint.h>
#include <memory_resource>
#include <deque>
#include <vector>
#include <map>
#include "../common/Crc.hpp"
#include "../peripheral/IUartPort.hh"
#include "IModBus.hh"
namespace driver {
namespace modbus {
using peripheral::IUartPort;
using std::pmr::memory_resource;
using std::pmr::polymorphic_allocator;
using std::pmr::get_default_resource;
using std::deque;
using std::vector;
using std::map;
using std::pair;
using std::make_pair;
typedef deque<char,polymorphic_allocator<char> > DequePolyAlloc;
typedef deque<uint16_t,polymorphic_allocator<uint16_t> > DequeU16PolyAlloc;
typedef map<uint16_t, uint16_t, std::less<uint16_t>,
polymorphic_allocator<pair<const uint16_t,uint16_t> > > MapPolyAlloc;
typedef vector<char,polymorphic_allocator<char> > VecPolyAlloc;
typedef map<uint16_t,IModBusDispatch*,std::less<uint16_t>,
polymorphic_allocator<pair<const uint16_t,IModBusDispatch*> > > MapDispPolyAlloc;
class ModBusPdu;
class ModBusDispatch;
class ModBusAdu {
IUartPort & mIUartPort;
const unsigned char mAddr;
memory_resource * const mpMemRes;
friend class ModBusPdu;
friend class ModBusDispatch;
bool crc_error_flag;
public:
typedef common::crc::Crc16_IBM ModbusCrc;
ModBusAdu ( unsigned char addr, IUartPort& port, memory_resource* pMemRes ) :
mIUartPort(port), mAddr(addr), mpMemRes(pMemRes), crc_error_flag(false) {}
/* Çàïðîñ ôðýéìà PDU */
bool getFrm( DequePolyAlloc & deqFrm );
bool putFrm( DequePolyAlloc & deqFrm );
bool isCrcError() const;
};
class ModBusPdu {
enum FuncCode {
DummyCode, // ??
ReadCoil = 1, WriteSingleCoil = 5, WriteMultipleCoil = 15, // DO
ReadDiscreteInput = 2, // DI
ReadHoldingReg = 3, WriteSingleReg = 6, WriteMultipleReg = 16, // AO
ReadInputReg = 4, // AI
};
friend class ModBusDispatch;
public:
enum ExceptCode {
NoException, IllegalFunc, IllegalDataAddr, IllegalDataValue, ServerDeviceFail,
Acknowledge, ServerDeviceBusy, MemoryParityErr = 8,
GatewayPathUnvail = 10, GatewayTargetDeviceFailResp
};
private:
struct DataTableBegin {
static const uint16_t DO = 1;
static const uint16_t DI = 10001;
static const uint16_t AI = 30001;
static const uint16_t AO = 40001;
};
ModBusAdu & mAdu;
DequePolyAlloc deqFrmReq; //!<Áóôåð äëÿ çàïðîñà
DequePolyAlloc deqFrmRes; //!<Áóôåð äëÿ îòâåòà
bool mIsBroadcast; //!<Ôëàã øèðîêîâåøàòåëüíîãî çàïðîñà
uint16_t mFuncCode; //!< != 0 Òåêóùèé àêòèâíûé êîä, 0 -> ñîñòîÿíèå îæèäàíèÿ
ExceptCode mExcCode; //!<Êîä èñêëþ÷åíèÿ
uint16_t packet_counter;
public:
MapPolyAlloc mMapTaskRd; //!<Î÷åðåäü çàäàíèé íà ÷òåíèå
MapPolyAlloc mMapTaskWr; //!<Î÷åðåäü çàäàíèé íà çàïèñü
MapPolyAlloc mMapTaskRes; //!<Î÷åðåäü ïîëó÷åííûõ ðåçóëüòàòîâ
public:
ModBusPdu ( ModBusAdu& adu ) :
mAdu(adu), mIsBroadcast(false), mFuncCode(DummyCode), mExcCode(NoException),
deqFrmReq(adu.mpMemRes), deqFrmRes(adu.mpMemRes),
mMapTaskRd(std::less<uint16_t>(),adu.mpMemRes),
mMapTaskWr(std::less<uint16_t>(),adu.mpMemRes),
mMapTaskRes(std::less<uint16_t>(),adu.mpMemRes),
packet_counter(0) {}
//!Ïðîöåññ îæèäàíèÿ çàïðîñà è ôîðìèðîâàíèÿ ïî íåìó ñïèñêà çàäàíèé
void processReq();
//!Ïðîöåññ îæèäàíèÿ âûïîëíåíèå ñïèñêà çàäàíèé è îòïðàâêà îòâåòà íà çàïðîñ
void processResp();
void setExceptCode( ExceptCode code );
bool isException() const;
uint16_t getPacketCounter() const;
ExceptCode getExceptCode() const;
private:
//!Ïîëó÷åíèå ìàêñèìàëüíî êîëè÷åñòâà ðåãèñòðîâ â îïåðàöèè ïî åå êîäó
uint16_t getLimitQuantity( FuncCode code ) const;
//!Ïîëó÷åíèå íà÷àëüíîãî ñìåùåíèÿ â òàáëèöå äàííûõ ïî êîäó îïåðàöèè
uint16_t getDataTblShift( FuncCode code ) const;
};
class ModBusDispatch {
enum TaskType { TaskRead, TaskWrite };
MapDispPolyAlloc mBase;
ModBusPdu & mPdu;
public:
ModBusDispatch ( ModBusPdu& pdu ) :
mPdu(pdu), mBase(std::less<uint16_t>(), pdu.mAdu.mpMemRes) {}
void add( uint16_t nReg, IModBusDispatch & disp );
void del( uint16_t nReg );
void process();
private:
void dispatch( TaskType typeOp, MapPolyAlloc & mapTasks );
};
class ModBusRtu : public IModBus {
ModBusAdu mAdu;
ModBusPdu mPdu;
ModBusDispatch mDisp;
IUartPort& mPort;
public:
ModBusRtu ( uint16_t addr, IUartPort& port,
memory_resource* pMemRes = get_default_resource () ) :
mAdu(addr,port,pMemRes), mPdu(mAdu), mDisp(mPdu), mPort(port) {}
void process();
void add( uint16_t nReg, IModBusDispatch & disp );
void del( uint16_t nReg );
bool isCrcError() const;
bool isException() const;
float getPacketCounter() const;
};
} // namespace modbus
} // namespace driver
#endif /* UMLIBRARY_DRIVER_MODBUSRTU_HH_ */