Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Thu Oct 22 11:59:08 CEST 2009 IRQActivity.cpp 00003 00004 IRQActivity.cpp - description 00005 ------------------- 00006 begin : Thu October 22 2009 00007 copyright : (C) 2009 Peter Soetens 00008 email : peter@thesourcworks.com 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 #include "IRQActivity.hpp" 00040 #include "../ExecutionEngine.hpp" 00041 #include "../base/TaskCore.hpp" 00042 #include "../Logger.hpp" 00043 00044 #include <iostream> 00045 00046 using namespace RTT; 00047 using namespace extras; 00048 using namespace base; 00049 00050 IRQActivity::IRQActivity(int priority, RunnableInterface* _r, const std::string& name ) 00051 : Activity(priority, 0.0, _r, name) 00052 , m_irq(-1) 00053 , m_runner(_r) {} 00054 00055 IRQActivity::IRQActivity(int scheduler, int priority, RunnableInterface* _r, const std::string& name ) 00056 : Activity(scheduler, priority, 0.0, _r, name) 00057 , m_irq(-1) 00058 , m_runner(_r) {} 00059 00060 IRQActivity::~IRQActivity() 00061 { 00062 stop(); 00063 } 00064 00065 int IRQActivity::getIRQ() const { return m_irq; } 00066 void IRQActivity::setIRQ(int irq) { m_irq = irq; } 00067 00068 #ifndef OROPKG_OS_XENOMAI 00069 bool IRQActivity::start() { 00070 Logger::log() << Logger::Error << "IRQActivity is only usable on Xenomai" << Logger::endl; 00071 return false; 00072 } 00073 #else 00074 00075 #include <sys/select.h> 00076 #include <unistd.h> 00077 00078 bool IRQActivity::start() 00079 { 00080 if (m_irq == -1) 00081 { // no FD explicitely set. Try to find one. 00082 ExecutionEngine* engine = dynamic_cast<ExecutionEngine*>(m_runner); 00083 if (engine) 00084 { 00085 Provider* provider = dynamic_cast<Provider*>(engine->getParent()); 00086 if (provider) 00087 m_irq = provider->getIRQ(); 00088 } 00089 } 00090 00091 if (m_irq == -1) 00092 { 00093 Logger::log() << Logger::Error << "no IRQ set for IRQActivity" << Logger::endl; 00094 return false; 00095 } 00096 00097 char name[20]; 00098 if (snprintf(name, 20, "IRQActivity%d", m_irq) >= 20) 00099 { 00100 Logger::log() << Logger::Error << "something is wrong with m_irq. Are you trying to do a buffer overflow ?" << strerror(errno) << Logger::endl; 00101 return false; 00102 } 00103 00104 int ret = rt_intr_create(&m_handle, name, m_irq, 0); 00105 if (ret != 0) 00106 { 00107 Logger::log() << Logger::Error << "cannot create interrupt object for IRQ " << m_irq << ": " << strerror(-ret) << Logger::endl; 00108 return false; 00109 } 00110 00111 if (! Activity::start()) 00112 { 00113 rt_intr_delete(&m_handle); 00114 return false; 00115 } 00116 00117 return true; 00118 } 00119 00120 void IRQActivity::loop() 00121 { 00122 if (m_irq == -1) 00123 return; 00124 00125 while(true) 00126 { 00127 if (rt_intr_wait(&m_handle, TM_INFINITE) > 0) 00128 step(); 00129 else 00130 break; 00131 // { 00132 // sleep(1); 00133 // if (errno == -EIDRM) // interrupt handler has been deleted 00134 // break; 00135 // else 00136 // { 00137 // std::cout << "ERROR " << errno << std::endl; 00138 // break; 00139 // } 00140 // } 00141 // step(); 00142 } 00143 } 00144 00145 bool IRQActivity::breakLoop() 00146 { 00147 rt_intr_delete(&m_handle); 00148 return true; 00149 } 00150 00151 void IRQActivity::step() 00152 { 00153 if (m_runner != 0) 00154 m_runner->step(); 00155 } 00156 00157 #endif // OS is xenomai 00158