Files
inav/docs/development/Backup Restore Architecture.md
admin dac37fd077
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
Sync inav to Gitea
2026-08-03 16:37:40 +08:00

12 KiB

Backup, Restore & Settings Migration — Architecture

Note: This document describes the internals of the INAV Configurator's backup/restore and settings migration system. It is intended for Configurator developers, not end users. For user-facing documentation, see the INAV docs.

Architecture Overview

User → Firmware Flasher Tab → STM32.connect(onCliReady) → CLI mode
                                                              ↓
                                          BackupRestore.captureCliDiffAll()
                                                              ↓
                                           Save to file, prune old backups
                                                              ↓
                                               STM32 flash (DFU or serial)
                                                              ↓
                                              onFlashComplete() callback
                                                              ↓
                                      Version check → Migration check → UI overlay
                                                              ↓
                                      User confirms → Poll for FC reconnect
                                                              ↓
                        BackupRestore.performRestore() or performRestoreWithMigration()
                                                              ↓
                                    saveAndReboot() or abortRestore()

Files

File Purpose
js/backup_restore.js Core backup/restore module — CLI protocol, file I/O, auto-backup
js/migration/migration_handler.js Version migration engine — profile chaining, line transformation
js/migration/7_to_8.json Migration profile: INAV 7.x → 8.0
js/migration/8_to_9.json Migration profile: INAV 8.0 → 9.0
tabs/firmware_flasher.js Flash integration — auto-backup trigger, restore UI, version gating
tabs/firmware_flasher.html Overlays and buttons for backup/restore/migration UI
src/css/tabs/firmware_flasher.css Overlay styles
js/protocols/stm32.js STM32 flash protocol — onCliReady callback, DFU timeout fix
js/main/main.js Electron main process — IPC handlers for file operations
js/main/preload.js IPC bridge — exposes backup API to renderer
locale/en/messages.json All i18n translation keys

Adding a New Migration Profile

When a new major INAV version is released (e.g. 9.x → 10.x), create a migration profile:

Step 1: Create the JSON profile

Create js/migration/9_to_10.json:

{
    "fromVersion": "9",
    "toVersion": "10",
    "description": "INAV 9.x → 10.0 migration profile",

    "commandRenames": {
        "old_command_name": "new_command_name"
    },

    "settingRenames": {
        "old_setting_name": "new_setting_name"
    },

    "valueReplacements": {
        "setting_name": {
            "OLD_VALUE": "NEW_VALUE"
        }
    },

    "removed": [
        "deleted_setting_1",
        "deleted_setting_2"
    ],

    "settingPatternMappings": [
        {
            "pattern": "^regex_matching_setting_names$",
            "valueMap": { "old_numeric_id": "new_numeric_id" },
            "description": "Human-readable description of remapping"
        }
    ],

    "warnings": [
        "Human-readable warning about settings whose semantics changed and need manual review."
    ]
}

Step 2: Register the profile

In js/migration/migration_handler.js, add the import and append to the array:

import profile_9_to_10 from './9_to_10.json';

const MIGRATION_PROFILES = [
    profile_7_to_8,
    profile_8_to_9,
    profile_9_to_10,   // ← add here
];

The migration engine automatically chains profiles. A 7.x → 10.x upgrade will apply all three profiles in sequence (7→8, 8→9, 9→10).

How to determine what goes into a migration profile

Compare CLI settings between the old and new firmware version:

  1. Removed settings: Run diff all on old and new firmware with default settings. Settings present in old but not in new → add to removed
  2. Renamed settings: Check INAV release notes and source code for renamed settings → add to settingRenames
  3. Renamed commands: Check for CLI command name changes (e.g. profilecontrol_profile) → add to commandRenames
  4. Value replacements: Check for enum value name changes → add to valueReplacements
  5. Pattern mappings: Check for bulk ID renumbering (OSD elements, etc.) → add to settingPatternMappings
  6. Warnings: Check for settings where the meaning/units changed but name stayed the same → add to warnings

Key INAV source files to check:

  • src/main/fc/settings.yaml — all CLI settings definitions
  • src/main/fc/cli.c — CLI command implementations
  • Release notes on GitHub

Migration Profile Schema Reference

Field Type Required Description
fromVersion string Yes Source major version number (e.g. "9")
toVersion string Yes Target major version number (e.g. "10")
description string Yes Human-readable description
commandRenames object Yes Maps old CLI command names to new names. Applied to any token in the command line. E.g. "profile" → "control_profile" transforms profile 2 to control_profile 2
settingRenames object Yes Maps old set setting names to new names. Only applies to set <name> = <value> lines
valueReplacements object Yes Maps setting names to value replacement objects { "oldval": "newval" }. Only modifies the value portion after =
removed string[] Yes List of setting names to remove entirely. Lines with set <name> = ... matching these are dropped
settingPatternMappings array Yes Array of pattern-based value remappings for settings matching a regex. Each entry has pattern (regex), valueMap (object), description (string)
warnings string[] Yes Warning messages about semantic changes requiring manual review. Displayed in migration preview overlay

Existing Migration Profile Details

7_to_8.json (INAV 7.x → 8.0)

Category Changes
Command renames profilecontrol_profile
Value replacements gps_provider: UBLOX7UBLOX
Removed settings (18) control_deadband, cpu_underclock, disarm_kill_switch, dji_workarounds, fw_iterm_limit_stick_position, gyro_anti_aliasing_lpf_type, gyro_hardware_lpf, gyro_main_lpf_type, gyro_use_dyn_lpf, inav_use_gps_no_baro, inav_use_gps_velned, ledstrip_visual_beeper, max_throttle, nav_auto_climb_rate, nav_manual_climb_rate, osd_stats_min_voltage_unit, pidsum_limit, pidsum_limit_yaw
Pattern mappings osd_custom_element_N_type: IDs remapped 4→9, 5→16, 6→7, 7→10
Warnings nav_fw_wp_tracking_accuracy semantics changed: was arbitrary tracking response, now distance in meters

8_to_9.json (INAV 8.0 → 9.0)

Category Changes
Command renames controlrate_profileuse_control_profile
Setting renames mixer_pid_profile_linkingmixer_control_profile_linking, osd_pan_servo_pwm2centidegosd_pan_servo_range_decadegrees
Value replacements None
Removed settings None
Pattern mappings None
Warnings Position estimator defaults changed (w_z_baro_v, inav_w_z_gps_p, inav_w_z_gps_v). ahrs_acc_ignore_rate default changed 20→15

Migration Engine Internals

Profile chaining

buildMigrationChain(fromVersion, toVersion) selects all profiles where profileFrom >= fromMajor and profileTo <= toMajor, sorted by fromVersion. A 7.x → 9.x migration applies both 7→8 and 8→9 profiles in sequence.

Line processing

Each non-comment, non-empty line passes through every profile in the chain. For each profile, transformations are applied in this order:

  1. Command renames (any token in the line)
  2. Removed settings (line dropped if set <name> matches)
  3. Setting renames (set <name> replacement)
  4. Value replacements (value after = replaced)
  5. Setting pattern mappings (regex-matched settings with value remapping)

Missing profile detection

hasMissingProfiles() returns true when the number of profiles in the chain is fewer than the number of major version steps. The UI shows a warning but still allows restore — some settings may fail.

Edge Cases Handled

  1. Stale FC version after flash: Real FC version is queried via MSP_FC_VERSION after connect, not the cached value
  2. DFU mode (no MSP): FC.CONFIG null checks prevent crashes when connected in DFU mode
  3. DFU timeout: UI unlock and progress label update on timeout (no permanent lock)
  4. Local firmware files: localFirmwareLoaded flag prevents stale dropdown version from triggering wrong migration
  5. Backup pruning with mixed versions: Sort by timestamp portion, not full filename
  6. Multi-step migration: 7.x → 9.x automatically chains 7→8 + 8→9 profiles
  7. Missing migration profiles: Warning shown but restore allowed — graceful degradation
  8. Version detection from backup: Parsed from backup header (# Version: X.Y.Z), not from FC state

i18n Keys

All backup/restore/migration translation keys in locale/en/messages.json:

Backup status

Key Text
backupRestoreStatusEnteringCli Entering CLI
backupRestoreStatusReadingConfig Reading configuration via CLI
backupRestoreStatusSavingFile Saving backup file...
backupRestoreStatusExitingCli Exiting CLI mode
backupRestoreBackupSaved Backup saved $1
backupRestoreAutoBackupSaved Auto-backup saved to $1
backupRestoreBackupComplete Backup complete
backupRestoreBackupCancelled Backup cancelled
backupRestoreBackupFailed Backup failed

Restore status

Key Text
backupRestoreStatusConnecting Connecting to flight controller
backupRestoreStatusRestoringConfig Restoring configuration
backupRestoreStatusRestoringProgress Restoring... $1 / $2
backupRestoreStatusSaving Saving configuration
backupRestoreRestoreComplete Configuration restored. Flight controller is rebooting.
backupRestoreRestoreCancelled Restore cancelled.
backupRestoreRestoreFailed Restore failed.

Auto-restore UI

Key Text
backupRestoreAutoRestoreConfirm Restore confirmation prompt
backupRestoreAutoRestoreWaiting Waiting for FC to reboot after flash
backupRestoreAutoRestoreYes Yes, restore settings
backupRestoreAutoRestoreNo No, keep current settings
backupRestoreAutoRestoreWaitingPort Waiting for port $1 to reconnect
backupRestoreDowngradeNoAutoRestore Major downgrade warning
backupRestoreFlashCompleteBackupSaved Backup saved (local firmware, no restore offer)
backupRestoreMigrationApplied Migration applied: $1 → $2 ($3 changes)
backupRestoreMigrationWarningsHeader Migration Warnings:

Migration preview

Key Text
migrationPreviewTitle Settings Migration Required
migrationPreviewSubtitle Conversion explanation
migrationPreviewRemovedHeader Removed Settings:
migrationPreviewRenamedSettingsHeader Renamed Settings:
migrationPreviewRenamedCommandsHeader Renamed Commands:
migrationPreviewValueReplacementsHeader Value Replacements:
migrationPreviewSettingRemappingsHeader Setting Remappings:
migrationPreviewContinue Continue with migration
migrationPreviewCancel Cancel restore
migrationMissingProfileWarning Missing profile warning

Error messages

Key Text
backupRestoreErrorTitle Restore Errors Detected
backupRestoreErrorText Error explanation
backupRestoreErrorAbort Abort
backupRestoreErrorSave Save anyway