From fa31c128dd16138939da66150343ec3dbe412f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Mi=C5=A1i=C4=87?= Date: Wed, 15 Feb 2023 11:33:54 +0100 Subject: [PATCH] Parameter transition from block device to LittleFS This commit can be reverted after the transition period --- ROMFS/px4fmu_common/init.d/rcS | 14 ++++ .../include/px4_platform_common/px4_mtd.h | 12 +++ platforms/nuttx/src/px4/common/px4_mtd.cpp | 79 ++++++++++++++++++- src/systemcmds/param/param.cpp | 41 ++++++++++ 4 files changed, 145 insertions(+), 1 deletion(-) diff --git a/ROMFS/px4fmu_common/init.d/rcS b/ROMFS/px4fmu_common/init.d/rcS index f5bfbf9856..b38dcd1eaf 100644 --- a/ROMFS/px4fmu_common/init.d/rcS +++ b/ROMFS/px4fmu_common/init.d/rcS @@ -113,6 +113,20 @@ else if mft query -q -k MTD -s MTD_PARAMETERS -v /fs/mtd_params then set PARAM_FILE /fs/mtd_params/parameters.bson + else + # Revert after the transition period is completed + set PARAM_FILE /fs/mtd_params/parameters.bson + param select $PARAM_FILE + echo "Start parameter transition to LittleFS" + if ! param transition + then + echo "ERROR [init] param transition" + else + echo "Successful param transition. The system will reboot!" + # Wait for UART to send messages + usleep 200000 + reboot + fi fi # diff --git a/platforms/common/include/px4_platform_common/px4_mtd.h b/platforms/common/include/px4_platform_common/px4_mtd.h index 7313bd78a9..7bcac10880 100644 --- a/platforms/common/include/px4_platform_common/px4_mtd.h +++ b/platforms/common/include/px4_platform_common/px4_mtd.h @@ -77,6 +77,18 @@ __EXPORT int px4_mtd_get_geometry(const mtd_instance_s *instance, unsigned long */ __EXPORT ssize_t px4_mtd_get_partition_size(const mtd_instance_s *instance, const char *partname); +/* + Helper function for transition to LittleFS. + It will unmount MTD for parameters with LittleFS and mount Block Device +*/ +__EXPORT int px4_mtd_unmount_littlefs_mount_block_device(void); + +/* + Helper function for transition to LittleFS. + It will unmount MTD for parameters with Block Device and mount LittleFS with auto formatting +*/ +__EXPORT int px4_mtd_unmount_block_device_mount_littlefs(void); + int px4_at24c_initialize(FAR struct i2c_master_s *dev, uint8_t address, FAR struct mtd_dev_s **mtd_dev); diff --git a/platforms/nuttx/src/px4/common/px4_mtd.cpp b/platforms/nuttx/src/px4/common/px4_mtd.cpp index e1f76be6d1..459b680325 100644 --- a/platforms/nuttx/src/px4/common/px4_mtd.cpp +++ b/platforms/nuttx/src/px4/common/px4_mtd.cpp @@ -70,6 +70,10 @@ static int num_instances = 0; static int total_blocks = 0; static mtd_instance_s *instances[MAX_MTD_INSTANCES] = {}; +static uint8_t param_instance = 0; +static uint8_t param_part = 0; +static uint8_t param_block = 0; + static int ramtron_attach(mtd_instance_s &instance) { @@ -396,6 +400,10 @@ memoryout: if (instances[i]->partition_types[part] == MTD_PARAMETERS) { + param_instance = i; + param_part = part; + param_block = total_blocks; + rv = register_mtddriver(blockname, instances[i]->part_dev[part], 0755, nullptr); if (rv < 0) { @@ -404,7 +412,8 @@ memoryout: } // Now create a character device on the block device - rv = nx_mount(blockname, instances[i]->partition_names[part], "littlefs", 0, "autoformat"); + //TODO: after the transition period return "autoformat" + rv = nx_mount(blockname, instances[i]->partition_names[part], "littlefs", 0, ""); printf("nx_mount: blockname: %s partition: %s\n", blockname, instances[i]->partition_names[part]); @@ -493,4 +502,72 @@ __EXPORT int px4_mtd_query(const char *sub, const char *val, const char **get) return rv; } +int px4_mtd_unmount_littlefs_mount_block_device(void) +{ + char blockname[32]; + snprintf(blockname, sizeof(blockname), "/dev/mtdblock%d", param_block); + + // in case if it is mounted + nx_umount2(instances[param_instance]->partition_names[param_part], 0); + + int ret = unregister_mtddriver(blockname); + + if (ret < 0) { + PX4_ERR("unregister_mtddriver fail: %d", ret); + + } else { + ret = ftl_initialize(0, instances[0]->part_dev[0]); + + if (ret < 0) { + PX4_ERR("ftl_initialize failed: %d", ret); + + } else { + ret = bchdev_register(blockname, instances[param_instance]->partition_names[param_part], false); + + if (ret < 0) { + PX4_ERR("bchdev_register failed: %d", ret); + + } + } + } + + return ret; +} + +int px4_mtd_unmount_block_device_mount_littlefs(void) +{ + char blockname[32]; + snprintf(blockname, sizeof(blockname), "/dev/mtdblock%d", param_block); + + int ret = bchdev_unregister(instances[param_instance]->partition_names[param_part]); + + if (ret < 0) { + PX4_ERR("bchdev_unregister %s failed: %d", instances[param_instance]->partition_names[param_part], ret); + + } else { + ret = unregister_blockdriver(blockname); + + if (ret < 0) { + PX4_ERR("unregister_blockdriver %s failed: %d", blockname, ret); + + } else { + ret = register_mtddriver(blockname, instances[param_instance]->part_dev[param_part], 0755, nullptr); + + if (ret < 0) { + PX4_ERR("register_mtddriver %s failed: %d", blockname, ret); + + } else { + ret = nx_mount(blockname, instances[param_instance]->partition_names[param_part], "littlefs", 0, "forceformat"); + + if (ret < 0) { + PX4_ERR("nx_mount %s failed: %d", instances[param_instance]->partition_names[param_part], ret); + + } + } + } + } + + return ret; +} + #endif // CONFIG_MTD diff --git a/src/systemcmds/param/param.cpp b/src/systemcmds/param/param.cpp index 2f7842f126..300323f585 100644 --- a/src/systemcmds/param/param.cpp +++ b/src/systemcmds/param/param.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,7 @@ enum class COMPARE_ERROR_LEVEL { static int do_save(const char *param_file_name); static int do_save_default(); static int do_load(const char *param_file_name); +static int do_transition(); static int do_import(const char *param_file_name = nullptr); static int do_show(const char *search_string, bool only_changed); static int do_show_for_airframe(); @@ -218,6 +220,11 @@ param_main(int argc, char *argv[]) } } + // Delete after the transition period is completed + if (!strcmp(argv[1], "transition")) { + return do_transition(); + } + if (!strcmp(argv[1], "import")) { if (argc >= 3) { return do_import(argv[2]); @@ -466,6 +473,40 @@ do_load(const char *param_file_name) return 0; } +static int +do_transition() +{ +#ifdef __PX4_NUTTX + + int ret_val = px4_mtd_unmount_littlefs_mount_block_device(); + + if (ret_val < 0) { + PX4_ERR("Transition from LittleFS to Blockdriver"); + } else { + ret_val = do_import("/fs/mtd_params"); + + if (ret_val < 0) { + PX4_ERR("Import from blockdriver"); + } else { + ret_val = px4_mtd_unmount_block_device_mount_littlefs(); + + if (ret_val < 0){ + PX4_ERR("Transition from Blockdriver to LittleFS failed"); + } else { + ret_val = param_export(param_get_default_file(), nullptr); + } + } + } + + if (ret_val < 0) { + return 1; + } + +#endif + + return 0; +} + static int do_import(const char *param_file_name) {