43 #ifndef _MLAB_CANOPENSDOCLIENT_H_ 44 #define _MLAB_CANOPENSDOCLIENT_H_ 49 #include <boost/thread/future.hpp> 50 #include <boost/thread/mutex.hpp> 52 #include <boost/format.hpp> 63 namespace mira {
namespace can {
104 boost::shared_ptr<ReadRequest<T>> request(
new ReadRequest<T>(node, index, subIndex));
105 boost::mutex::scoped_lock lock(mReadRequestsMutex);
106 uint64 requestID = getNextRequestID();
107 mReadRequests[requestID] = request;
108 sendSDOReadRequest(request);
109 return SDOFuture<T>(request->promise.get_future(),
this, requestID);
122 T
readSync(uint8 node, uint16 index, uint8 subIndex,
127 while(tries++ < maxTries)
129 auto r = read<T>(node, index, subIndex);
130 if (r.timedWait(waitTime))
133 MIRA_THROW(XTimeout,
"Timeout during read SDO " << std::hex
136 <<
"subindex (0x" <<
boost::format(
"%02x") % (
int)subIndex <<
")");
165 std::size_t size = CANOpenUtil::write<T>(message, 4, value);
167 boost::shared_ptr<WriteRequest> request(
new WriteRequest(node, index, subIndex));
168 boost::mutex::scoped_lock lock(mWriteRequestsMutex);
169 uint64 requestID = getNextRequestID();
170 mWriteRequests[requestID] = request;
171 sendSDOWriteRequest(request, message, size);
172 return SDOFuture<void>(request->promise.get_future(),
this, requestID);
191 while(tries++ < maxTries)
193 auto w = write<T>(node, index, subIndex, value);
194 if (w.timedWait(waitTime))
197 MIRA_THROW(XTimeout,
"Timeout during write SDO " << std::hex
200 <<
"subindex (0x" <<
boost::format(
"%02x") % (
int)subIndex <<
")");
206 virtual void onDestructFuture(uint64 requestID);
212 class ReadWriteRequestBase
215 ReadWriteRequestBase(uint8 iNode, uint16 iIdx, uint8 iSubIdx) :
216 node(iNode), idx(iIdx), subIdx(iSubIdx) {}
217 virtual ~ReadWriteRequestBase() {}
219 virtual void setMessage(
const CANMessage& message, std::size_t offset) = 0;
220 virtual void setException(
const Exception& ex) = 0;
232 public ReadWriteRequestBase
235 ReadRequest(uint8 iNode, uint16 iIdx, uint8 iSubIdx) :
236 ReadWriteRequestBase(iNode, iIdx, iSubIdx) {}
237 virtual ~ReadRequest() {}
239 virtual void setMessage(
const CANMessage& message, std::size_t offset) {
240 T value = CANOpenUtil::read<T>(message, offset);
241 promise.set_value(value);
243 virtual void setException(
const Exception& ex) {
244 promise.set_exception(boost::copy_exception(ex));
247 boost::promise<T> promise;
253 class WriteRequest :
public ReadWriteRequestBase
256 WriteRequest(uint8 iNode, uint16 iIdx, uint8 iSubIdx) :
257 ReadWriteRequestBase(iNode, iIdx, iSubIdx) {}
258 virtual ~WriteRequest() {}
260 virtual void setMessage(
const CANMessage& message, std::size_t offset) {
263 virtual void setException(
const Exception& ex) {
264 promise.set_exception(boost::copy_exception(ex));
267 boost::promise<void> promise;
270 typedef boost::shared_ptr<ReadWriteRequestBase> RequestPtr;
271 typedef std::map<uint64, RequestPtr> RequestList;
277 void sendSDOReadRequest(RequestPtr iRequest);
280 void sendSDOWriteRequest(RequestPtr iRequest,
281 CANMessage& iMessage, std::size_t iSize);
284 void processSDOMessage(
const CANMessage& iMsg,
const Time& time);
287 static uint64 getNextRequestID() {
288 static uint64 sNextRequestID = 0;
289 static boost::mutex sIDMutex;
291 boost::mutex::scoped_lock lock(sIDMutex);
292 return(sNextRequestID++);
299 RequestList mReadRequests;
300 boost::mutex mReadRequestsMutex;
301 RequestList mWriteRequests;
302 boost::mutex mWriteRequestsMutex;
TEigenFormat< Derived > format(Eigen::MatrixBase< Derived > &matrix, Eigen::IOFormat format=EigenFormat::matlab())
tick_type milliseconds() const
T readSync(uint8 node, uint16 index, uint8 subIndex, Duration waitTime=Duration::milliseconds(50), uint32 maxTries=5)
Perform a synchronous SDO upload (read operation)
Definition: CANOpenSDOClient.h:122
Abstract class for a hardware specific CAN driver.
boost::shared_ptr< CANInterface > CANInterfacePtr
A shared pointer of the CANInterface.
Definition: CANInterface.h:224
Global definitions of the CANopen standard.
A CANopen SDO client.
Definition: CANOpenSDOClient.h:73
#define MIRA_THROW(ex, msg)
Definition: SDOFuture.h:54
boost::shared_ptr< CANOpenSDOClient > CANOpenSDOClientPtr
A shared pointer of the CANOpenSDOClient.
Definition: CANOpenSDOClient.h:306
This is a specialization for SDO calls with the return type of void, where no get() method is availab...
Definition: SDOFuture.h:221
#define MLAB_CAN_EXPORT
Definition: CANExports.h:57
A SDOFuture is a proxy for the result of an asynchronous SDO upload or download.
Definition: SDOFuture.h:163
Implementation of a future for SDO read and write operations.
A struct, which contains standard information about a CANopen node.
Definition: CANOpenDefs.h:165
CANopen utility functions.
SDOFuture< void > write(uint8 node, uint16 index, uint8 subIndex, T value)
Perform an expedited SDO download (a write operation)
Definition: CANOpenSDOClient.h:162
A definition of a CAN message.
Definition: CANDefs.h:105
SDOFuture< void > writeSync(uint8 node, uint16 index, uint8 subIndex, T value, Duration waitTime=Duration::milliseconds(50), uint32 maxTries=5)
Perform a synchronous write operation.
Definition: CANOpenSDOClient.h:186
SDOFuture< T > read(uint8 node, uint16 index, uint8 subIndex)
Perform an expedited SDO upload (a read operation)
Definition: CANOpenSDOClient.h:102