From 4a102e2f2be3f977840dd85050c74a1c4ea03ba2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 8 Sep 2024 16:11:30 +1000 Subject: [PATCH] AP_HAL: support more than 1 registered CAN callback this allows for CAN MCAST and MAVCAN at the same time --- libraries/AP_HAL/CANIface.cpp | 58 +++++++++++++++++++++++++++++------ libraries/AP_HAL/CANIface.h | 12 ++++++-- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/libraries/AP_HAL/CANIface.cpp b/libraries/AP_HAL/CANIface.cpp index 7bd1a8ebbd..74fa742f9c 100644 --- a/libraries/AP_HAL/CANIface.cpp +++ b/libraries/AP_HAL/CANIface.cpp @@ -58,9 +58,16 @@ bool AP_HAL::CANFrame::priorityHigherThan(const CANFrame& rhs) const */ int16_t AP_HAL::CANIface::receive(CANFrame& out_frame, uint64_t& out_ts_monotonic, CanIOFlags& out_flags) { - auto cb = frame_callback; - if (cb && (out_flags & IsMAVCAN)==0) { - cb(get_iface_num(), out_frame); + if ((out_flags & IsMAVCAN) != 0) { + return 1; + } +#ifndef HAL_BOOTLOADER_BUILD + WITH_SEMAPHORE(callbacks.sem); +#endif + for (auto &cb : callbacks.cb) { + if (cb != nullptr) { + cb(get_iface_num(), out_frame); + } } return 1; } @@ -70,28 +77,59 @@ int16_t AP_HAL::CANIface::receive(CANFrame& out_frame, uint64_t& out_ts_monotoni */ int16_t AP_HAL::CANIface::send(const CANFrame& frame, uint64_t tx_deadline, CanIOFlags flags) { - auto cb = frame_callback; - if (cb) { +#ifndef HAL_BOOTLOADER_BUILD + WITH_SEMAPHORE(callbacks.sem); +#endif + bool added_to_rx_queue = false; + for (auto &cb : callbacks.cb) { + if (cb == nullptr) { + continue; + } if ((flags & IsMAVCAN) == 0) { cb(get_iface_num(), frame); - } else { + } else if (!added_to_rx_queue) { CanRxItem rx_item; rx_item.frame = frame; rx_item.timestamp_us = AP_HAL::micros64(); rx_item.flags = AP_HAL::CANIface::IsMAVCAN; add_to_rx_queue(rx_item); + added_to_rx_queue = true; } } return 1; } /* - register a callback for for sending CAN_FRAME messages + register a callback for for sending CAN_FRAME messages. + On success the returned callback_id can be used to unregister the callback */ -bool AP_HAL::CANIface::register_frame_callback(FrameCb cb) +bool AP_HAL::CANIface::register_frame_callback(FrameCb cb, uint8_t &callback_id) { - frame_callback = cb; - return true; +#ifndef HAL_BOOTLOADER_BUILD + WITH_SEMAPHORE(callbacks.sem); +#endif + for (uint8_t i=0; i