CAN.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. /*
  14. * Many thanks to members of the UAVCAN project:
  15. * Pavel Kirienko <pavel.kirienko@gmail.com>
  16. * Ilia Sheremet <illia.sheremet@gmail.com>
  17. *
  18. * license info can be found in the uavcan submodule located:
  19. * modules/uavcan/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp
  20. */
  21. #include <AP_HAL/AP_HAL.h>
  22. #include <AP_HAL/system.h>
  23. #include <AP_BoardConfig/AP_BoardConfig.h>
  24. #if HAL_WITH_UAVCAN
  25. #include "CAN.h"
  26. #include <unistd.h>
  27. #include <fcntl.h>
  28. #include <sys/socket.h>
  29. #include <sys/ioctl.h>
  30. #include <net/if.h>
  31. #include <linux/can/raw.h>
  32. extern const AP_HAL::HAL& hal;
  33. using namespace Linux;
  34. uavcan::MonotonicTime getMonotonic()
  35. {
  36. return uavcan::MonotonicTime::fromUSec(AP_HAL::micros64());
  37. }
  38. static can_frame makeSocketCanFrame(const uavcan::CanFrame& uavcan_frame)
  39. {
  40. can_frame sockcan_frame { uavcan_frame.id& uavcan::CanFrame::MaskExtID, uavcan_frame.dlc, { } };
  41. std::copy(uavcan_frame.data, uavcan_frame.data + uavcan_frame.dlc, sockcan_frame.data);
  42. if (uavcan_frame.isExtended()) {
  43. sockcan_frame.can_id |= CAN_EFF_FLAG;
  44. }
  45. if (uavcan_frame.isErrorFrame()) {
  46. sockcan_frame.can_id |= CAN_ERR_FLAG;
  47. }
  48. if (uavcan_frame.isRemoteTransmissionRequest()) {
  49. sockcan_frame.can_id |= CAN_RTR_FLAG;
  50. }
  51. return sockcan_frame;
  52. }
  53. static uavcan::CanFrame makeUavcanFrame(const can_frame& sockcan_frame)
  54. {
  55. uavcan::CanFrame uavcan_frame(sockcan_frame.can_id & CAN_EFF_MASK, sockcan_frame.data, sockcan_frame.can_dlc);
  56. if (sockcan_frame.can_id & CAN_EFF_FLAG) {
  57. uavcan_frame.id |= uavcan::CanFrame::FlagEFF;
  58. }
  59. if (sockcan_frame.can_id & CAN_ERR_FLAG) {
  60. uavcan_frame.id |= uavcan::CanFrame::FlagERR;
  61. }
  62. if (sockcan_frame.can_id & CAN_RTR_FLAG) {
  63. uavcan_frame.id |= uavcan::CanFrame::FlagRTR;
  64. }
  65. return uavcan_frame;
  66. }
  67. bool CAN::begin(uint32_t bitrate)
  68. {
  69. if (_initialized) {
  70. return _initialized;
  71. }
  72. // TODO: Add possibility change bitrate
  73. _fd = openSocket(HAL_BOARD_CAN_IFACE_NAME);
  74. if (_fd > 0) {
  75. _bitrate = bitrate;
  76. _initialized = true;
  77. } else {
  78. _initialized = false;
  79. }
  80. return _initialized;
  81. }
  82. void CAN::reset()
  83. {
  84. if (_initialized && _bitrate != 0) {
  85. close(_fd);
  86. begin(_bitrate);
  87. }
  88. }
  89. void CAN::end()
  90. {
  91. _initialized = false;
  92. close(_fd);
  93. }
  94. bool CAN::is_initialized()
  95. {
  96. return _initialized;
  97. }
  98. int32_t CAN::tx_pending()
  99. {
  100. if (_initialized) {
  101. return _tx_queue.size();
  102. } else {
  103. return -1;
  104. }
  105. }
  106. int32_t CAN::available()
  107. {
  108. if (_initialized) {
  109. return _rx_queue.size();
  110. } else {
  111. return -1;
  112. }
  113. }
  114. int CAN::openSocket(const std::string& iface_name)
  115. {
  116. errno = 0;
  117. int s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
  118. if (s < 0) {
  119. return s;
  120. }
  121. std::shared_ptr<void> defer(&s, [](int* fd) { if (*fd >= 0) close(*fd); });
  122. const int ret = s;
  123. // Detect the iface index
  124. auto ifr = ifreq();
  125. if (iface_name.length() >= IFNAMSIZ) {
  126. errno = ENAMETOOLONG;
  127. return -1;
  128. }
  129. std::strncpy(ifr.ifr_name, iface_name.c_str(), iface_name.length());
  130. if (ioctl(s, SIOCGIFINDEX, &ifr) < 0 || ifr.ifr_ifindex < 0) {
  131. return -1;
  132. }
  133. // Bind to the specified CAN iface
  134. {
  135. auto addr = sockaddr_can();
  136. addr.can_family = AF_CAN;
  137. addr.can_ifindex = ifr.ifr_ifindex;
  138. if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
  139. return -1;
  140. }
  141. }
  142. // Configure
  143. {
  144. const int on = 1;
  145. // Timestamping
  146. if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0) {
  147. return -1;
  148. }
  149. // Socket loopback
  150. if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &on, sizeof(on)) < 0) {
  151. return -1;
  152. }
  153. // Non-blocking
  154. if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
  155. return -1;
  156. }
  157. }
  158. // Validate the resulting socket
  159. {
  160. int socket_error = 0;
  161. socklen_t errlen = sizeof(socket_error);
  162. getsockopt(s, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&socket_error), &errlen);
  163. if (socket_error != 0) {
  164. errno = socket_error;
  165. return -1;
  166. }
  167. }
  168. s = -1;
  169. return ret;
  170. }
  171. int16_t CAN::send(const uavcan::CanFrame& frame, const uavcan::MonotonicTime tx_deadline,
  172. const uavcan::CanIOFlags flags)
  173. {
  174. _tx_queue.emplace(frame, tx_deadline, flags, _tx_frame_counter);
  175. _tx_frame_counter++;
  176. _pollRead(); // Read poll is necessary because it can release the pending TX flag
  177. _pollWrite();
  178. return 1;
  179. }
  180. int16_t CAN::receive(uavcan::CanFrame& out_frame, uavcan::MonotonicTime& out_ts_monotonic,
  181. uavcan::UtcTime& out_ts_utc, uavcan::CanIOFlags& out_flags)
  182. {
  183. if (_rx_queue.empty()) {
  184. _pollRead(); // This allows to use the socket not calling poll() explicitly.
  185. if (_rx_queue.empty()) {
  186. return 0;
  187. }
  188. }
  189. {
  190. const RxItem& rx = _rx_queue.front();
  191. out_frame = rx.frame;
  192. out_ts_monotonic = rx.ts_mono;
  193. out_ts_utc = rx.ts_utc;
  194. out_flags = rx.flags;
  195. }
  196. _rx_queue.pop();
  197. return 1;
  198. }
  199. bool CAN::hasReadyTx() const
  200. {
  201. return !_tx_queue.empty() && (_frames_in_socket_tx_queue < _max_frames_in_socket_tx_queue);
  202. }
  203. bool CAN::hasReadyRx() const
  204. {
  205. return !_rx_queue.empty();
  206. }
  207. void CAN::poll(bool read, bool write)
  208. {
  209. if (read) {
  210. _pollRead(); // Read poll must be executed first because it may decrement _frames_in_socket_tx_queue
  211. }
  212. if (write) {
  213. _pollWrite();
  214. }
  215. }
  216. int16_t CAN::configureFilters(const uavcan::CanFilterConfig* const filter_configs,
  217. const std::uint16_t num_configs)
  218. {
  219. if (filter_configs == nullptr) {
  220. return -1;
  221. }
  222. _hw_filters_container.clear();
  223. _hw_filters_container.resize(num_configs);
  224. for (unsigned i = 0; i < num_configs; i++) {
  225. const uavcan::CanFilterConfig& fc = filter_configs[i];
  226. _hw_filters_container[i].can_id = fc.id & uavcan::CanFrame::MaskExtID;
  227. _hw_filters_container[i].can_mask = fc.mask & uavcan::CanFrame::MaskExtID;
  228. if (fc.id & uavcan::CanFrame::FlagEFF) {
  229. _hw_filters_container[i].can_id |= CAN_EFF_FLAG;
  230. }
  231. if (fc.id & uavcan::CanFrame::FlagRTR) {
  232. _hw_filters_container[i].can_id |= CAN_RTR_FLAG;
  233. }
  234. if (fc.mask & uavcan::CanFrame::FlagEFF) {
  235. _hw_filters_container[i].can_mask |= CAN_EFF_FLAG;
  236. }
  237. if (fc.mask & uavcan::CanFrame::FlagRTR) {
  238. _hw_filters_container[i].can_mask |= CAN_RTR_FLAG;
  239. }
  240. }
  241. return 0;
  242. }
  243. /**
  244. * SocketCAN emulates the CAN filters in software, so the number of filters is virtually unlimited.
  245. * This method returns a constant value.
  246. */
  247. static constexpr unsigned NumFilters = CAN_FILTER_NUMBER;
  248. uint16_t CAN::getNumFilters() const { return NumFilters; }
  249. uint64_t CAN::getErrorCount() const
  250. {
  251. uint64_t ec = 0;
  252. for (auto& kv : _errors) { ec += kv.second; }
  253. return ec;
  254. }
  255. void CAN::_pollWrite()
  256. {
  257. while (hasReadyTx()) {
  258. const TxItem tx = _tx_queue.top();
  259. if (tx.deadline >= getMonotonic()) {
  260. const int res = _write(tx.frame);
  261. if (res == 1) { // Transmitted successfully
  262. _incrementNumFramesInSocketTxQueue();
  263. if (tx.flags & uavcan::CanIOFlagLoopback) {
  264. _pending_loopback_ids.insert(tx.frame.id);
  265. }
  266. } else if (res == 0) { // Not transmitted, nor is it an error
  267. break; // Leaving the loop, the frame remains enqueued for the next retry
  268. } else { // Transmission error
  269. _registerError(SocketCanError::SocketWriteFailure);
  270. }
  271. } else {
  272. _registerError(SocketCanError::TxTimeout);
  273. }
  274. // Removing the frame from the queue even if transmission failed
  275. _tx_queue.pop();
  276. }
  277. }
  278. void CAN::_pollRead()
  279. {
  280. uint8_t iterations_count = 0;
  281. while (iterations_count < CAN_MAX_POLL_ITERATIONS_COUNT)
  282. {
  283. iterations_count++;
  284. RxItem rx;
  285. rx.ts_mono = getMonotonic(); // Monotonic timestamp is not required to be precise (unlike UTC)
  286. bool loopback = false;
  287. const int res = _read(rx.frame, rx.ts_utc, loopback);
  288. if (res == 1) {
  289. bool accept = true;
  290. if (loopback) { // We receive loopback for all CAN frames
  291. _confirmSentFrame();
  292. rx.flags |= uavcan::CanIOFlagLoopback;
  293. accept = _wasInPendingLoopbackSet(rx.frame);
  294. }
  295. if (accept) {
  296. _rx_queue.push(rx);
  297. }
  298. } else if (res == 0) {
  299. break;
  300. } else {
  301. _registerError(SocketCanError::SocketReadFailure);
  302. break;
  303. }
  304. }
  305. }
  306. int CAN::_write(const uavcan::CanFrame& frame) const
  307. {
  308. errno = 0;
  309. const can_frame sockcan_frame = makeSocketCanFrame(frame);
  310. const int res = write(_fd, &sockcan_frame, sizeof(sockcan_frame));
  311. if (res <= 0) {
  312. if (errno == ENOBUFS || errno == EAGAIN) { // Writing is not possible atm, not an error
  313. return 0;
  314. }
  315. return res;
  316. }
  317. if (res != sizeof(sockcan_frame)) {
  318. return -1;
  319. }
  320. return 1;
  321. }
  322. int CAN::_read(uavcan::CanFrame& frame, uavcan::UtcTime& ts_utc, bool& loopback) const
  323. {
  324. auto iov = iovec();
  325. auto sockcan_frame = can_frame();
  326. iov.iov_base = &sockcan_frame;
  327. iov.iov_len = sizeof(sockcan_frame);
  328. union {
  329. uint8_t data[CMSG_SPACE(sizeof(::timeval))];
  330. struct cmsghdr align;
  331. } control;
  332. auto msg = msghdr();
  333. msg.msg_iov = &iov;
  334. msg.msg_iovlen = 1;
  335. msg.msg_control = control.data;
  336. msg.msg_controllen = sizeof(control.data);
  337. const int res = recvmsg(_fd, &msg, MSG_DONTWAIT);
  338. if (res <= 0) {
  339. return (res < 0 && errno == EWOULDBLOCK) ? 0 : res;
  340. }
  341. /*
  342. * Flags
  343. */
  344. loopback = (msg.msg_flags & static_cast<int>(MSG_CONFIRM)) != 0;
  345. if (!loopback && !_checkHWFilters(sockcan_frame)) {
  346. return 0;
  347. }
  348. frame = makeUavcanFrame(sockcan_frame);
  349. /*
  350. * Timestamp
  351. */
  352. const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
  353. if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
  354. auto tv = timeval();
  355. std::memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv)); // Copy to avoid alignment problems
  356. ts_utc = uavcan::UtcTime::fromUSec(std::uint64_t(tv.tv_sec) * 1000000ULL + tv.tv_usec);
  357. } else {
  358. return -1;
  359. }
  360. return 1;
  361. }
  362. void CAN::_incrementNumFramesInSocketTxQueue()
  363. {
  364. _frames_in_socket_tx_queue++;
  365. }
  366. void CAN::_confirmSentFrame()
  367. {
  368. if (_frames_in_socket_tx_queue > 0) {
  369. _frames_in_socket_tx_queue--;
  370. }
  371. }
  372. bool CAN::_wasInPendingLoopbackSet(const uavcan::CanFrame& frame)
  373. {
  374. if (_pending_loopback_ids.count(frame.id) > 0) {
  375. _pending_loopback_ids.erase(frame.id);
  376. return true;
  377. }
  378. return false;
  379. }
  380. bool CAN::_checkHWFilters(const can_frame& frame) const
  381. {
  382. if (!_hw_filters_container.empty()) {
  383. for (auto& f : _hw_filters_container) {
  384. if (((frame.can_id & f.can_mask) ^ f.can_id) == 0) {
  385. return true;
  386. }
  387. }
  388. return false;
  389. } else {
  390. return true;
  391. }
  392. }
  393. void CANManager::IfaceWrapper::updateDownStatusFromPollResult(const pollfd& pfd)
  394. {
  395. if (!_down&& (pfd.revents & POLLERR)) {
  396. int error = 0;
  397. socklen_t errlen = sizeof(error);
  398. getsockopt(pfd.fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&error), &errlen);
  399. _down= error == ENETDOWN || error == ENODEV;
  400. hal.console->printf("Iface %d is dead; error %d", this->getFileDescriptor(), error);
  401. }
  402. }
  403. bool CANManager::begin(uint32_t bitrate, uint8_t can_number)
  404. {
  405. if (init(can_number) >= 0) {
  406. _initialized = true;
  407. }
  408. return _initialized;
  409. }
  410. bool CANManager::is_initialized()
  411. {
  412. return _initialized;
  413. }
  414. void CANManager::initialized(bool val)
  415. {
  416. _initialized = val;
  417. }
  418. CAN* CANManager::getIface(uint8_t iface_index)
  419. {
  420. return (iface_index >= _ifaces.size()) ? nullptr : _ifaces[iface_index].get();
  421. }
  422. int CANManager::init(uint8_t can_number)
  423. {
  424. int res = -1;
  425. char iface_name[16];
  426. sprintf(iface_name, "can%u", can_number);
  427. res = addIface(iface_name);
  428. if (res < 0) {
  429. hal.console->printf("CANManager: init %s failed\n", iface_name);
  430. }
  431. return res;
  432. }
  433. int16_t CANManager::select(uavcan::CanSelectMasks& inout_masks,
  434. const uavcan::CanFrame* (&)[uavcan::MaxCanIfaces],
  435. uavcan::MonotonicTime blocking_deadline)
  436. {
  437. // Detecting whether we need to block at all
  438. bool need_block = (inout_masks.write == 0); // Write queue is infinite
  439. for (unsigned i = 0; need_block && (i < _ifaces.size()); i++) {
  440. const bool need_read = inout_masks.read & (1 << i);
  441. if (need_read && _ifaces[i]->hasReadyRx()) {
  442. need_block = false;
  443. }
  444. }
  445. if (need_block) {
  446. // Poll FD set setup
  447. pollfd pollfds[uavcan::MaxCanIfaces] = {};
  448. unsigned num_pollfds = 0;
  449. IfaceWrapper* pollfd_index_to_iface[uavcan::MaxCanIfaces] = {};
  450. for (unsigned i = 0; i < _ifaces.size(); i++) {
  451. if (_ifaces[i]->isDown()) {
  452. continue;
  453. }
  454. pollfds[num_pollfds].fd = _ifaces[i]->getFileDescriptor();
  455. pollfds[num_pollfds].events = POLLIN;
  456. if (_ifaces[i]->hasReadyTx() || (inout_masks.write & (1U << i))) {
  457. pollfds[num_pollfds].events |= POLLOUT;
  458. }
  459. pollfd_index_to_iface[num_pollfds] = _ifaces[i].get();
  460. num_pollfds++;
  461. }
  462. if (num_pollfds == 0) {
  463. return 0;
  464. }
  465. // Timeout conversion
  466. const std::int64_t timeout_usec = (blocking_deadline - getMonotonic()).toUSec();
  467. auto ts = timespec();
  468. if (timeout_usec > 0) {
  469. ts.tv_sec = timeout_usec / 1000000LL;
  470. ts.tv_nsec = (timeout_usec % 1000000LL) * 1000;
  471. }
  472. // Blocking here
  473. const int res = ppoll(pollfds, num_pollfds, &ts, nullptr);
  474. if (res < 0) {
  475. return res;
  476. }
  477. // Handling poll output
  478. for (unsigned i = 0; i < num_pollfds; i++) {
  479. pollfd_index_to_iface[i]->updateDownStatusFromPollResult(pollfds[i]);
  480. const bool poll_read = pollfds[i].revents & POLLIN;
  481. const bool poll_write = pollfds[i].revents & POLLOUT;
  482. pollfd_index_to_iface[i]->poll(poll_read, poll_write);
  483. }
  484. }
  485. // Writing the output masks
  486. inout_masks = uavcan::CanSelectMasks();
  487. for (unsigned i = 0; i < _ifaces.size(); i++) {
  488. if (!_ifaces[i]->isDown()) {
  489. inout_masks.write |= std::uint8_t(1U << i); // Always ready to write if not down
  490. }
  491. if (_ifaces[i]->hasReadyRx()) {
  492. inout_masks.read |= std::uint8_t(1U << i); // Readability depends only on RX buf, even if down
  493. }
  494. }
  495. // Return value is irrelevant as long as it's non-negative
  496. return _ifaces.size();
  497. }
  498. int CANManager::addIface(const std::string& iface_name)
  499. {
  500. if (_ifaces.size() >= uavcan::MaxCanIfaces) {
  501. return -1;
  502. }
  503. // Open the socket
  504. const int fd = CAN::openSocket(iface_name);
  505. if (fd < 0) {
  506. return fd;
  507. }
  508. // Construct the iface - upon successful construction the iface will take ownership of the fd.
  509. _ifaces.emplace_back(new IfaceWrapper(fd));
  510. hal.console->printf("New iface '%s' fd %d\n", iface_name.c_str(), fd);
  511. return _ifaces.size() - 1;
  512. }
  513. #endif