master_plugin.cpp
Go to the documentation of this file.
4 
5 #include <set>
6 
7 namespace canopen {
8 
9 class ManagingSyncLayer: public SyncLayer {
10 protected:
12  boost::chrono::milliseconds step_, half_step_;
13 
14  std::set<void *> nodes_;
15  boost::mutex nodes_mutex_;
16  std::atomic<size_t> nodes_size_;
17 
18  virtual void handleShutdown(LayerStatus &status) {
19  }
20 
21  virtual void handleHalt(LayerStatus &status) { /* nothing to do */ }
22  virtual void handleDiag(LayerReport &report) { /* TODO */ }
23  virtual void handleRecover(LayerStatus &status) { /* TODO */ }
24 
25 public:
27  : SyncLayer(p), interface_(interface), step_(p.period_ms_), half_step_(p.period_ms_/2), nodes_size_(0)
28  {
29  }
30 
31  virtual void addNode(void * const ptr) {
32  boost::mutex::scoped_lock lock(nodes_mutex_);
33  nodes_.insert(ptr);
34  nodes_size_ = nodes_.size();
35  }
36  virtual void removeNode(void * const ptr) {
37  boost::mutex::scoped_lock lock(nodes_mutex_);
38  nodes_.erase(ptr);
39  nodes_size_ = nodes_.size();
40  }
41 };
42 
43 
45  time_point read_time_, write_time_;
47  uint8_t overflow_;
48 
49  void resetCounter(){
50  frame_.data[0] = 1; // SYNC counter starts at 1
51  }
53  if (frame_.dlc > 0) { // sync counter is used
54  if (frame_.data[0] >= overflow_) {
55  resetCounter();
56  }else{
57  ++frame_.data[0];
58  }
59  }
60  }
61 protected:
62  virtual void handleRead(LayerStatus &status, const LayerState &current_state) {
63  if(current_state > Init){
64  boost::this_thread::sleep_until(read_time_);
65  write_time_ += step_;
66  }
67  }
68  virtual void handleWrite(LayerStatus &status, const LayerState &current_state) {
69  if(current_state > Init){
70  boost::this_thread::sleep_until(write_time_);
71  tryUpdateCounter();
72  if(nodes_size_){ //)
73  interface_->send(frame_);
74  }
75  read_time_ = get_abs_time(half_step_);
76  }
77  }
78 
79  virtual void handleInit(LayerStatus &status){
80  write_time_ = get_abs_time(step_);
81  read_time_ = get_abs_time(half_step_);
82  }
83 public:
85  : ManagingSyncLayer(p, interface), frame_(p.header_, 0), overflow_(p.overflow_) {
86  if(overflow_ == 1 || overflow_ > 240){
87  BOOST_THROW_EXCEPTION(Exception("SYNC counter overflow is invalid"));
88  }else if(overflow_ > 1){
89  frame_.dlc = 1;
90  resetCounter();
91  }
92  }
93 };
94 
97 protected:
98  virtual void handleRead(LayerStatus &status, const LayerState &current_state) {
99  can::Frame msg;
100  if(current_state > Init){
101  if(reader_.readUntil(&msg, get_abs_time(step_))){ // wait for sync
102  boost::this_thread::sleep_until(get_abs_time(half_step_)); // shift readout to middle of period
103  }
104  }
105  }
106  virtual void handleWrite(LayerStatus &status, const LayerState &current_state) {
107  // nothing to do here
108  }
109  virtual void handleInit(LayerStatus &status){
111  }
112 public:
114  : ManagingSyncLayer(p, interface), reader_(true,1) {}
115 };
116 
117 
118 template<typename SyncType> class WrapMaster: public Master{
120 public:
122  return std::make_shared<SyncType>(properties, interface_);
123  }
124  WrapMaster(can::CommInterfaceSharedPtr interface) : interface_(interface) {}
125 
126  class Allocator : public Master::Allocator{
127  public:
128  virtual MasterSharedPtr allocate(const std::string &name, can::CommInterfaceSharedPtr interface){
129  return std::make_shared<WrapMaster>(interface);
130  }
131  };
132 };
133 
136 }
std::array< value_type, 8 > data
std::set< void * > nodes_
const SyncProperties properties
Definition: canopen.h:181
can::BufferedReader reader_
void listen(CommInterfaceSharedPtr interface)
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
virtual MasterSharedPtr allocate(const std::string &name, can::CommInterfaceSharedPtr interface)
virtual void handleShutdown(LayerStatus &status)
can::CommInterfaceSharedPtr interface_
bool readUntil(can::Frame *msg, boost::chrono::high_resolution_clock::time_point abs_time)
const can::Header header_
Definition: canopen.h:171
std::shared_ptr< Master > MasterSharedPtr
Definition: canopen.h:319
can::CommInterfaceSharedPtr interface_
CLASS_LOADER_REGISTER_CLASS(canopen::SimpleMaster::Allocator, canopen::Master::Allocator)
boost::chrono::milliseconds step_
std::atomic< size_t > nodes_size_
boost::chrono::high_resolution_clock::time_point time_point
Definition: canopen.h:18
std::shared_ptr< CommInterface > CommInterfaceSharedPtr
virtual SyncLayerSharedPtr getSync(const SyncProperties &properties)
virtual void addNode(void *const ptr)
virtual void handleRead(LayerStatus &status, const LayerState &current_state)
WrapMaster< SimpleSyncLayer > SimpleMaster
WrapMaster(can::CommInterfaceSharedPtr interface)
const std::string name
Definition: layer.h:75
virtual void handleRecover(LayerStatus &status)
SimpleSyncLayer(const SyncProperties &p, can::CommInterfaceSharedPtr interface)
virtual void handleRead(LayerStatus &status, const LayerState &current_state)
WrapMaster< ExternalSyncLayer > ExternalMaster
virtual void handleInit(LayerStatus &status)
virtual void removeNode(void *const ptr)
boost::chrono::milliseconds half_step_
ManagingSyncLayer(const SyncProperties &p, can::CommInterfaceSharedPtr interface)
unsigned char dlc
virtual void handleDiag(LayerReport &report)
std::shared_ptr< SyncLayer > SyncLayerSharedPtr
Definition: canopen.h:309
ExternalSyncLayer(const SyncProperties &p, can::CommInterfaceSharedPtr interface)
time_point get_abs_time(const time_duration &timeout)
Definition: canopen.h:20
virtual void handleInit(LayerStatus &status)
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
virtual void handleHalt(LayerStatus &status)


canopen_master
Author(s): Mathias Lüdtke
autogenerated on Mon Feb 28 2022 23:28:03