00001 #include "RTCANController.hpp"
00002
00003 #include <rtt/Logger.hpp>
00004
00005 #include <rtdm/rtcan.h>
00006
00007
00008 #define INVALID -1
00009
00010 struct RTCANControllerPrivate
00011 {
00012
00013
00014 int fd;
00015
00016 struct ifreq ifr;
00017
00018 struct sockaddr_can addr;
00019 bool exit;
00020 RTT::CAN::CANMessage msg;
00021
00022 RTT::CAN::CANBusInterface * mbus;
00023
00024
00025 unsigned int total_TX;
00026
00027 unsigned int total_RX;
00028
00029 unsigned int failed_TX;
00030
00031 unsigned int failed_RX;
00032 };
00033
00034 namespace RTT
00035 {
00036 namespace CAN
00037 {
00038
00039 RTCANController::RTCANController(int priority, std::string dev_name, int timeout)
00040 : NonPeriodicActivity(ORO_SCHED_RT, priority),
00041 d(new RTCANControllerPrivate)
00042 {
00043 int ifindex;
00044 int ret;
00045 nanosecs_rel_t rxtimeout = timeout * 1000000;
00046
00047 Logger::In in("RTCANController");
00048
00049 log(Info) << "Trying to open " << dev_name << endlog();
00050 d->fd = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW);
00051 if (d->fd < 0)
00052 {
00053 log(Error) << dev_name << ": failed. Could not open device."
00054 << endlog();
00055 }
00056 else
00057 {
00058 strcpy(d->ifr.ifr_name, dev_name.c_str());
00059
00060 ret = rt_dev_ioctl(d->fd, SIOCGIFINDEX,
00061 &d->ifr);
00062 if (ret < 0)
00063 log(Error) << dev_name
00064 << ": failed. Unable to find CAN interface. "
00065 << endlog();
00066 ifindex = d->ifr.ifr_ifindex;
00067
00068 d->addr.can_family = AF_CAN;
00069 d->addr.can_ifindex = ifindex;
00070
00071 ret = rt_dev_bind(d->fd,
00072 (struct sockaddr *) &d->addr,
00073 sizeof(struct sockaddr_can));
00074 if (ret < 0)
00075 log(Error) << dev_name
00076 << ": failed. Could not bind to device." << ret
00077 << endlog();
00078
00079
00080 ret = rt_dev_ioctl(d->fd, RTCAN_RTIOC_RCV_TIMEOUT, &rxtimeout);
00081 if (ret < 0)
00082 log(Error) << dev_name << ": failed. Could not enable timeout for RX CAN messages." << endlog();
00083 }
00084 }
00085
00086 RTCANController::~RTCANController()
00087 {
00088 Logger::In in("RTCANController");
00089
00090
00091 this->stop();
00092
00093
00094 if (d->fd >= 0)
00095 {
00096 rt_dev_close(d->fd);
00097 d->fd = INVALID;
00098 }
00099
00100
00101 delete (d);
00102
00103 }
00104
00105 bool RTCANController::initialize()
00106 {
00107 Logger::In in("RTCANController");
00108
00109 log(Info) << "Initialize CAN device" << endlog();
00110 if (d->fd < 0)
00111 return false;
00112
00113 d->exit = false;
00114
00115 d->total_RX = d->total_TX = 0;
00116 d->failed_RX = d->failed_TX = 0;
00117
00118 return true;
00119 }
00120
00121 void RTCANController::loop()
00122 {
00123 Logger::In in("RTCANController");
00124
00125 log(Info) << "Start loop" << endlog();
00126 while (!d->exit)
00127 {
00128 this->readFromBuffer();
00129 }
00130 }
00131
00132 bool RTCANController::breakLoop()
00133 {
00134 d->exit = true;
00135 return true;
00136 }
00137
00138 void RTCANController::finalize()
00139 {
00140 Logger::In in("RTCANController");
00141
00142 log(Info) << "RTCAN Controller stopped. Last run statistics :"
00143 << endlog();
00144 log(Info) << " Total Received : " << d->total_RX
00145 << ". Failed to Receive : " << d->failed_RX
00146 << endlog();
00147 log(Info) << " Total Transmitted : " << d->total_TX
00148 << ". Failed to Transmit : " << d->failed_TX
00149 << endlog();
00150 d->total_RX = d->failed_RX
00151 = d->total_TX = d->failed_TX = 0;
00152 }
00153
00154 void RTCANController::addBus(CANBusInterface* bus)
00155 {
00156 Logger::In in("RTCANController");
00157
00158 if(bus == NULL)
00159 log(Error) << "Can not add CANBus, CANBusInterface is not valid!" << endlog();
00160 else {
00161 d->mbus = bus;
00162 bus->setController(this);
00163 }
00164 }
00165
00166 void RTCANController::process(const CANMessage* msg)
00167 {
00168 Logger::In in("RTCANController");
00169
00170 int ret = 0;
00171
00172
00173 struct can_frame frame;
00174 for (unsigned int i = 0; i < msg->getDLC(); i++)
00175 frame.data[i] = msg->getData(i);
00176
00177
00178 frame.can_dlc = msg->getDLC();
00179
00180
00181 if (msg->isExtended())
00182 frame.can_id = msg->getExtId() | CAN_EFF_FLAG;
00183 else
00184
00185 frame.can_id = msg->getStdId();
00186
00187 if (msg->isRemote())
00188 frame.can_id = CAN_RTR_FLAG;
00189
00190
00191 ret = rt_dev_send(d->fd, &frame, sizeof(can_frame),
00192 MSG_DONTWAIT);
00193 if (ret > 0)
00194 d->total_TX++;
00195 else if (ret < 0)
00196 d->failed_TX++;
00197
00198 }
00199
00200 bool RTCANController::readFromBuffer()
00201 {
00202 Logger::In in("RTCANController");
00203
00204 struct can_frame frame;
00205 struct sockaddr_can addr;
00206 socklen_t addrlen = sizeof(addr);
00207 int ret;
00208
00209 if(d->mbus == NULL) {
00210 log(Error) << "No CANBus added! Use RTCANController::addBus "
00211 << "else received CAN messages on the device will be lost." << endlog();
00212 return false;
00213 }
00214
00215 ret = rt_dev_recvfrom(d->fd, (void *) &frame, sizeof(can_frame_t), 0,
00216 (struct sockaddr *) &addr, &addrlen);
00217 if (ret > 0)
00218 {
00219 d->msg.clear();
00220
00221 d->msg.setDLC(frame.can_dlc);
00222
00223 if (frame.can_id == CAN_RTR_FLAG)
00224 d->msg.setRemote();
00225
00226 if ((frame.can_id & CAN_EFF_MASK) > CAN_SFF_MASK)
00227 d->msg.setExtId(frame.can_id);
00228 else
00229
00230 d->msg.setStdId(frame.can_id);
00231
00232 for (unsigned int i = 0; i < d->msg.getDLC(); i++)
00233 d->msg.setData(i, frame.data[i]);
00234
00235 #if 0
00236 log(Debug) << "Receiving CAN Message: Id=";
00237 if (d->msg.isStandard())
00238 log(Debug) << d->msg.getStdId();
00239 else
00240 log(Debug) << d->msg.getExtId();
00241 log(Debug) << ", DLC=" << d->msg.getDLC() << ", DATA = ";
00242 for (unsigned int i=0; i < d->msg.getDLC(); i++)
00243 log(Debug) << (unsigned int) d->msg.getData(i) << " ";
00244 log(Debug) << endlog();
00245 #endif
00246
00247 d->msg.origin = this;
00248 d->mbus->write(&d->msg);
00249 d->total_RX++;
00250 }
00251 else if (ret == -ETIMEDOUT) { }
00252 else
00253 d->failed_RX++;
00254
00255 return true;
00256 }
00257
00258 }
00259 }