11 static const unsigned int ID_MASK = (1u << 29)-1;
12 static const unsigned int EXTENDED_MASK = (1u << 29);
13 static const unsigned int NO_RTR_MASK = (1u << 30);
14 static const unsigned int INVALID_MASK = (1u << 31);
20 return can::Header(value_ & ID_MASK, value_ & EXTENDED_MASK, fill_rtr && !(value_ & NO_RTR_MASK),
false);
22 bool isInvalid()
const {
return value_ & INVALID_MASK; }
31 sub_index((val>>8) & 0xFF),
52 bool com_changed =
false;
55 for(uint8_t sub = 0; sub <=6 ; ++sub){
57 if(!dict(com_id,sub).init_val.is_empty()){
62 catch (std::out_of_range) {}
68 bool map_changed =
false;
72 for(uint8_t sub = 1; sub <=num ; ++sub){
74 if(!dict(map_index,sub).init_val.is_empty()){
79 catch (std::out_of_range) {}
82 map_changed = dict( map_index ,0 ).init_val.is_empty();
108 if((map_changed || com_changed) && cob_id.
desc().
writable){
111 if(map_num > 0 && map_num <= 0x40){
117 for(uint8_t sub = 1; sub <=map_num; ++sub){
119 storage->entry(mapentry, map_index, sub);
120 const HoldAny init = dict(map_index ,sub).init_val;
125 if(param.index < 0x1000){
132 rd = std::bind<void(Buffer::*)(const canopen::ObjectDict::Entry&, String&)>(&Buffer::read, b.get(), std::placeholders::_1, std::placeholders::_2);
136 wd = std::bind<void(Buffer::*)(const canopen::ObjectDict::Entry&, const String&)>(&Buffer::write, b.get(), std::placeholders::_1, std::placeholders::_2);
137 size_t l = storage->map(param.index, param.sub_index, rd, wd);
138 assert(l == param.length/8);
142 frame.dlc += b->size;
143 assert( frame.dlc <= 8 );
145 buffers.push_back(b);
149 uint8_t subs = dict(com_index,
SUB_COM_NUM).value().
get<uint8_t>();
155 catch (
const std::out_of_range &){
161 num_entry.
set(map_num);
163 if((com_changed || map_changed) && cob_id.
desc().
writable){
172 :interface_(interface)
176 boost::mutex::scoped_lock lock(
mutex_);
205 catch(
const std::out_of_range &e){
206 status.
error(std::string(
"PDO error: ") + e.what());
213 boost::mutex::scoped_lock lock(mutex);
216 parse_and_set_mapping(storage, com_index, map_index,
true,
false);
220 if(buffers.empty() || pdoid.
isInvalid()){
224 frame = pdoid.
header(
true);
234 boost::mutex::scoped_lock lock(mutex);
241 parse_and_set_mapping(storage, com_index, map_index,
false,
true);
242 if(buffers.empty() || pdoid.
isInvalid()){
249 if(transmission_type != 1 && transmission_type <=240){
256 boost::mutex::scoped_lock lock(mutex);
258 bool updated =
false;
259 size_t len = frame.dlc;
261 for(std::vector< BufferSharedPtr >::iterator b_it = buffers.begin(); b_it != buffers.end(); ++b_it){
264 updated = b.
read(dest, len) || updated;
283 boost::mutex::scoped_lock lock(mutex);
284 if((transmission_type >= 1 && transmission_type <= 240) || transmission_type == 0xFC){
287 }
else if(timeout == 0) {
288 status.
warn(
"RPDO timeout");
291 if(transmission_type == 0xFC || transmission_type == 0xFD){
300 const uint8_t * src = msg.
data.data();
301 for(std::vector<BufferSharedPtr >::iterator it = buffers.begin(); it != buffers.end(); ++it){
304 if( offset + b.
size <= msg.
dlc ){
311 if( offset != msg.
dlc ){
315 boost::mutex::scoped_lock lock(mutex);
316 if(transmission_type >= 1 && transmission_type <= 240){
317 timeout = transmission_type + 2;
318 }
else if(transmission_type == 0xFC || transmission_type == 0xFD){
327 boost::mutex::scoped_lock lock(
mutex_);
328 for(std::unordered_set<RPDO::RPDOSharedPtr >::iterator it =
rpdos_.begin(); it !=
rpdos_.end(); ++it){
333 boost::mutex::scoped_lock lock(
mutex_);
334 for(std::unordered_set<TPDO::TPDOSharedPtr >::iterator it =
tpdos_.begin(); it !=
tpdos_.end(); ++it){
341 boost::mutex::scoped_lock lock(mutex);
343 BOOST_THROW_EXCEPTION( std::bad_cast() );
345 if(empty)
return false;
347 memcpy(b,&buffer[0], size);
348 bool was_dirty = dirty;
353 boost::mutex::scoped_lock lock(mutex);
355 BOOST_THROW_EXCEPTION( std::bad_cast() );
359 memcpy(&buffer[0], b, size);
362 boost::mutex::scoped_lock lock(mutex);
364 if(size != data.size()){
371 data.assign(buffer.begin(), buffer.end());
376 boost::mutex::scoped_lock lock(mutex);
377 if(size != data.size()){
382 buffer.assign(data.begin(),data.end());
static RPDOSharedPtr create(const can::CommInterfaceSharedPtr interface, const ObjectStorageSharedPtr &storage, const uint16_t &com_index, const uint16_t &map_index)
std::array< value_type, 8 > data
bool init(const ObjectStorageSharedPtr storage, LayerStatus &status)
bool check_map_changed(const uint8_t &num, const ObjectDict &dict, const uint16_t &map_index)
bool read(uint8_t *b, const size_t len)
bool check_com_changed(const ObjectDict &dict, const uint16_t com_id)
std::unordered_set< TPDO::TPDOSharedPtr > tpdos_
const uint16_t RPDO_COM_BASE
std::shared_ptr< TPDO > TPDOSharedPtr
const uint8_t SUB_COM_NUM
PDOid(const uint32_t &val)
const void warn(const std::string &r)
std::shared_ptr< RPDO > RPDOSharedPtr
const EntryConstSharedPtr & get(const Key &k) const
const uint8_t SUB_MAP_NUM
const uint16_t TPDO_MAP_BASE
std::unordered_set< RPDO::RPDOSharedPtr > rpdos_
const HoldAny & value() const
const uint16_t RPDO_MAP_BASE
PDOMapper(const can::CommInterfaceSharedPtr interface)
boost::chrono::high_resolution_clock::time_point time_point
std::shared_ptr< CommInterface > CommInterfaceSharedPtr
std::shared_ptr< Buffer > BufferSharedPtr
void read(LayerStatus &status)
void sync(LayerStatus &status)
void write(const uint8_t *b, const size_t len)
bool init(const ObjectStorageSharedPtr &storage, const uint16_t &com_index, const uint16_t &map_index)
static const unsigned int INVALID_MASK
can::Header header(bool fill_rtr=false) const
const uint8_t SUB_COM_TRANSMISSION_TYPE
bool has(uint16_t i, uint8_t s) const
const can::CommInterfaceSharedPtr interface_
const ObjectDict::Entry & desc() const
static TPDOSharedPtr create(const can::CommInterfaceSharedPtr interface, const ObjectStorageSharedPtr &storage, const uint16_t &com_index, const uint16_t &map_index)
const uint16_t TPDO_COM_BASE
const DeviceInfo device_info
const void error(const std::string &r)
bool init(const ObjectStorageSharedPtr &storage, const uint16_t &com_index, const uint16_t &map_index)
#define THROW_WITH_KEY(e, k)
time_point get_abs_time(const time_duration &timeout)
void parse_and_set_mapping(const ObjectStorageSharedPtr &storage, const uint16_t &com_index, const uint16_t &map_index, const bool &read, const bool &write)
std::function< void(const ObjectDict::Entry &, const String &)> WriteFunc
ObjectStorage::ObjectStorageSharedPtr ObjectStorageSharedPtr
const uint8_t SUB_COM_RESERVED
std::function< void(const ObjectDict::Entry &, String &)> ReadFunc
void handleFrame(const can::Frame &msg)
const uint8_t SUB_COM_COB_ID