Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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 {
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
00133
00134
00135
00136
00137
00138
00139
00140
00141
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