From 1e59a592a6a41a65e9e69814ae3d8cb62a061367 Mon Sep 17 00:00:00 2001 From: px4dev Date: Tue, 9 Oct 2012 22:45:36 -0700 Subject: [PATCH] Split the parameter load/save commands out of the 'eeprom' command, since that's not really the obvious place for them. Add parameter printing functionality (though, it's a mess due to %f being busted) Update the script examples to use the new command. --- ROMFS/scripts/rc.FMU_quad_x | 2 +- ROMFS/scripts/rc.PX4IOAR | 2 +- ROMFS/scripts/rc.standalone | 10 ++ apps/systemcmds/bl_update/bl_update.c | 1 - apps/systemcmds/eeprom/eeprom.c | 4 + apps/systemcmds/param/Makefile | 42 ++++++ apps/systemcmds/param/param.c | 185 ++++++++++++++++++++++++++ apps/systemlib/param/param.c | 58 ++++++-- apps/systemlib/param/param.h | 17 ++- nuttx/configs/px4fmu/nsh/appconfig | 1 + 10 files changed, 307 insertions(+), 15 deletions(-) create mode 100644 apps/systemcmds/param/Makefile create mode 100644 apps/systemcmds/param/param.c diff --git a/ROMFS/scripts/rc.FMU_quad_x b/ROMFS/scripts/rc.FMU_quad_x index 94ed2be18b..e9f07b4a29 100644 --- a/ROMFS/scripts/rc.FMU_quad_x +++ b/ROMFS/scripts/rc.FMU_quad_x @@ -9,7 +9,7 @@ echo "[init] eeprom" eeprom start if [ -f /eeprom/parameters ] then - eeprom load_param /eeprom/parameters + param load fi echo "[init] sensors" diff --git a/ROMFS/scripts/rc.PX4IOAR b/ROMFS/scripts/rc.PX4IOAR index 532dd6a256..382d8e25c0 100644 --- a/ROMFS/scripts/rc.PX4IOAR +++ b/ROMFS/scripts/rc.PX4IOAR @@ -19,7 +19,7 @@ echo "[init] eeprom" eeprom start if [ -f /eeprom/parameters ] then - eeprom load_param /eeprom/parameters + param load fi # diff --git a/ROMFS/scripts/rc.standalone b/ROMFS/scripts/rc.standalone index 7dfd98a166..8ccdb577b5 100644 --- a/ROMFS/scripts/rc.standalone +++ b/ROMFS/scripts/rc.standalone @@ -10,6 +10,16 @@ echo "[init] doing standalone PX4FMU startup..." # uorb start +# +# Init the EEPROM +# +echo "[init] eeprom" +eeprom start +if [ -f /eeprom/parameters ] +then + param load +fi + # # Start the sensors. # diff --git a/apps/systemcmds/bl_update/bl_update.c b/apps/systemcmds/bl_update/bl_update.c index ac3e93be14..752c01986a 100644 --- a/apps/systemcmds/bl_update/bl_update.c +++ b/apps/systemcmds/bl_update/bl_update.c @@ -51,7 +51,6 @@ #include #include "systemlib/systemlib.h" -#include "systemlib/param/param.h" #include "systemlib/err.h" __EXPORT int bl_update_main(int argc, char *argv[]); diff --git a/apps/systemcmds/eeprom/eeprom.c b/apps/systemcmds/eeprom/eeprom.c index a0b15f77b7..fa88fa09e5 100644 --- a/apps/systemcmds/eeprom/eeprom.c +++ b/apps/systemcmds/eeprom/eeprom.c @@ -193,6 +193,8 @@ eeprom_save(const char *name) if (!name) err(1, "missing argument for device name, try '/eeprom/parameters'"); + warnx("WARNING: 'eeprom save_param' deprecated - use 'param save' instead"); + /* delete the file in case it exists */ unlink(name); @@ -222,6 +224,8 @@ eeprom_load(const char *name) if (!name) err(1, "missing argument for device name, try '/eeprom/parameters'"); + warnx("WARNING: 'eeprom load_param' deprecated - use 'param load' instead"); + int fd = open(name, O_RDONLY); if (fd < 0) diff --git a/apps/systemcmds/param/Makefile b/apps/systemcmds/param/Makefile new file mode 100644 index 0000000000..603746a206 --- /dev/null +++ b/apps/systemcmds/param/Makefile @@ -0,0 +1,42 @@ +############################################################################ +# +# Copyright (C) 2012 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. +# +############################################################################ + +# +# Build the parameters tool. +# + +APPNAME = param +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 4096 + +include $(APPDIR)/mk/app.mk diff --git a/apps/systemcmds/param/param.c b/apps/systemcmds/param/param.c new file mode 100644 index 0000000000..199bffed5b --- /dev/null +++ b/apps/systemcmds/param/param.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * Author: Lorenz Meier + * + * 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 param.c + * + * Parameter tool. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "systemlib/systemlib.h" +#include "systemlib/param/param.h" +#include "systemlib/err.h" + +__EXPORT int param_main(int argc, char *argv[]); + +static void do_save(void); +static void do_load(void); +static void do_import(void); +static void do_show(void); +static void do_show_print(void *arg, param_t param); + +static const char *param_file_name = "/eeprom/parameters"; + +int +param_main(int argc, char *argv[]) +{ + if (argc >= 2) { + if (!strcmp(argv[1], "save")) + do_save(); + if (!strcmp(argv[1], "load")) + do_load(); + if (!strcmp(argv[1], "import")) + do_import(); + if (!strcmp(argv[1], "show")) + do_show(); + } + + errx(1, "expected a command, try 'load', 'import', 'show' or 'save'\n"); +} + +static void +do_save(void) +{ + /* delete the parameter file in case it exists */ + unlink(param_file_name); + + /* create the file */ + int fd = open(param_file_name, O_WRONLY | O_CREAT | O_EXCL); + + if (fd < 0) + err(1, "opening '%s' failed", param_file_name); + + int result = param_export(fd, false); + close(fd); + + if (result < 0) { + unlink(param_file_name); + errx(1, "error exporting to '%s'", param_file_name); + } + + exit(0); +} + +static void +do_load(void) +{ + int fd = open(param_file_name, O_RDONLY); + + if (fd < 0) + err(1, "open '%s'", param_file_name); + + int result = param_load(fd); + close(fd); + + if (result < 0) + errx(1, "error importing from '%s'", param_file_name); + + exit(0); +} + +static void +do_import(void) +{ + int fd = open(param_file_name, O_RDONLY); + + if (fd < 0) + err(1, "open '%s'", param_file_name); + + int result = param_import(fd); + close(fd); + + if (result < 0) + errx(1, "error importing from '%s'", param_file_name); + + exit(0); +} + +static void +do_show(void) +{ + printf(" + = saved, * = unsaved (warning, floating-point values are often printed with the decimal point wrong)\n"); + param_foreach(do_show_print, NULL, false); + + exit(0); +} + +static void +do_show_print(void *arg, param_t param) +{ + int32_t i; + float f; + + printf("%c %s: ", + param_value_unsaved(param) ? '*' : (param_value_is_default(param) ? ' ' : '+'), + param_name(param)); + + /* + * This case can be expanded to handle printing common structure types. + */ + + switch (param_type(param)) { + case PARAM_TYPE_INT32: + if (!param_get(param, &i)) { + printf("%d\n", i); + return; + } + break; + case PARAM_TYPE_FLOAT: + if (!param_get(param, &f)) { + printf("%4.4f\n", (double)f); + return; + } + break; + case PARAM_TYPE_STRUCT ... PARAM_TYPE_STRUCT_MAX: + printf("\n", 0 + param_type(param), param_size(param)); + return; + default: + printf("\n", 0 + param_type(param)); + return; + } + printf("\n", param); +} diff --git a/apps/systemlib/param/param.c b/apps/systemlib/param/param.c index 0ab7c0ea30..9e886ea651 100644 --- a/apps/systemlib/param/param.c +++ b/apps/systemlib/param/param.c @@ -242,6 +242,25 @@ param_name(param_t param) return NULL; } +bool +param_value_is_default(param_t param) +{ + return param_find_changed(param) ? false : true; +} + +bool +param_value_unsaved(param_t param) +{ + static struct param_wbuf_s *s; + + s = param_find_changed(param); + + if (s && s->unsaved) + return true; + + return false; +} + enum param_type_e param_type(param_t param) { @@ -330,8 +349,8 @@ param_get(param_t param, void *val) return result; } -int -param_set(param_t param, const void *val) +static int +param_set_internal(param_t param, const void *val, bool mark_saved) { int result = -1; bool params_changed = false; @@ -394,7 +413,7 @@ param_set(param_t param, const void *val) goto out; } - s->unsaved = true; + s->unsaved = !mark_saved; params_changed = true; result = 0; } @@ -412,6 +431,12 @@ out: return result; } +int +param_set(param_t param, const void *val) +{ + return param_set_internal(param, val, false); +} + void param_reset(param_t param) { @@ -535,6 +560,11 @@ out: return result; } +struct param_import_state +{ + bool mark_saved; +}; + static int param_import_callback(bson_decoder_t decoder, void *private, bson_node_t node) { @@ -542,13 +572,13 @@ param_import_callback(bson_decoder_t decoder, void *private, bson_node_t node) int32_t i; void *v, *tmp = NULL; int result = -1; + struct param_import_state *state = (struct param_import_state *)private; /* * EOO means the end of the parameter object. (Currently not supporting * nested BSON objects). */ if (node->type == BSON_EOO) { - *(bool *)private = true; debug("end of parameters"); return 0; } @@ -621,7 +651,7 @@ param_import_callback(bson_decoder_t decoder, void *private, bson_node_t node) goto out; } - if (param_set(param, v)) { + if (param_set_internal(param, v, state->mark_saved)) { debug("error setting value for '%s'", node->name); goto out; } @@ -642,19 +672,19 @@ out: return result; } -int -param_import(int fd) +static int +param_import_internal(int fd, bool mark_saved) { - bool done; struct bson_decoder_s decoder; int result = -1; + struct param_import_state state; - if (bson_decoder_init(&decoder, fd, param_import_callback, &done)) { + if (bson_decoder_init(&decoder, fd, param_import_callback, &state)) { debug("decoder init failed"); goto out; } - done = false; + state.mark_saved = mark_saved; do { result = bson_decoder_next(&decoder); @@ -668,11 +698,17 @@ out: return result; } +int +param_import(int fd) +{ + return param_import_internal(fd, false); +} + int param_load(int fd) { param_reset_all(); - return param_import(fd); + return param_import_internal(fd, true); } void diff --git a/apps/systemlib/param/param.h b/apps/systemlib/param/param.h index ffce07a4ed..41e268db08 100644 --- a/apps/systemlib/param/param.h +++ b/apps/systemlib/param/param.h @@ -121,6 +121,20 @@ __EXPORT int param_get_index(param_t param); */ __EXPORT const char *param_name(param_t param); +/** + * Test whether a parameter's value has changed from the default. + * + * @return If true, the parameter's value has not been changed from the default. + */ +__EXPORT bool param_value_is_default(param_t param); + +/** + * Test whether a parameter's value has been changed but not saved. + * + * @return If true, the parameter's value has not been saved. + */ +__EXPORT bool param_value_unsaved(param_t param); + /** * Obtain the type of a parameter. * @@ -160,7 +174,8 @@ __EXPORT int param_set(param_t param, const void *val); /** * Reset a parameter to its default value. * - * This function frees any storage used by struct parameters, but scalar parameters + * This function frees any storage used by struct parameters, and returns the parameter + * to its default value. * * @param param A handle returned by param_find or passed by param_foreach. */ diff --git a/nuttx/configs/px4fmu/nsh/appconfig b/nuttx/configs/px4fmu/nsh/appconfig index e76c4cf482..be0a3d1d71 100644 --- a/nuttx/configs/px4fmu/nsh/appconfig +++ b/nuttx/configs/px4fmu/nsh/appconfig @@ -53,6 +53,7 @@ CONFIGURED_APPS += systemcmds/boardinfo CONFIGURED_APPS += systemcmds/mixer CONFIGURED_APPS += systemcmds/eeprom CONFIGURED_APPS += systemcmds/led +CONFIGURED_APPS += systemcmds/param CONFIGURED_APPS += systemcmds/bl_update #CONFIGURED_APPS += systemcmds/calibration