From e00c07be2835dd082862730189c87baacbfbdbeb Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Wed, 26 Apr 2017 00:19:18 +0200 Subject: [PATCH] Reworked reading CAN devices from BCM socket. Now reading thread hold in can_bus_t object instead of can_bus_dev_t and reading happens using select(). Change-Id: Ib8cc68c4484679168519f3c0fa485fedd1616c74 Signed-off-by: Romain Forlot --- CAN-binder/low-can-binding/can/can-bus-dev.cpp | 9 +++-- CAN-binder/low-can-binding/can/can-bus-dev.hpp | 3 +- CAN-binder/low-can-binding/can/can-bus.cpp | 51 +++++++++++++++++++++++++- CAN-binder/low-can-binding/can/can-bus.hpp | 4 ++ 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/CAN-binder/low-can-binding/can/can-bus-dev.cpp b/CAN-binder/low-can-binding/can/can-bus-dev.cpp index df0c0d6f..955e617d 100644 --- a/CAN-binder/low-can-binding/can/can-bus-dev.cpp +++ b/CAN-binder/low-can-binding/can/can-bus-dev.cpp @@ -27,6 +27,7 @@ #include "can-message.hpp" #include "../low-can-binding.hpp" #include "canutil/write.h" +#include "../bitfield/bitfield.h" /// @brief Class constructor /// @@ -45,6 +46,9 @@ int can_bus_dev_t::get_index() const { return index_; } +utils::socketcan_t& can_bus_dev_t::get_socket() +{ + return can_socket_; } /// @brief Open the can socket and returning it @@ -125,13 +129,12 @@ int can_bus_dev_t::create_rx_filter(const can_signal_t& s) struct utils::canfd_bcm_msg bcm_msg; uint8_t bit_size = s.get_bit_size(); - float val = (float)exp2(bit_size); - uint64_t filter = eightbyte_encode_float(val, s.get_bit_position(), bit_size, s.get_factor(), s.get_offset()); + float val = (float)exp2(bit_size)-1; bcm_msg.msg_head.opcode = RX_SETUP; bcm_msg.msg_head.can_id = can_id; bcm_msg.msg_head.nframes = 1; - U64_DATA(&bcm_msg.frames[0]) = filter; + bitfield_encode_float(val, s.get_bit_position(), bit_size, s.get_factor(), s.get_offset(), bcm_msg.frames[0].data, CANFD_MAX_DLEN); if(can_socket_ << bcm_msg) return 0; diff --git a/CAN-binder/low-can-binding/can/can-bus-dev.hpp b/CAN-binder/low-can-binding/can/can-bus-dev.hpp index 38727e03..8b4cf47e 100644 --- a/CAN-binder/low-can-binding/can/can-bus-dev.hpp +++ b/CAN-binder/low-can-binding/can/can-bus-dev.hpp @@ -43,10 +43,11 @@ private: void can_reader(can_bus_t& can_bus); public: - can_bus_dev_t(const std::string& dev_name, int32_t address); + can_bus_dev_t(const std::string& dev_name, int index); std::string get_device_name() const; int get_index() const; + utils::socketcan_t& get_socket(); int open(); void configure(); diff --git a/CAN-binder/low-can-binding/can/can-bus.cpp b/CAN-binder/low-can-binding/can/can-bus.cpp index 6e74b86a..6f9e78d9 100644 --- a/CAN-binder/low-can-binding/can/can-bus.cpp +++ b/CAN-binder/low-can-binding/can/can-bus.cpp @@ -47,6 +47,49 @@ can_bus_t::can_bus_t(utils::config_parser_t conf_file) std::map> can_bus_t::can_devices_; +/// @brief Listen for all device sockets and fill can_messages_queue with them. +/// Reading blocks until message arrive on listened sockets. +/// +/// @return 0 if ok -1 if not +int can_bus_t::can_reader() +{ + fd_set rfds; + int sock_max = INVALID_SOCKET; + + FD_ZERO(&rfds); + + for(auto& can_dev : can_devices_) + { + FD_SET(can_dev.second->get_socket().socket(), &rfds); + if (sock_max < can_dev.second->get_socket().socket()) + sock_max = can_dev.second->get_socket().socket(); + } + + int ret; + while(is_reading_) + { + ret = select(sock_max + 1, &rfds, nullptr, nullptr, nullptr); + + if(ret == -1) + perror("select()"); + else if(ret > 0) + { + for(const auto& s: can_devices_) + { + if(FD_ISSET(s.second->get_socket().socket(), &rfds)) + { + can_message_t msg; + s.second->get_socket() >> msg; + push_new_can_message(msg); + } + } + } + else + printf("Timeout\n"); + } + return 0; +} + /// @brief Will make the decoding operation on a classic CAN message. It will not /// handle CAN commands nor diagnostic messages that have their own method to get /// this happens. @@ -199,6 +242,11 @@ void can_bus_t::can_event_push() /// and push subscribed events. void can_bus_t::start_threads() { + is_reading_ = true; + th_reading_ = std::thread(&can_bus_t::can_reader, this); + if(!th_reading_.joinable()) + is_reading_ = false; + is_decoding_ = true; th_decoding_ = std::thread(&can_bus_t::can_decode_message, this); if(!th_decoding_.joinable()) @@ -215,6 +263,7 @@ void can_bus_t::start_threads() /// they'll finish their job. void can_bus_t::stop_threads() { + is_reading_ = false; is_decoding_ = false; is_pushing_ = false; } @@ -248,7 +297,7 @@ int can_bus_t::init_can_dev() can_bus_t::can_devices_[device]->configure(); DEBUG(binder_interface, "%s: Start reading thread", __FUNCTION__); NOTICE(binder_interface, "%s: %s device opened and reading", __FUNCTION__, device.c_str()); - can_bus_t::can_devices_[device]->start_reading(*this); + //can_bus_t::can_devices_[device]->start_reading(*this); i++; } else diff --git a/CAN-binder/low-can-binding/can/can-bus.hpp b/CAN-binder/low-can-binding/can/can-bus.hpp index 11b3b7af..94aa0428 100644 --- a/CAN-binder/low-can-binding/can/can-bus.hpp +++ b/CAN-binder/low-can-binding/can/can-bus.hpp @@ -54,6 +54,10 @@ private: int process_can_signals(can_message_t& can_message); int process_diagnostic_signals(diagnostic_manager_t& manager, const can_message_t& can_message); + int can_reader(); + std::thread th_reading_; ///< Thread handling read the socket can device filling can_message_q_ queue of can_bus_t + bool is_reading_ = false; ///< boolean telling whether or not reading is running or not + void can_decode_message(); std::thread th_decoding_; ///< thread that'll handle decoding a can frame bool is_decoding_ = false; ///< boolean member controling thread while loop -- 2.16.6