Lely core libraries 2.3.4
logical_driver.cpp
Go to the documentation of this file.
1
24#include "coapp.hpp"
25
26#if !LELY_NO_COAPP_MASTER
27
29
30namespace lely {
31
32namespace canopen {
33
34BasicLogicalDriver<BasicDriver>::BasicLogicalDriver(BasicDriver& driver_,
35 int num, uint32_t dev)
36 : master(driver_.master),
37 driver(driver_),
38 rpdo_mapped(*this),
39 tpdo_mapped(*this),
40 tpdo_event_mutex(driver_.tpdo_event_mutex),
41 num_(num),
42 dev_(dev) {
43 driver.Insert(*this);
44}
45
46BasicLogicalDriver<BasicDriver>::~BasicLogicalDriver() { driver.Erase(*this); }
47
48SdoFuture<void>
49BasicLogicalDriver<BasicDriver>::AsyncConfig() {
50 SdoFuture<void> f;
51 // A convenience function which reads and copies the device type from object
52 // 67FF:00 (adjusted for logical device number) in the remote object
53 // dictionary.
54 auto read_67ff = [this]() {
55 return AsyncRead<uint32_t>(0x67ff, 0).then(
56 GetExecutor(),
57 [this](SdoFuture<uint32_t> f) { dev_ = f.get().value(); });
58 };
59 if (num_ == 1) {
60 // A convenience function which checks and copies the value of the
61 // (expected) device type or, if it indicates multiple logical devices,
62 // reads the value from object 67FF:00 in the remote object dictionary.
63 auto check_1000 = [this, read_67ff](uint32_t value) -> SdoFuture<void> {
64 if ((value) >> 16 == 0xffff) return read_67ff();
65 dev_ = value;
66 return make_empty_sdo_future();
67 };
68 ::std::error_code ec;
69 // Try to read the expected device type from the local object dictionary
70 // (object 1F84:$NODEID).
71 auto value = driver.master[0x1f84][driver.id()].Read<uint32_t>(ec);
72 if (!ec) {
73 f = check_1000(value);
74 } else {
75 // If the expected device type is not available, read the device type from
76 // the remote object dictionary (object 1000:00).
77 f = AsyncRead<uint32_t>(0x1000, 0).then(
78 GetExecutor(), [check_1000](SdoFuture<uint32_t> f) {
79 return check_1000(f.get().value());
80 });
81 }
82 } else {
83 // This is not the first logical device. Read and copy the device type from
84 // object 67FF:00 (adjusted for logical device number) in the remote object
85 // dictionary.
86 f = read_67ff();
87 }
88 // Run OnConfig() after the device type has been obtained.
89 return f.then(GetExecutor(), [this](SdoFuture<void> f) {
90 // Throw an exception if an SDO error occurred.
91 f.get().value();
92 // Only invoke OnConfig() if the previous operations succeeded.
93 SdoPromise<void> p;
94 OnConfig([p](::std::error_code ec) mutable {
95 p.set(::std::make_exception_ptr(::std::system_error(ec, "OnConfig")));
96 });
97 return p.get_future();
98 });
99}
100
101SdoFuture<void>
102BasicLogicalDriver<BasicDriver>::AsyncDeconfig() {
103 SdoPromise<void> p;
104 // Post a task for OnDeconfig() to ensure this function does not block.
105 GetExecutor().post([this, p]() mutable {
106 OnDeconfig([p](::std::error_code ec) mutable {
107 p.set(::std::make_exception_ptr(::std::system_error(ec, "OnDeconfig")));
108 });
109 });
110 return p.get_future();
111}
112
113} // namespace canopen
114
115} // namespace lely
116
117#endif // !LELY_NO_COAPP_MASTER
This is the internal header file of the C++ CANopen application library.
This header file is part of the C++ CANopen application library; it contains the logical device drive...
SdoFuture< void > make_empty_sdo_future()
Returns an SDO future with a shared state that is immediately ready, containing a successful result o...
Definition: sdo.hpp:73