emcy.cpp
Go to the documentation of this file.
3 
4 using namespace canopen;
5 
6 #pragma pack(push) /* push current alignment to stack */
7 #pragma pack(1) /* set alignment to 1 byte boundary */
8 
9 struct EMCYid{
10  uint32_t id:29;
11  uint32_t extended:1;
12  uint32_t :1;
13  uint32_t invalid:1;
14  EMCYid(uint32_t val){
15  *(uint32_t*) this = val;
16  }
18  return can::Header(id, extended, false, false);
19  }
20  const uint32_t get() const { return *(uint32_t*) this; }
21 };
22 
23 struct EMCYfield{
24  uint32_t error_code:16;
25  uint32_t addition_info:16;
26  EMCYfield(uint32_t val){
27  *(uint32_t*) this = val;
28  }
29 };
30 
31 struct EMCYmsg{
32  uint16_t error_code;
33  uint8_t error_register;
34  uint8_t manufacturer_specific_error_field[5];
35 
36  struct Frame: public FrameOverlay<EMCYmsg>{
37  Frame(const can::Frame &f) : FrameOverlay(f){ }
38  };
39 };
40 
41 #pragma pack(pop) /* pop previous alignment from stack */
42 
44  EMCYmsg::Frame em(msg);
45  LOG("EMCY: " << can::tostring(msg, false));
46  has_error_ = (em.data.error_register & ~32) != 0;
47 }
48 
49 EMCYHandler::EMCYHandler(const can::CommInterfaceSharedPtr interface, const ObjectStorageSharedPtr storage): Layer("EMCY handler"), storage_(storage), has_error_(true){
50  storage_->entry(error_register_, 0x1001);
51  try{
52  storage_->entry(num_errors_, 0x1003,0);
53  }
54  catch(...){
55  // pass, 1003 is optional
56  }
57  try{
58  EMCYid emcy_id(storage_->entry<uint32_t>(0x1014).get_cached());
59  emcy_listener_ = interface->createMsgListener( emcy_id.header(), can::CommInterface::FrameDelegate(this, &EMCYHandler::handleEMCY));
60  }
61  catch(...){
62  // pass, EMCY is optional
63  }
64 }
65 
66 void EMCYHandler::handleRead(LayerStatus &status, const LayerState &current_state) {
67  if(current_state == Ready){
68  if(has_error_){
69  status.error("Node has emergency error");
70  }
71  }
72 }
73 void EMCYHandler::handleWrite(LayerStatus &status, const LayerState &current_state) {
74  // noithing to do
75 }
76 
78  uint8_t error_register = 0;
79  if(!error_register_.get(error_register)){
80  report.error("Could not read error error_register");
81  return;
82  }
83 
84  if(error_register){
85  if(error_register & 1){ // first bit should be set on all errors
86  report.error("Node has emergency error");
87  }else if(error_register & ~32){ // filter profile-specific bit
88  report.warn("Error register is not zero");
89  }
90  report.add("error_register", (uint32_t) error_register);
91 
92  uint8_t num = num_errors_.valid() ? num_errors_.get() : 0;
93  std::stringstream buf;
94  for(size_t i = 0; i < num; ++i) {
95  if( i!= 0){
96  buf << ", ";
97  }
98  try{
100  storage_->entry(error, 0x1003,i+1);
101  EMCYfield field(error.get());
102  buf << std::hex << field.error_code << "#" << field.addition_info;
103  }
104  catch (const std::out_of_range & e){
105  buf << "NOT_IN_DICT!";
106  }
107  catch (const TimeoutException & e){
108  buf << "LIST_UNDERFLOW!";
109  break;
110  }
111 
112  }
113  report.add("errors", buf.str());
114 
115  }
116 }
118  uint8_t error_register = 0;
119  if(!error_register_.get(error_register)){
120  status.error("Could not read error error_register");
121  return;
122  }else if(error_register & 1){
123  LOG("ER: " << int(error_register));
124  status.error("Node has emergency error");
125  return;
126  }
127 
128  resetErrors(status);
129 }
131  if(num_errors_.valid()) num_errors_.set(0);
132  has_error_ = false;
133 }
134 
136  handleInit(status);
137 }
139 }
141  // do nothing
142 }
EMCYHandler(const can::CommInterfaceSharedPtr interface, const ObjectStorageSharedPtr storage)
Definition: emcy.cpp:49
uint32_t error_code
Definition: emcy.cpp:24
std::string tostring(const Header &h, bool lc)
Frame(const can::Frame &f)
Definition: emcy.cpp:37
virtual void handleHalt(LayerStatus &status)
Definition: emcy.cpp:140
Definition: emcy.cpp:9
const void warn(const std::string &r)
Definition: layer.h:43
EMCYfield(uint32_t val)
Definition: emcy.cpp:26
ObjectStorage::Entry< uint8_t > num_errors_
Definition: canopen.h:146
boost::atomic< bool > has_error_
Definition: canopen.h:144
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
Definition: emcy.cpp:73
void handleEMCY(const can::Frame &msg)
Definition: emcy.cpp:43
boost::shared_ptr< CommInterface > CommInterfaceSharedPtr
can::FrameListenerConstSharedPtr emcy_listener_
Definition: canopen.h:147
virtual void handleRecover(LayerStatus &status)
Definition: emcy.cpp:135
virtual void handleInit(LayerStatus &status)
Definition: emcy.cpp:117
#define LOG(log)
fastdelegate::FastDelegate1< const Frame & > FrameDelegate
can::Header header()
Definition: emcy.cpp:17
void resetErrors(LayerStatus &status)
Definition: emcy.cpp:130
virtual void handleDiag(LayerReport &report)
Definition: emcy.cpp:77
uint8_t error_register
Definition: emcy.cpp:33
const ObjectStorageSharedPtr storage_
Definition: canopen.h:149
uint16_t error_code
Definition: emcy.cpp:32
ObjectStorage::Entry< uint8_t > error_register_
Definition: canopen.h:145
Definition: emcy.cpp:31
void add(const std::string &key, const T &value)
Definition: layer.h:51
virtual void handleShutdown(LayerStatus &status)
Definition: emcy.cpp:138
const void error(const std::string &r)
Definition: layer.h:44
void set(const T &val)
Definition: objdict.h:407
EMCYid(uint32_t val)
Definition: emcy.cpp:14
ObjectStorage::ObjectStorageSharedPtr ObjectStorageSharedPtr
Definition: objdict.h:523
virtual void handleRead(LayerStatus &status, const LayerState &current_state)
Definition: emcy.cpp:66


canopen_master
Author(s): Mathias Lüdtke
autogenerated on Sat May 4 2019 02:40:43