LCOV - code coverage report
Current view: top level - AP_CANManager - AP_CANSensor.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1 2 50.0 %
Date: 2026-09-09 11:02:08 Functions: 1 2 50.0 %

          Line data    Source code
       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             : 
       7             :    This program is distributed in the hope that it will be useful,
       8             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10             :    GNU General Public License for more details.
      11             : 
      12             :    You should have received a copy of the GNU General Public License
      13             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      14             :  */
      15             : /*
      16             :   CANSensor class, for easy creation of CAN sensors using custom CAN protocols
      17             :  */
      18             :  
      19             : #pragma once
      20             : 
      21             : #include "AP_CAN.h"
      22             : #include "AP_CANDriver.h"
      23             : #ifndef HAL_BUILD_AP_PERIPH
      24             : #include "AP_CANManager.h"
      25             : #endif
      26             : 
      27             : #if HAL_MAX_CAN_PROTOCOL_DRIVERS
      28             : 
      29             : class CANSensor : public AP_CANDriver {
      30             : public:
      31             :     CANSensor(const char *driver_name, uint16_t stack_size=2048);
      32             : 
      33             :     /* Do not allow copies */
      34             :     CLASS_NO_COPY(CANSensor);
      35             : 
      36             :     void init(uint8_t driver_index) override;
      37             :     bool add_interface(AP_HAL::CANIface* can_iface) override;
      38             : 
      39             :     // Return true if this sensor has been successfully registered to a driver and initialized.
      40           0 :     bool initialized() const { return _initialized; }
      41             : 
      42             :     // handler for incoming frames
      43             :     virtual void handle_frame(AP_HAL::CANFrame &frame) = 0;
      44             : 
      45             :     // handler for outgoing frames
      46             :     bool write_frame(AP_HAL::CANFrame &out_frame, const uint32_t timeout_us);
      47             : 
      48             : #ifdef HAL_BUILD_AP_PERIPH
      49             :     static void set_periph(const uint8_t i, const AP_CAN::Protocol protocol, AP_HAL::CANIface* iface) {
      50             :         if (i < ARRAY_SIZE(_periph)) {
      51             :             _periph[i].protocol = protocol;
      52             :             _periph[i].iface = iface;
      53             :         }
      54             :     }
      55             : 
      56             :     // return driver type index i
      57             :     static AP_CAN::Protocol get_driver_type(const uint8_t i)
      58             :     {
      59             :         if (i < ARRAY_SIZE(_periph)) {
      60             :             return _periph[i].protocol;
      61             :         }
      62             :         return AP_CAN::Protocol::None;
      63             :     }
      64             : #else
      65        4172 :     static AP_CAN::Protocol get_driver_type(const uint8_t i) { return AP::can().get_driver_type(i); }
      66             : #endif
      67             : 
      68             : protected:
      69             :     void register_driver(AP_CAN::Protocol dtype);
      70             : 
      71             : private:
      72             :     void loop();
      73             : 
      74             :     const char *const _driver_name;
      75             :     const uint16_t _stack_size;
      76             :     bool _initialized;
      77             :     uint8_t _driver_index;
      78             : 
      79             :     // this is true when we are setup as an auxillary driver using CAN_Dn_PROTOCOL2
      80             :     bool is_aux_11bit_driver;
      81             : 
      82             :     AP_CANDriver *_can_driver;
      83             :     HAL_BinarySemaphore sem_handle;
      84             :     AP_HAL::CANIface* _can_iface;
      85             : 
      86             : #ifdef HAL_BUILD_AP_PERIPH
      87             :     void register_driver_periph(const AP_CAN::Protocol dtype);
      88             :     
      89             :     struct CANSensor_Periph {
      90             :         AP_HAL::CANIface* iface;
      91             :         AP_CAN::Protocol protocol;
      92             :     } static _periph[HAL_NUM_CAN_IFACES];
      93             : #endif
      94             : };
      95             : 
      96             : // a class to allow for multiple CAN backends with one
      97             : // CANSensor driver. This can be shared among different libraries like rangefinder and proximity
      98             : class MultiCAN : public CANSensor {
      99             : public:
     100             :     // callback functor def for forwarding frames
     101             :     FUNCTOR_TYPEDEF(ForwardCanFrame, bool, AP_HAL::CANFrame &);
     102             : 
     103             :     MultiCAN(ForwardCanFrame cf, AP_CAN::Protocol can_type, const char *driver_name);
     104             : 
     105             :     // handle a received frame from the CAN bus
     106             :     void handle_frame(AP_HAL::CANFrame &frame) override;
     107             : 
     108             : private:
     109             :     // class to allow for multiple callbacks implemented as a linked list
     110             :     class MultiCANLinkedList {
     111             :     public:
     112             :         struct CANSensor_Multi {
     113             :             ForwardCanFrame _callback;
     114             :             CANSensor_Multi* next = nullptr;
     115             :         };
     116             : 
     117             :         // register a callback for a CAN frame by adding it to the linked list
     118             :         void register_callback(ForwardCanFrame callback);
     119             : 
     120             :         // distribute the CAN frame to the registered callbacks
     121             :         void handle_frame(AP_HAL::CANFrame &frame);
     122             :         HAL_Semaphore sem;
     123             : 
     124             :     private:
     125             :         CANSensor_Multi* head = nullptr;
     126             :     };
     127             : 
     128             :     // Pointer to static instance of the linked list for persistence across instances
     129             :     static MultiCANLinkedList* callbacks;
     130             : };
     131             : 
     132             : #endif // HAL_MAX_CAN_PROTOCOL_DRIVERS
     133             : 

Generated by: LCOV version 1.14