AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
can_hardware_interface.hpp
Go to the documentation of this file.
1//================================================================================================
9//================================================================================================
10#ifndef CAN_HARDWARE_INTERFACE_HPP
11#define CAN_HARDWARE_INTERFACE_HPP
12
16#include "isobus/utility/event_dispatcher.hpp"
17
18#include <atomic>
19#include <cstdint>
20#include <cstring>
21#include <deque>
22#include <vector>
23
24#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
25#include <condition_variable>
26#include <thread>
27#endif
28
29namespace isobus
30{
37 {
38 public:
41 static std::uint8_t get_number_of_can_channels();
42
51 static bool set_number_of_can_channels(std::uint8_t value, std::size_t queueCapacity = 40);
52
58 static bool assign_can_channel_frame_handler(std::uint8_t channelIndex, std::shared_ptr<CANHardwarePlugin> canDriver);
59
64 static bool unassign_can_channel_frame_handler(std::uint8_t channelIndex);
65
69 static std::shared_ptr<CANHardwarePlugin> get_assigned_can_channel_frame_handler(std::uint8_t channelIndex);
70
73 static bool start();
74
77 static bool stop();
78
81 static bool is_running();
82
86 static bool transmit_can_frame(const CANMessageFrame &frame);
87
90 static EventDispatcher<const CANMessageFrame &> &get_can_frame_received_event_dispatcher();
91
94 static EventDispatcher<const CANMessageFrame &> &get_can_frame_transmitted_event_dispatcher();
95
98 static EventDispatcher<> &get_periodic_update_event_dispatcher();
99
102 static void update();
103
106 static void set_periodic_update_interval(std::uint32_t value);
107
110 static std::uint32_t get_periodic_update_interval();
111
112 private:
115 {
116 public:
119 explicit CANHardware(std::size_t queueCapacity);
120
122 virtual ~CANHardware();
123
126 bool start();
127
130 bool stop();
131
135 bool transmit_can_frame(const CANMessageFrame &frame) const;
136
139 bool receive_can_frame();
140
141#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
143 void start_threads();
144
146 void stop_threads();
147
150
151 std::unique_ptr<std::thread> receiveMessageThread;
152 bool receiveThreadRunning = false;
153#endif
154
155 std::shared_ptr<CANHardwarePlugin> frameHandler;
156
157 LockFreeQueue<CANMessageFrame> messagesToBeTransmittedQueue;
158 LockFreeQueue<CANMessageFrame> receivedMessagesQueue;
159 };
160
164
166 static constexpr std::uint32_t PERIODIC_UPDATE_INTERVAL = 4;
167
168#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
170 virtual ~CANHardwareInterface();
171
173 static void update_thread_function();
174
176 static void start_threads();
177
179 static void stop_threads();
180
181 static std::unique_ptr<std::thread> updateThread;
182 static std::condition_variable updateThreadWakeupCondition;
183#endif
184 static std::uint32_t lastUpdateTimestamp;
185 static std::uint32_t periodicUpdateInterval;
186 static EventDispatcher<const CANMessageFrame &> frameReceivedEventDispatcher;
187 static EventDispatcher<const CANMessageFrame &> frameTransmittedEventDispatcher;
188 static EventDispatcher<> periodicUpdateEventDispatcher;
189
190 static std::vector<std::unique_ptr<CANHardware>> hardwareChannels;
192 static Mutex updateMutex;
193 static bool started;
194 };
195}
196#endif // CAN_HARDWARE_INTERFACE_HPP
An abstraction between this CAN stack and any hardware layer.
A base class for a CAN driver. Can be derived into your platform's required interface.
A classical CAN frame, with 8 data bytes.
Stores the data for a single CAN channel.
std::shared_ptr< CANHardwarePlugin > frameHandler
The CAN driver to use for a CAN channel.
CANHardware(std::size_t queueCapacity)
Constructor for the CANHardware.
virtual ~CANHardware()
Destructor for the CANHardware.
LockFreeQueue< CANMessageFrame > messagesToBeTransmittedQueue
Transmit message queue for a CAN channel.
void receive_thread_function()
The receiving thread loop for this CAN channel.
bool receive_can_frame()
Receives a frame from the hardware and adds it to the receive queue.
void start_threads()
Starts the receiving thread for this CAN channel.
bool receiveThreadRunning
Flag to indicate if the receive thread is running.
LockFreeQueue< CANMessageFrame > receivedMessagesQueue
Receive message queue for a CAN channel.
bool start()
Starts this hardware channel.
void stop_threads()
Stops the receiving thread for this CAN channel.
bool transmit_can_frame(const CANMessageFrame &frame) const
Try to transmit the frame to the hardware.
std::unique_ptr< std::thread > receiveMessageThread
Thread to manage getting messages from a CAN channel.
Provides a common queuing and thread layer for running the CAN stack and all CAN drivers.
static bool stop()
Stops all CAN management threads and discards all remaining messages in the Tx and Rx queues.
static std::vector< std::unique_ptr< CANHardware > > hardwareChannels
A list of all CAN channel's metadata.
static EventDispatcher< const CANMessageFrame & > frameReceivedEventDispatcher
The event dispatcher for when a CAN message frame is received from hardware event.
static EventDispatcher< const CANMessageFrame & > frameTransmittedEventDispatcher
The event dispatcher for when a CAN message has been transmitted via hardware.
static std::uint8_t get_number_of_can_channels()
Returns the number of configured CAN channels that the class is managing.
static EventDispatcher< const CANMessageFrame & > & get_can_frame_received_event_dispatcher()
Get the event dispatcher for when a CAN message frame is received from hardware event.
static EventDispatcher periodicUpdateEventDispatcher
The event dispatcher for when a periodic update is called.
static Mutex updateMutex
A mutex for the main thread.
static std::uint32_t periodicUpdateInterval
The period between calls to the network manager update function in milliseconds.
static EventDispatcher & get_periodic_update_event_dispatcher()
Get the event dispatcher for when a periodic update is called.
static void stop_threads()
Stops all threads related to the hardware interface.
static bool started
Stores if the threads have been started.
static bool unassign_can_channel_frame_handler(std::uint8_t channelIndex)
Removes a CAN driver from a channel.
static void update()
Call this periodically if you have threads disabled.
static bool set_number_of_can_channels(std::uint8_t value, std::size_t queueCapacity=40)
Sets the number of CAN channels to manage.
static void start_threads()
Starts all threads related to the hardware interface.
static std::shared_ptr< CANHardwarePlugin > get_assigned_can_channel_frame_handler(std::uint8_t channelIndex)
Gets the CAN driver assigned to a channel.
static bool transmit_can_frame(const CANMessageFrame &frame)
Called externally, adds a message to a CAN channel's Tx queue.
static Mutex hardwareChannelsMutex
Mutex to protect hardwareChannels
static std::uint32_t lastUpdateTimestamp
The last time the network manager was updated.
static CANHardwareInterface SINGLETON
Singleton instance of the CANHardwareInterface class.
virtual ~CANHardwareInterface()
Deconstructor for the CANHardwareInterface class for stopping threads.
static std::uint32_t get_periodic_update_interval()
Get the interval between periodic updates to the network manager.
static EventDispatcher< const CANMessageFrame & > & get_can_frame_transmitted_event_dispatcher()
Get the event dispatcher for when a CAN message frame will be send to hardware event.
static bool is_running()
Checks if the CAN stack and CAN drivers are running.
static bool assign_can_channel_frame_handler(std::uint8_t channelIndex, std::shared_ptr< CANHardwarePlugin > canDriver)
Assigns a CAN driver to a channel.
static constexpr std::uint32_t PERIODIC_UPDATE_INTERVAL
The default update interval for the CAN stack. Mostly arbitrary.
static void update_thread_function()
The main thread loop for updating the stack.
static std::condition_variable updateThreadWakeupCondition
A condition variable to allow for signaling the updateThread to wakeup.
static std::unique_ptr< std::thread > updateThread
The main thread.
static void set_periodic_update_interval(std::uint32_t value)
Set the interval between periodic updates to the network manager.
static bool start()
Starts the threads for managing the CAN stack and CAN drivers.
A CAN frame for interfacing with a hardware layer, like socket CAN or other interface.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...