modbusrtuinterface.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef MODBUSRTUINTERFACE_H_
15 #define MODBUSRTUINTERFACE_H_
16 
17 #include "charinterface.h"
18 #include "chardevicedriver.h"
19 #include "serial.h"
20 
22 public:
23  XModbusRTUInterface(const char *name, bool runtime, const shared_ptr<XDriver> &driver);
24  virtual ~XModbusRTUInterface();
25 
26  void readHoldingResistors(uint16_t res_addr, int count, std::vector<uint16_t> &data);
27  void presetSingleResistor(uint16_t res_addr, uint16_t data);
28  void presetMultipleResistors(uint16_t res_no, int count, const std::vector<uint16_t> &data);
29  void diagnostics();
30 
31  uint16_t readHoldingSingleResistor(uint16_t res_addr) {
32  std::vector<uint16_t> data(1);
33  readHoldingResistors(res_addr, 1, data);
34  return data[0];
35  }
36  uint32_t readHoldingTwoResistors(uint16_t res_addr) {
37  std::vector<uint16_t> data(2);
38  readHoldingResistors(res_addr, 2, data);
39  return data[0] * 0x10000uL + data[1];
40  }
41  void presetTwoResistors(uint16_t res_addr, uint32_t dword) {
42  std::vector<uint16_t> data(2);
43  data[0] = dword / 0x10000uL;
44  data[1] = dword % 0x10000uL;
45  presetMultipleResistors(res_addr, 2, data);
46  }
47 protected:
48  virtual void open() throw (XInterfaceError &);
49  //! This can be called even if has already closed.
50  virtual void close() throw (XInterfaceError &);
51 
52  virtual bool isOpened() const {return !!m_openedPort;}
53 
54  void query_unicast(unsigned int func_code, const std::vector<unsigned char> &bytes, std::vector<unsigned char> &buf);
55 private:
56  //Modbus utilizes Big endian.
57  static void set_word(unsigned char *ptr, uint16_t word) {
58  ptr[0] = static_cast<unsigned char>(word / 0x100u);
59  ptr[1] = static_cast<unsigned char>(word % 0x100u);
60  }
61  static void set_dword(unsigned char *ptr, uint32_t dword) {
62  set_word(ptr, static_cast<uint16_t>(dword / 0x10000u));
63  set_word(ptr + 2, static_cast<uint16_t>(dword % 0x10000u));
64  }
65  static uint16_t get_word(unsigned char *ptr) {
66  return ptr[1] +ptr[0] * 0x100u;
67  }
68  static uint32_t get_dword(unsigned char *ptr) {
69  return get_word(ptr + 2) + get_word(ptr) * 0x10000uL;
70  }
71  uint16_t crc16(const unsigned char *bytes, uint32_t count);
72 
73  struct PortWrapper {
74  shared_ptr<XPort> port;
75  XTime lastTimeStamp;
76  XMutex mutex; //for the port.
77  };
78  shared_ptr<PortWrapper> m_openedPort;
79  static XMutex s_globalMutex;
80  static std::deque<weak_ptr<PortWrapper>> s_openedPorts; //should be guarded by s_globalMutex.
81 };
82 
83 template <class T>
84 class XModbusRTUDriver : public XCharDeviceDriver<T, XModbusRTUInterface> {
85 public:
86  XModbusRTUDriver(const char *name, bool runtime,
87  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
88  XCharDeviceDriver<T, XModbusRTUInterface>(name, runtime, ref(tr_meas), meas) {}
89  virtual ~XModbusRTUDriver() {};
90 };
91 
92 #endif /*MODBUSRTUINTERFACE_H_*/

Generated for KAME4 by  doxygen 1.8.3