master.cpp
Go to the documentation of this file.
00001 #include <canopen_master/master.h>
00002 #include <boost/interprocess/allocators/allocator.hpp>
00003 #include <boost/interprocess/containers/list.hpp>
00004 
00005 namespace can{
00006 std::size_t hash_value(can::Header const& h){ return (unsigned int)(h);}
00007 }
00008 
00009 using namespace canopen;
00010 
00011 void IPCSyncMaster::run() {
00012     boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock = sync_obj_->waiter.get_lock();
00013     boost::posix_time::ptime abs_time = boost::get_system_time();
00014     
00015     can::Frame frame(sync_obj_->properties.header_, sync_obj_->properties.overflow_ ? 1 : 0);
00016     while(true){
00017         abs_time += boost::posix_time::milliseconds(sync_obj_->properties.period_ms_);
00018         if(abs_time >= boost::get_system_time()){
00019             if(!sync_obj_->waiter.sync(abs_time)) LOG("Slave timeout");
00020 
00021             if(sync_obj_->nextSync(frame.data[0])){
00022                 interface_->send(frame);
00023             }
00024 
00025             boost::this_thread::sleep(abs_time);
00026         }
00027         
00028     }
00029 }
00030 
00031 
00032 void IPCSyncLayer::handleInit(LayerStatus &status) {
00033     boost::mutex::scoped_lock lock(mutex_);
00034     if(!nodes_.empty()){
00035         status.warn("Nodes list was not empty");
00036         nodes_.clear();
00037     }
00038     sync_master_->start(status);
00039 }
00040 
00041 // TODO: unify/combine
00042 
00043 boost::shared_ptr<SyncLayer> LocalMaster::getSync(const SyncProperties &p){
00044     boost::mutex::scoped_lock lock(mutex_);
00045     boost::unordered_map<can::Header, boost::shared_ptr<LocalIPCSyncMaster> >::iterator it = syncmasters_.find(p.header_);
00046     if(it == syncmasters_.end()){
00047         std::pair<boost::unordered_map<can::Header, boost::shared_ptr<LocalIPCSyncMaster> >::iterator, bool>
00048             res = syncmasters_.insert(std::make_pair(p.header_, boost::make_shared<LocalIPCSyncMaster>(p,interface_)));
00049         it = res.first;
00050     }else if(!it->second->matches(p)) return boost::shared_ptr<SyncLayer>();
00051     return boost::make_shared<IPCSyncLayer>(p, interface_, it->second);
00052 }
00053 
00054 boost::shared_ptr<SyncLayer> SharedMaster::getSync(const SyncProperties &p){
00055     boost::mutex::scoped_lock lock(mutex_);
00056     boost::unordered_map<can::Header, boost::shared_ptr<SharedIPCSyncMaster> >::iterator it = syncmasters_.find(p.header_);
00057     if(it == syncmasters_.end()){
00058         std::pair<boost::unordered_map<can::Header, boost::shared_ptr<SharedIPCSyncMaster> >::iterator, bool>
00059             res = syncmasters_.insert(std::make_pair(p.header_, boost::make_shared<SharedIPCSyncMaster>(boost::ref(managed_shm_), p,interface_)));
00060         it = res.first;
00061     }else if(!it->second->matches(p)) return boost::shared_ptr<SyncLayer>();
00062     return boost::make_shared<IPCSyncLayer>(p, interface_, it->second);
00063 }
00064 IPCSyncMaster::SyncObject * SharedIPCSyncMaster::getSyncObject(LayerStatus &status){
00065     typedef boost::interprocess::allocator<SyncObject, boost::interprocess::managed_shared_memory::segment_manager>  SyncAllocator;
00066     typedef boost::interprocess::list<SyncObject, SyncAllocator> SyncList;
00067     
00068     boost::interprocess::interprocess_mutex  *list_mutex = managed_shm_.find_or_construct<boost::interprocess::interprocess_mutex>("SyncListMutex")();
00069     
00070     if(!list_mutex){
00071         status.error("Could not find/construct SyncListMutex");
00072         return 0;
00073     }
00074     
00075     SyncList *synclist = managed_shm_.find_or_construct<SyncList>("SyncList")(managed_shm_.get_allocator<SyncAllocator>());
00076     
00077     if(!synclist){
00078         status.error("Could not find/construct SyncList");
00079         return 0;
00080     }
00081     
00082     
00083     SyncObject * sync_obj = 0;
00084 
00085     boost::posix_time::ptime abs_time = boost::get_system_time() + boost::posix_time::seconds(1);
00086         
00087     boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(*list_mutex, abs_time);
00088     if(!lock){
00089         status.error("Could not lock master mutex");
00090         return 0;
00091     }
00092     
00093     for(SyncList::iterator it = synclist->begin(); it != synclist->end(); ++it){
00094         if( it->properties.header_ == properties_.header_){
00095             
00096             if(it->properties.overflow_ != properties_.overflow_ || it->properties.period_ms_ != properties_.period_ms_){
00097                 status.error("sync properties mismatch");
00098                 return 0;
00099             }
00100             
00101             sync_obj = &(*it);
00102             break;
00103         }
00104     }
00105     if(!sync_obj) {
00106         synclist->emplace_back(properties_);
00107         sync_obj = &synclist->back();
00108     }
00109     return sync_obj;
00110 }


canopen_master
Author(s): Mathias L├╝dtke
autogenerated on Thu Jun 6 2019 20:43:54