diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index da19602209d..e8bc3faba65 100755 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -415,6 +415,8 @@ main_sources(COMMON_SRC mavlink/mavlink_mission.c mavlink/mavlink_mission.h mavlink/mavlink_modes.c + mavlink/mavlink_msg_entry.c + mavlink/mavlink_msg_entry.h mavlink/mavlink_modes.h mavlink/mavlink_types.h mavlink/mavlink_ports.c diff --git a/src/main/fc/fc_mavlink.c b/src/main/fc/fc_mavlink.c index 02bdfb84fc4..1205438c5cc 100644 --- a/src/main/fc/fc_mavlink.c +++ b/src/main/fc/fc_mavlink.c @@ -419,6 +419,7 @@ mavlinkFcDispatchResult_e mavlinkFcDispatchIncomingMessage(uint8_t ingressPortIn return mavlinkHandleIncomingTimesync() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: return handleIncoming_PARAM_REQUEST_LIST() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; +#ifndef USE_TELEMETRY_MAVLINK_CONSTRAINED case MAVLINK_MSG_ID_MISSION_CLEAR_ALL: return mavlinkHandleIncomingMissionClearAll() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_MISSION_COUNT: @@ -429,16 +430,19 @@ mavlinkFcDispatchResult_e mavlinkFcDispatchIncomingMessage(uint8_t ingressPortIn return mavlinkHandleIncomingMissionItemInt() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_MISSION_REQUEST_LIST: return mavlinkHandleIncomingMissionRequestList() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; +#endif case MAVLINK_MSG_ID_COMMAND_LONG: return mavlinkHandleIncomingCommandLong() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_COMMAND_INT: return mavlinkHandleIncomingCommandInt() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; +#ifndef USE_TELEMETRY_MAVLINK_CONSTRAINED case MAVLINK_MSG_ID_MISSION_REQUEST: return mavlinkHandleIncomingMissionRequest() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_MISSION_REQUEST_INT: return mavlinkHandleIncomingMissionRequestInt() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_MISSION_ACK: return mavlinkHandleIncomingMissionAck() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; +#endif case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: return mavlinkHandleIncomingRequestDataStream() ? MAVLINK_FC_DISPATCH_HANDLED_ACTIVITY : MAVLINK_FC_DISPATCH_NOT_HANDLED; case MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE: diff --git a/src/main/mavlink/mavlink_mission.c b/src/main/mavlink/mavlink_mission.c index 08141b4f086..abd959ad597 100644 --- a/src/main/mavlink/mavlink_mission.c +++ b/src/main/mavlink/mavlink_mission.c @@ -4,7 +4,7 @@ #include "mavlink/mavlink_mission.h" #include "mavlink/mavlink_runtime.h" -#if defined(USE_TELEMETRY) && defined(USE_TELEMETRY_MAVLINK) +#if defined(USE_TELEMETRY) && defined(USE_TELEMETRY_MAVLINK) && !defined(USE_TELEMETRY_MAVLINK_CONSTRAINED) /* * Mission transfer retry and partner tracking are adapted from Betaflight's diff --git a/src/main/mavlink/mavlink_msg_entry.c b/src/main/mavlink/mavlink_msg_entry.c new file mode 100644 index 00000000000..f0f972b9498 --- /dev/null +++ b/src/main/mavlink/mavlink_msg_entry.c @@ -0,0 +1,30 @@ +/* + * This file is part of INAV. + * + * INAV is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * INAV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with INAV. If not, see . + */ + +#include "mavlink/mavlink_types.h" + +#if defined(USE_TELEMETRY_MAVLINK) || defined(USE_SERIALRX_MAVLINK) + +/* + * The single instantiation of the MAVLink helpers for the whole firmware. + * MAVLINK_SEPARATE_HELPERS (see mavlink_msg_entry.h) leaves MAVLINK_HELPER + * empty and stops protocol.h including these, so this is the only place they + * are defined, with external linkage. + */ +#include "mavlink_helpers.h" + +#endif diff --git a/src/main/mavlink/mavlink_msg_entry.h b/src/main/mavlink/mavlink_msg_entry.h new file mode 100644 index 00000000000..6f66fd8c3b0 --- /dev/null +++ b/src/main/mavlink/mavlink_msg_entry.h @@ -0,0 +1,36 @@ +/* + * This file is part of INAV. + * + * INAV is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * INAV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with INAV. If not, see . + */ + +#pragma once + +/* + * protocol.h compiles the MAVLink helpers as MAVLINK_HELPER = static and + * includes them into every translation unit, so each one gets a private copy of + * every helper it touches - and of the static data inside them. Nothing warns + * about it: the copies are static data rather than unused code, so no + * diagnostic fires and nothing shows up in a diff. + * + * The message table is the expensive case. mavlink_get_msg_entry() holds it as + * a function-local static, and two callers - routing and runtime - meant two + * copies of a 4044 byte table. + * + * MAVLINK_SEPARATE_HELPERS is the library's own switch for this: protocol.h + * then emits declarations only, and mavlink_msg_entry.c compiles the helpers + * once with external linkage. This header must be included before + * storm32/mavlink.h so the switch is set before protocol.h is reached. + */ +#define MAVLINK_SEPARATE_HELPERS diff --git a/src/main/mavlink/mavlink_runtime.c b/src/main/mavlink/mavlink_runtime.c index 6fce0de2422..fb477bb0ca8 100644 --- a/src/main/mavlink/mavlink_runtime.c +++ b/src/main/mavlink/mavlink_runtime.c @@ -279,8 +279,10 @@ static bool isMAVLinkTelemetryHalfDuplex(uint8_t portIndex) void mavlinkRuntimeHandle(timeUs_t currentTimeUs) { +#ifndef USE_TELEMETRY_MAVLINK_CONSTRAINED mavlinkSendPendingMissionItemReached(); mavlinkMissionUpdate(currentTimeUs / 1000); +#endif mavlinkSendModeStatusText(); mavlinkSendArmingStatusText(); diff --git a/src/main/mavlink/mavlink_types.h b/src/main/mavlink/mavlink_types.h index 8fb2f9e6b7e..1d1476fd732 100644 --- a/src/main/mavlink/mavlink_types.h +++ b/src/main/mavlink/mavlink_types.h @@ -28,6 +28,7 @@ #ifndef MAVLINK_COMM_NUM_BUFFERS #define MAVLINK_COMM_NUM_BUFFERS MAX_MAVLINK_PORTS #endif +#include "mavlink/mavlink_msg_entry.h" #include "storm32/mavlink.h" #pragma GCC diagnostic pop diff --git a/src/main/rx/mavlink.h b/src/main/rx/mavlink.h index 0290b010003..7396825cac7 100644 --- a/src/main/rx/mavlink.h +++ b/src/main/rx/mavlink.h @@ -22,6 +22,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #define MAVLINK_COMM_NUM_BUFFERS MAX_MAVLINK_PORTS +#include "mavlink/mavlink_msg_entry.h" #include "storm32/mavlink.h" #pragma GCC diagnostic pop diff --git a/src/main/target/common.h b/src/main/target/common.h index d339e6620ae..3c997b74d02 100644 --- a/src/main/target/common.h +++ b/src/main/target/common.h @@ -424,9 +424,16 @@ #endif //Designed to free space of F722 and F411 MCUs -#if (MCU_FLASH_SIZE > 512) -#define USE_TELEMETRY_MAVLINK #define USE_SERIALRX_MAVLINK +#if (MCU_FLASH_SIZE > 512) + #define USE_TELEMETRY_MAVLINK +#endif + +#if defined(MCU_FLASH_SIZE) && (MCU_FLASH_SIZE <= 512) + #define USE_TELEMETRY_MAVLINK_CONSTRAINED +#endif + +#if (MCU_FLASH_SIZE > 512) #define USE_TELEMETRY_SIM #define USE_VTX_FFPV #define USE_SERIALRX_SUMD diff --git a/src/main/target/common_post.h b/src/main/target/common_post.h index a27835731cc..a6e3ed2a440 100644 --- a/src/main/target/common_post.h +++ b/src/main/target/common_post.h @@ -19,6 +19,13 @@ #pragma once +// Constrained MAVLink, selected by flash size in common.h: the full subsystem +// minus MAVLink mission transfer, which does not fit on a 512 KB target. +// Missions themselves are unaffected - they are managed over MSP. +#ifdef USE_TELEMETRY_MAVLINK_CONSTRAINED +#define USE_TELEMETRY_MAVLINK +#endif + // MSP-over-MAVLink is independently removable from MAVLink targets that cannot // afford its reply buffer. Define DISABLE_MAVLINK_MSP_TUNNEL in a target to // retain normal MAVLink without the tunnel RAM/code cost. diff --git a/src/test/unit/CMakeLists.txt b/src/test/unit/CMakeLists.txt index ce7813f033d..44cae96d829 100644 --- a/src/test/unit/CMakeLists.txt +++ b/src/test/unit/CMakeLists.txt @@ -80,7 +80,7 @@ set_property(SOURCE gimbal_serial_unittest.cc PROPERTY definitions USE_SERIAL_GI set_property(SOURCE mavlink_unittest.cc PROPERTY depends "fc/fc_mavlink.c" "mavlink/mavlink_command.c" "mavlink/mavlink_guided.c" "mavlink/mavlink_mission.c" "mavlink/mavlink_modes.c" "mavlink/mavlink_ports.c" - "mavlink/mavlink_routing.c" "mavlink/mavlink_runtime.c" "mavlink/mavlink_streams.c" "telemetry/mavlink.c" + "mavlink/mavlink_msg_entry.c" "mavlink/mavlink_routing.c" "mavlink/mavlink_runtime.c" "mavlink/mavlink_streams.c" "telemetry/mavlink.c" "common/crc.c" "common/maths.c" "common/streambuf.c" "common/string_light.c" "msp/msp_serial.c") set_property(SOURCE mavlink_unittest.cc PROPERTY definitions USE_TELEMETRY USE_TELEMETRY_MAVLINK USE_MAVLINK_MSP_TUNNEL) set_property(SOURCE mavlink_unittest.cc PROPERTY extra_includes