mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-10-06 09:02:52 +08:00
* feat(sensors): decouple sensor internal/external classification from the bus
A sensor's internal/external classification was derived from its bus
(px4_i2c_bus_external / px4_spi_bus_external), but a bus is a wire: one bus
routinely serves both chips soldered on the FC and a pinned-out connector, and
any onboard sensor on such a shared bus was classified external. That hands an
onboard mag an operator-settable rotation instead of the board rotation, feeds
an onboard baro's self-heated die temperature into air density as if it were
ambient, and inverts the 75/50 default priority. FMU-v6C and AirBrainH743
worked around it with hand-rolled device_id whitelists behind
BOARD_OVERRIDE_I2C_DEVICE_EXTERNAL; FMU-v6XRT's second onboard baro was simply
misclassified.
Classify the device instead of the bus: drivers publish is_external in
sensor_accel/gyro/mag/baro, derived from the device id by default and
overridden by the new -O start flag ("onboard") for onboard sensors that share
a bus with an external connector. -I/-X stay pure bus probe filters.
The question "is this sensor external" had four answers. It now has one, with
a single override point:
-O -> I2CSPIDriverConfig::external -> Device::set_external() and the
PX4* wrappers -> is_external in the sensor topic
px4_i2c_device_external() was px4_i2c_bus_external() with a device id decode in
front, and calibration::DeviceExternal() forwarded to device_is_external();
both are gone. Device::external() stops being a bus query: it is non-virtual,
defaults to device_is_external(), and takes the declared value through
set_external(), so the five I2C/SPI overrides that used to answer it from the
bus are deleted and cannot diverge again. device::I2C and device::SPI set it
from the config, so every driver built on the bus framework follows -O without
doing anything. px4_i2c_bus_external() and px4_spi_bus_external() survive as
what they honestly are - bus predicates - reachable only through the fallback.
-O is opt-in per driver (BusCLIArguments::support_onboard), the same way -k is:
a flag that every driver advertised but only a handful honoured would be a
silent no-op on the rest. This also drops the special case for the mcp23009 and
mcp23017 GPIO expanders, which use -O for their output state and simply do not
opt in.
sensor_gyro_fifo carries is_external too. VehicleAngularVelocity prefers the
FIFO topic for any IMU that publishes one, so without it the rate controller
would take its rotation from the bus while VehicleIMU took it from the topic -
the same chip, two classifications.
The BOARD_OVERRIDE_I2C_DEVICE_EXTERNAL hook is removed along with both board
implementations, replaced by -O on the affected rc.board_sensors lines.
FMU-v5x, MR-CANHUBK3, KakuteF7, NXT-Dual and MicoAir H743-Lite each start an
onboard barometer on an external bus and get the flag as well.
Assisted-by: Claude:claude-fable-5, Claude:claude-opus-5[1m]
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* feat(sensors): treat shared buses as first-class topology
A boolean internal/external flag cannot describe a bus that carries both
hard-mounted chips and a connector. -O was an opt-in override for that
case, so most drivers silently ignored it and classification still
followed the bus.
Declare Internal / External / Shared on the bus, probe External and
Shared, and classify each sensor from -I/-s vs -X/-S.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ci): drop stale ITCM symbols and clang-tidy errors
ITCM lists still named calibration::DeviceExternal and
px4_spi_bus_external after both were removed. The host test stubs
forwarded varargs in a way the analyzer rejected, and stripped I2C
headers kept extra trailing newlines.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(sensors): inline device_is_external into the header
Reaching it through drivers__device pulled the kernel-only library into
the userspace image of a protected build; giving it a library of its own
put an archive referencing px4_i2c_buses/px4_spi_buses after the board
library that defines them. Inlining sidesteps both.
* fix(sensors): compile tcbp001ta and probe canhubk3 GPS mag
tcbp001ta is not an I2CSPIDriver, so config.external does not exist; it
only ever starts on internal SPI. -X on canhubk3 I2C2 never ran because
that bus is Internal.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
241 lines
7.0 KiB
C++
241 lines
7.0 KiB
C++
/****************************************************************************
|
|
*
|
|
* Copyright (C) 2017 PX4 Development Team. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/**
|
|
* @file module.cpp
|
|
* Implementation of the API declared in px4_module.h.
|
|
*/
|
|
|
|
#ifndef MODULE_NAME
|
|
#define MODULE_NAME "module"
|
|
#endif
|
|
|
|
#include <px4_platform_common/module.h>
|
|
#include <px4_platform_common/defines.h>
|
|
#include <px4_platform_common/log.h>
|
|
|
|
pthread_mutex_t px4_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
#ifndef __PX4_NUTTX
|
|
|
|
void PRINT_MODULE_DESCRIPTION(const char *description)
|
|
{
|
|
// TODO: the output could be improved by:
|
|
// - mark titles in bold (lines starting with ##)
|
|
// - highlight commands (lines starting with $, or `cmd`)
|
|
PX4_INFO_RAW("%s\n\n", description);
|
|
}
|
|
|
|
#endif /* __PX4_NUTTX */
|
|
|
|
void PRINT_MODULE_USAGE_NAME(const char *executable_name, const char *category)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
PX4_INFO_RAW("Usage: %s <command> [arguments...]\n", executable_name);
|
|
PX4_INFO_RAW(" Commands:\n");
|
|
#else
|
|
PX4_INFO_RAW("Usage: %s See:" CONSTRAINED_FLASH_NO_HELP "\n", executable_name);
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_SUBCATEGORY(const char *subcategory)
|
|
{
|
|
(void)subcategory;
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_NAME_SIMPLE(const char *executable_name, const char *category)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
PX4_INFO_RAW("Usage: %s [arguments...]\n", executable_name);
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_COMMAND_DESCR(const char *name, const char *description)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
if (description) {
|
|
PX4_INFO_RAW("\n %-13s %s\n", name, description);
|
|
|
|
} else {
|
|
PX4_INFO_RAW("\n %s\n", name);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAM_COMMENT(const char *comment)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
PX4_INFO_RAW("\n %s\n", comment);
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(bool i2c_support, bool spi_support)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
// Note: this must be kept in sync with Tools/px4moduledoc/srcparser.py
|
|
if (i2c_support) {
|
|
PRINT_MODULE_USAGE_PARAM_FLAG('I', "Internal I2C bus(es) (onboard sensors; shared bus only if -b is given)", true);
|
|
PRINT_MODULE_USAGE_PARAM_FLAG('X', "External I2C bus(es) (connector sensors, including shared buses)", true);
|
|
}
|
|
|
|
if (spi_support) {
|
|
PRINT_MODULE_USAGE_PARAM_FLAG('s', "Internal SPI bus(es) (onboard sensors; shared bus only if -b is given)", true);
|
|
PRINT_MODULE_USAGE_PARAM_FLAG('S', "External SPI bus (connector sensors, including shared buses)", true);
|
|
}
|
|
|
|
PRINT_MODULE_USAGE_PARAM_INT('b', -1, 0, 16, "board-specific bus (default=all) (external SPI: n-th bus (default=1))",
|
|
true);
|
|
|
|
if (spi_support) {
|
|
PRINT_MODULE_USAGE_PARAM_INT('c', -1, 0, 31, "chip-select pin (for internal SPI) or index (for external SPI)", true);
|
|
PRINT_MODULE_USAGE_PARAM_INT('m', -1, 0, 3, "SPI mode", true);
|
|
}
|
|
|
|
PRINT_MODULE_USAGE_PARAM_INT('f', -1, 0, 100000, "bus frequency in kHz", true);
|
|
PRINT_MODULE_USAGE_PARAM_FLAG('q', "quiet startup (no message if no device found)", true);
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(uint8_t default_address)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
PRINT_MODULE_USAGE_PARAM_INT('a', default_address, 0, 0xff, "I2C address", true);
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAMS_I2C_KEEP_RUNNING_FLAG()
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
PRINT_MODULE_USAGE_PARAM_FLAG('k', "if initialization (probing) fails, keep retrying periodically", true);
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAM_INT(char option_char, int default_val, int min_val, int max_val,
|
|
const char *description, bool is_optional)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
if (is_optional) {
|
|
PX4_INFO_RAW(" [-%c <val>] %s\n", option_char, description);
|
|
|
|
if (default_val != -1) {
|
|
PX4_INFO_RAW(" default: %i\n", default_val);
|
|
}
|
|
|
|
} else {
|
|
PX4_INFO_RAW(" -%c <val> %s\n", option_char, description);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAM_FLOAT(char option_char, float default_val, float min_val, float max_val,
|
|
const char *description, bool is_optional)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
if (is_optional) {
|
|
PX4_INFO_RAW(" [-%c <val>] %s\n", option_char, description);
|
|
|
|
if (PX4_ISFINITE(default_val)) {
|
|
PX4_INFO_RAW(" default: %.1f\n", (double)default_val);
|
|
}
|
|
|
|
} else {
|
|
PX4_INFO_RAW(" -%c <val> %s\n", option_char, description);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAM_FLAG(char option_char, const char *description, bool is_optional)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
if (is_optional) {
|
|
PX4_INFO_RAW(" [-%c] %s\n", option_char, description);
|
|
|
|
} else {
|
|
PX4_INFO_RAW(" -%c %s\n", option_char, description);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void PRINT_MODULE_USAGE_PARAM_STRING(char option_char, const char *default_val, const char *values,
|
|
const char *description, bool is_optional)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
if (is_optional) {
|
|
PX4_INFO_RAW(" [-%c <val>] %s\n", option_char, description);
|
|
|
|
} else {
|
|
PX4_INFO_RAW(" -%c <val> %s\n", option_char, description);
|
|
}
|
|
|
|
if (values) {
|
|
if (default_val) {
|
|
PX4_INFO_RAW(" values: %s, default: %s\n", values, default_val);
|
|
|
|
} else {
|
|
PX4_INFO_RAW(" values: %s\n", values);
|
|
}
|
|
|
|
} else {
|
|
if (default_val) {
|
|
PX4_INFO_RAW(" default: %s\n", default_val);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
void PRINT_MODULE_USAGE_ARG(const char *values, const char *description, bool is_optional)
|
|
{
|
|
#ifndef CONSTRAINED_FLASH_NO_HELP
|
|
|
|
if (is_optional) {
|
|
PX4_INFO_RAW(" [%-9s] %s\n", values, description);
|
|
|
|
} else {
|
|
PX4_INFO_RAW(" %-11s %s\n", values, description);
|
|
}
|
|
|
|
#endif
|
|
}
|