Improve MSP handling (#3415)

* Improve MSP

* Only retain last duplicate MSP command in queue

* For MSP V1 we skip requests that are already in the queue

* Implement MULTIPLE_MSP

* Revert

* Give FC time to react to new settings

* Reduce timeout to 200ms

* Add new mspHelper for EEPROM write

* Reduce MIN_TIMEOUT
master
Mark Haslinghuis 2023-05-06 21:12:18 +02:00 committed by GitHub
parent 67ce2ec7c7
commit 07a352a941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 52 additions and 51 deletions

View File

@ -52,9 +52,9 @@ const MSP = {
packet_error: 0, packet_error: 0,
unsupported: 0, unsupported: 0,
MIN_TIMEOUT: 250, MIN_TIMEOUT: 50,
MAX_TIMEOUT: 2000, MAX_TIMEOUT: 2000,
timeout: 250, timeout: 200,
last_received_timestamp: null, last_received_timestamp: null,
listeners: [], listeners: [],
@ -305,46 +305,41 @@ const MSP = {
return bufferOut; return bufferOut;
}, },
send_message: function (code, data, callback_sent, callback_msp, doCallbackOnError) { send_message: function (code, data, callback_sent, callback_msp, doCallbackOnError) {
if (CONFIGURATOR.virtualMode) { if (code === undefined || !serial.connectionId || CONFIGURATOR.virtualMode) {
if (callback_msp) { if (callback_msp) {
callback_msp(); callback_msp();
} }
return false; return false;
} }
if (code === undefined || !serial.connectionId) { // Check if request already exists in the queue
return false;
}
const bufferOut = code <= 254 ? this.encode_message_v1(code, data) : this.encode_message_v2(code, data);
const obj = {
'code': code,
'requestBuffer': bufferOut,
'callback': callback_msp ? callback_msp : false,
'timer': false,
'callbackOnError': doCallbackOnError,
'start': performance.now(),
};
let requestExists = false; let requestExists = false;
for (const instance of MSP.callbacks) { for (const instance of MSP.callbacks) {
if (instance.code === code) { if (instance.code === code) {
// request already exist, we will just attach
requestExists = true; requestExists = true;
break; break;
} }
} }
const bufferOut = code <= 254 ? this.encode_message_v1(code, data) : this.encode_message_v2(code, data);
const obj = {
'code': code,
'requestBuffer': bufferOut,
'callback': callback_msp,
'callbackOnError': doCallbackOnError,
'start': performance.now(),
};
if (!requestExists) { if (!requestExists) {
obj.timer = setInterval(function () { obj.timer = setTimeout(function () {
console.warn(`MSP: data request timed-out: ${code} ID: ${serial.connectionId} TAB: ${GUI.active_tab} TIMEOUT: ${MSP.timeout} QUEUE: ${MSP.callbacks.length}`); console.warn(`MSP: data request timed-out: ${code} ID: ${serial.connectionId} TAB: ${GUI.active_tab} TIMEOUT: ${MSP.timeout} QUEUE: ${MSP.callbacks.length} (${MSP.callbacks.map(function (e) { return e.code; })})`);
serial.send(bufferOut, function (_sendInfo) { serial.send(bufferOut, function (_sendInfo) {
obj.stop = performance.now(); obj.stop = performance.now();
const executionTime = Math.round(obj.stop - obj.start); const executionTime = Math.round(obj.stop - obj.start);
MSP.timeout = Math.max(MSP.MIN_TIMEOUT, Math.min(executionTime, MSP.MAX_TIMEOUT)); MSP.timeout = Math.max(MSP.MIN_TIMEOUT, Math.min(executionTime, MSP.MAX_TIMEOUT));
}); });
}, MSP.timeout); }, MSP.timeout);
} }

View File

@ -2729,6 +2729,17 @@ MspHelper.prototype.sendSerialConfig = function(callback) {
MSP.send_message(mspCode, mspHelper.crunch(mspCode), false, callback); MSP.send_message(mspCode, mspHelper.crunch(mspCode), false, callback);
}; };
MspHelper.prototype.writeConfiguration = function(callback) {
setTimeout(function() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function() {
gui_log(i18n.getMessage('configurationEepromSaved'));
console.log('Configuration saved to EEPROM');
if (callback) {
callback();
}
});
}, 100); // 100ms delay before sending MSP_EEPROM_WRITE to ensure that all settings have been received
};
let mspHelper; let mspHelper;
// This is temporary, till things are moved // This is temporary, till things are moved

View File

@ -205,13 +205,13 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
function reboot() { function reboot() {
const buffer = []; const buffer = [];
buffer.push8(rebootMode); buffer.push8(rebootMode);
MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, () => { setTimeout(() => {
MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, () => {
// if firmware doesn't flush MSP/serial send buffers and gracefully shutdown VCP connections we won't get a reply, so don't wait for it. // if firmware doesn't flush MSP/serial send buffers and gracefully shutdown VCP connections we won't get a reply, so don't wait for it.
self.msp_connector.disconnect(disconnectionResult => onDisconnect(disconnectionResult));
self.msp_connector.disconnect(disconnectionResult => onDisconnect(disconnectionResult)); console.log('Reboot request received by device');
});
}, () => console.log('Reboot request received by device')); }, 100);
} }
function onAbort() { function onAbort() {

View File

@ -403,7 +403,7 @@ auxiliary.initialize = function (callback) {
mspHelper.sendModeRanges(save_to_eeprom); mspHelper.sendModeRanges(save_to_eeprom);
function save_to_eeprom() { function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function () { mspHelper.writeConfiguration(function () {
gui_log(i18n.getMessage('auxiliaryEepromSaved')); gui_log(i18n.getMessage('auxiliaryEepromSaved'));
}); });
} }

View File

@ -453,8 +453,7 @@ configuration.initialize = function (callback) {
.then(() => semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45) ? .then(() => semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45) ?
MSP.promise(MSPCodes.MSP2_SET_TEXT, mspHelper.crunch(MSPCodes.MSP2_SET_TEXT, MSPCodes.PILOT_NAME)) : Promise.resolve(true)) MSP.promise(MSPCodes.MSP2_SET_TEXT, mspHelper.crunch(MSPCodes.MSP2_SET_TEXT, MSPCodes.PILOT_NAME)) : Promise.resolve(true))
.then(() => MSP.promise(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG))) .then(() => MSP.promise(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG)))
.then(() => MSP.promise(MSPCodes.MSP_EEPROM_WRITE)) .then(() => mspHelper.writeConfiguration(reboot));
.then(() => reboot());
} }
function reboot() { function reboot() {

View File

@ -352,8 +352,7 @@ gps.initialize = async function (callback) {
async function saveConfiguration() { async function saveConfiguration() {
await MSP.promise(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG)); await MSP.promise(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG));
await MSP.promise(MSPCodes.MSP_SET_GPS_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_GPS_CONFIG)); await MSP.promise(MSPCodes.MSP_SET_GPS_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_GPS_CONFIG));
await MSP.promise(MSPCodes.MSP_EEPROM_WRITE); await mspHelper.writeConfiguration(reboot);
reboot();
} }
function reboot() { function reboot() {

View File

@ -567,7 +567,7 @@ led_strip.initialize = function (callback, scrollPosition) {
} }
function save_to_eeprom() { function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function() { mspHelper.writeConfiguration(function() {
gui_log(i18n.getMessage('ledStripEepromSaved')); gui_log(i18n.getMessage('ledStripEepromSaved'));
}); });
} }

View File

@ -1132,6 +1132,8 @@ motors.initialize = async function (callback) {
} }
$('a.save').on('click', async function() { $('a.save').on('click', async function() {
GUI.interval_kill_all(['motor_and_status_pull','motors_power_data_pull_slow']);
// gather data that doesn't have automatic change event bound // gather data that doesn't have automatic change event bound
FC.MOTOR_CONFIG.minthrottle = parseInt($('input[name="minthrottle"]').val()); FC.MOTOR_CONFIG.minthrottle = parseInt($('input[name="minthrottle"]').val());
FC.MOTOR_CONFIG.maxthrottle = parseInt($('input[name="maxthrottle"]').val()); FC.MOTOR_CONFIG.maxthrottle = parseInt($('input[name="maxthrottle"]').val());
@ -1156,16 +1158,16 @@ motors.initialize = async function (callback) {
await MSP.promise(MSPCodes.MSP_SET_MOTOR_3D_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MOTOR_3D_CONFIG)); await MSP.promise(MSPCodes.MSP_SET_MOTOR_3D_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MOTOR_3D_CONFIG));
await MSP.promise(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG)); await MSP.promise(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG));
await MSP.promise(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG)); await MSP.promise(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG));
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) { if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) {
await MSP.promise(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG)); await MSP.promise(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG));
} }
await MSP.promise(MSPCodes.MSP_EEPROM_WRITE);
tracking.sendSaveAndChangeEvents(tracking.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges, 'motors'); tracking.sendSaveAndChangeEvents(tracking.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges, 'motors');
self.analyticsChanges = {}; self.analyticsChanges = {};
self.configHasChanged = false; self.configHasChanged = false;
reboot(); mspHelper.writeConfiguration(reboot);
}); });
$('a.stop').on('click', () => motorsEnableTestModeElement.prop('checked', false).trigger('change')); $('a.stop').on('click', () => motorsEnableTestModeElement.prop('checked', false).trigger('change'));

View File

@ -59,7 +59,7 @@ onboard_logging.initialize = function (callback) {
} }
function save_to_eeprom() { function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, reboot); mspHelper.writeConfiguration(reboot);
} }
function reboot() { function reboot() {

View File

@ -9,7 +9,6 @@ import MSP from '../msp';
import MSPCodes from '../msp/MSPCodes'; import MSPCodes from '../msp/MSPCodes';
import { API_VERSION_1_42, API_VERSION_1_43, API_VERSION_1_45 } from '../data_storage'; import { API_VERSION_1_42, API_VERSION_1_43, API_VERSION_1_45 } from '../data_storage';
import BOARD from '../boards'; import BOARD from '../boards';
import { gui_log } from '../gui_log';
const ports = { const ports = {
analyticsChanges: {}, analyticsChanges: {},
@ -357,7 +356,7 @@ ports.initialize = function (callback) {
GUI.content_ready(callback); GUI.content_ready(callback);
} }
function on_save_handler() { function on_save_handler() {
tracking.sendSaveAndChangeEvents(tracking.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges, 'ports'); tracking.sendSaveAndChangeEvents(tracking.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges, 'ports');
self.analyticsChanges = {}; self.analyticsChanges = {};
@ -488,14 +487,10 @@ ports.initialize = function (callback) {
} }
function save_to_eeprom() { function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, on_saved_handler); mspHelper.writeConfiguration(function() {
} GUI.tab_switch_cleanup(function() {
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitializeConnection);
function on_saved_handler() { });
gui_log(i18n.getMessage('configurationEepromSaved'));
GUI.tab_switch_cleanup(function() {
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitializeConnection);
}); });
} }
} }

View File

@ -500,7 +500,7 @@ power.initialize = function (callback) {
} }
function save_to_eeprom() { function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, save_completed); mspHelper.writeConfiguration(save_completed);
} }
function save_completed() { function save_completed() {

View File

@ -139,7 +139,7 @@ servos.initialize = function (callback) {
function save_to_eeprom() { function save_to_eeprom() {
if (save_configuration_to_eeprom) { if (save_configuration_to_eeprom) {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function () { mspHelper.writeConfiguration(function () {
gui_log(i18n.getMessage('servosEepromSave')); gui_log(i18n.getMessage('servosEepromSave'));
}); });
} }

View File

@ -903,7 +903,7 @@ vtx.initialize = function (callback) {
} }
function save_to_eeprom() { function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, save_completed); mspHelper.writeConfiguration(save_completed);
} }
function save_completed() { function save_completed() {