From d16f31711e630bcb530ae9e503a069780f9c19bc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 1 May 2020 08:09:27 +1000 Subject: [PATCH] AP_RangeFinder: fixed mixing UAVCAN and non-UAVCAN rangefinders UAVCAN rangefinders add themselves to the frontend drivers as the devices appear. If they turn up before RangeFinder::init() is run then this prevented init() from scanning for the other rangefinders as num_instances is non-zero This also fixes a race condition in updating num_instances in the UAVCAN backend --- libraries/AP_RangeFinder/AP_RangeFinder.cpp | 22 ++++++++++++++++--- libraries/AP_RangeFinder/AP_RangeFinder.h | 2 ++ .../AP_RangeFinder/AP_RangeFinder_UAVCAN.cpp | 21 ++++++++++-------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/libraries/AP_RangeFinder/AP_RangeFinder.cpp b/libraries/AP_RangeFinder/AP_RangeFinder.cpp index e883cf17a5..0f1139562d 100644 --- a/libraries/AP_RangeFinder/AP_RangeFinder.cpp +++ b/libraries/AP_RangeFinder/AP_RangeFinder.cpp @@ -255,10 +255,11 @@ void RangeFinder::convert_params(void) { */ void RangeFinder::init(enum Rotation orientation_default) { - if (num_instances != 0) { + if (init_done) { // init called a 2nd time? return; } + init_done = true; convert_params(); @@ -270,11 +271,14 @@ void RangeFinder::init(enum Rotation orientation_default) for (uint8_t i=0, serial_instance = 0; iparams[i].type.get() == RangeFinder::Type::UAVCAN && - AP::rangefinder()->params[i].address == address) { - driver = (AP_RangeFinder_UAVCAN*)AP::rangefinder()->drivers[i]; + if ((RangeFinder::Type)frontend.params[i].type.get() == RangeFinder::Type::UAVCAN && + frontend.params[i].address == address) { + driver = (AP_RangeFinder_UAVCAN*)frontend.drivers[i]; } //Double check if the driver was initialised as UAVCAN Type if (driver != nullptr && (driver->_backend_type == RangeFinder::Type::UAVCAN)) { @@ -70,19 +71,21 @@ AP_RangeFinder_UAVCAN* AP_RangeFinder_UAVCAN::get_uavcan_backend(AP_UAVCAN* ap_u if (create_new) { for (uint8_t i = 0; i < RANGEFINDER_MAX_INSTANCES; i++) { - if ((RangeFinder::Type)AP::rangefinder()->params[i].type.get() == RangeFinder::Type::UAVCAN && - AP::rangefinder()->params[i].address == address) { - if (AP::rangefinder()->drivers[i] != nullptr) { + if ((RangeFinder::Type)frontend.params[i].type.get() == RangeFinder::Type::UAVCAN && + frontend.params[i].address == address) { + WITH_SEMAPHORE(frontend.detect_sem); + if (frontend.drivers[i] != nullptr) { //we probably initialised this driver as something else, reboot is required for setting //it up as UAVCAN type return nullptr; } - AP::rangefinder()->drivers[i] = new AP_RangeFinder_UAVCAN(AP::rangefinder()->state[i], AP::rangefinder()->params[i]); - driver = (AP_RangeFinder_UAVCAN*)AP::rangefinder()->drivers[i]; + frontend.drivers[i] = new AP_RangeFinder_UAVCAN(frontend.state[i], frontend.params[i]); + driver = (AP_RangeFinder_UAVCAN*)frontend.drivers[i]; if (driver == nullptr) { break; } - AP::rangefinder()->num_instances = MAX(i+1, AP::rangefinder()->num_instances); + gcs().send_text(MAV_SEVERITY_INFO, "RangeFinder[%u]: added UAVCAN node %u addr %u", + unsigned(i), unsigned(node_id), unsigned(address)); //Assign node id and respective uavcan driver, for identification if (driver->_ap_uavcan == nullptr) { driver->_ap_uavcan = ap_uavcan;