mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
parameters: merge generated files ito single static constexpr header
- store parameter type and if volatile separately (saves kilobytes of flash)
- use Bitset for tracking active and changed parameters
- use atomic for autosave_enabled flag
- compile at ${MAX_CUSTOM_OPT_LEVEL} (-O2 on non flash constrained boards)
This commit is contained in:
parent
71c7c69c9d
commit
da1a38b44e
3
.gitignore
vendored
3
.gitignore
vendored
@ -101,9 +101,6 @@ msg/tmp/
|
||||
msg/topics_sources/
|
||||
platforms/posix/apps.cpp
|
||||
platforms/posix/apps.h
|
||||
src/lib/parameters/px4_parameters.c
|
||||
src/lib/parameters/px4_parameters.h
|
||||
src/lib/parameters/px4_parameters_public.h
|
||||
src/lib/version/build_git_version.h
|
||||
src/modules/simulator/simulator_config.h
|
||||
src/systemcmds/topic_listener/listener_generated.cpp
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
# workaround for syslink parameter PARAM_DEFINE_INT32(SLNK_RADIO_ADDR2, 3890735079); // 0xE7E7E7E7
|
||||
add_compile_options(-Wno-narrowing)
|
||||
|
||||
px4_add_board(
|
||||
PLATFORM nuttx
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
# workaround for syslink parameter PARAM_DEFINE_INT32(SLNK_RADIO_ADDR2, 3890735079); // 0xE7E7E7E7
|
||||
add_compile_options(-Wno-narrowing)
|
||||
|
||||
px4_add_board(
|
||||
PLATFORM nuttx
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
#include "param_macros.h"
|
||||
|
||||
#include <parameters/px4_parameters_public.h>
|
||||
#include <parameters/px4_parameters.hpp>
|
||||
|
||||
/**
|
||||
* get the parameter handle from a parameter enum
|
||||
@ -112,7 +112,7 @@ class Param<float, p>
|
||||
{
|
||||
public:
|
||||
// static type-check
|
||||
static_assert(px4::param_types_array[(int)p] == PARAM_TYPE_FLOAT, "parameter type must be float");
|
||||
static_assert(px4::parameters_type[(int)p] == PARAM_TYPE_FLOAT, "parameter type must be float");
|
||||
|
||||
Param()
|
||||
{
|
||||
@ -151,7 +151,7 @@ class Param<float &, p>
|
||||
{
|
||||
public:
|
||||
// static type-check
|
||||
static_assert(px4::param_types_array[(int)p] == PARAM_TYPE_FLOAT, "parameter type must be float");
|
||||
static_assert(px4::parameters_type[(int)p] == PARAM_TYPE_FLOAT, "parameter type must be float");
|
||||
|
||||
Param(float &external_val)
|
||||
: _val(external_val)
|
||||
@ -190,7 +190,7 @@ class Param<int32_t, p>
|
||||
{
|
||||
public:
|
||||
// static type-check
|
||||
static_assert(px4::param_types_array[(int)p] == PARAM_TYPE_INT32, "parameter type must be int32_t");
|
||||
static_assert(px4::parameters_type[(int)p] == PARAM_TYPE_INT32, "parameter type must be int32_t");
|
||||
|
||||
Param()
|
||||
{
|
||||
@ -229,7 +229,7 @@ class Param<int32_t &, p>
|
||||
{
|
||||
public:
|
||||
// static type-check
|
||||
static_assert(px4::param_types_array[(int)p] == PARAM_TYPE_INT32, "parameter type must be int32_t");
|
||||
static_assert(px4::parameters_type[(int)p] == PARAM_TYPE_INT32, "parameter type must be int32_t");
|
||||
|
||||
Param(int32_t &external_val)
|
||||
: _val(external_val)
|
||||
@ -268,7 +268,7 @@ class Param<bool, p>
|
||||
{
|
||||
public:
|
||||
// static type-check
|
||||
static_assert(px4::param_types_array[(int)p] == PARAM_TYPE_INT32, "parameter type must be int32_t");
|
||||
static_assert(px4::parameters_type[(int)p] == PARAM_TYPE_INT32, "parameter type must be int32_t");
|
||||
|
||||
Param()
|
||||
{
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
add_compile_options(${MAX_CUSTOM_OPT_LEVEL})
|
||||
|
||||
add_subdirectory(tinybson)
|
||||
|
||||
if (NOT PARAM_DEFAULT_OVERRIDES)
|
||||
@ -113,16 +115,14 @@ add_custom_command(OUTPUT ${parameters_xml} ${parameters_json} ${parameters_json
|
||||
)
|
||||
add_custom_target(parameters_xml DEPENDS ${parameters_xml})
|
||||
|
||||
# generate px4_parameters.c and px4_parameters{,_public}.h
|
||||
add_custom_command(OUTPUT px4_parameters.c px4_parameters.h px4_parameters_public.h
|
||||
# generate px4_parameters.hpp
|
||||
add_custom_command(OUTPUT px4_parameters.hpp
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/px_generate_params.py
|
||||
--xml ${parameters_xml} --dest ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${PX4_BINARY_DIR}/parameters.xml
|
||||
px_generate_params.py
|
||||
templates/px4_parameters.c.jinja
|
||||
templates/px4_parameters.h.jinja
|
||||
templates/px4_parameters_public.h.jinja
|
||||
templates/px4_parameters.hpp.jinja
|
||||
)
|
||||
|
||||
set(SRCS)
|
||||
@ -147,10 +147,8 @@ endif()
|
||||
if (NOT "${PX4_BOARD}" MATCHES "px4_io")
|
||||
add_library(parameters
|
||||
${SRCS}
|
||||
px4_parameters.c
|
||||
px4_parameters.h
|
||||
px4_parameters_public.h
|
||||
)
|
||||
px4_parameters.hpp
|
||||
)
|
||||
|
||||
if ("${CONFIG_SHMEM}" STREQUAL "1")
|
||||
target_link_libraries(parameters PRIVATE px4_layer)
|
||||
|
||||
@ -435,25 +435,7 @@ union param_value_u {
|
||||
* instead.
|
||||
*/
|
||||
struct param_info_s {
|
||||
const char *name
|
||||
|
||||
// GCC 4.8 and higher don't implement proper alignment of static data on
|
||||
// 64-bit. This means that the 24-byte param_info_s variables are
|
||||
// 16 byte aligned by GCC and that messes up the assumption that
|
||||
// sequential items in the __param segment can be addressed as an array.
|
||||
// The assumption is that the address of the second parameter is at
|
||||
// ¶m[0]+sizeof(param[0]). When compiled with clang it is
|
||||
// true, with gcc is is not true.
|
||||
// See https://llvm.org/bugs/show_bug.cgi?format=multiple&id=18006
|
||||
// The following hack is for GCC >=4.8 only. Clang works fine without
|
||||
// this.
|
||||
#ifdef __PX4_POSIX
|
||||
__attribute__((aligned(16)));
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
param_type_t type;
|
||||
uint16_t volatile_param: 1;
|
||||
const char *name;
|
||||
union param_value_u val;
|
||||
};
|
||||
|
||||
|
||||
@ -44,13 +44,14 @@
|
||||
#define PARAM_IMPLEMENTATION
|
||||
#include "param.h"
|
||||
#include "param_translation.h"
|
||||
#include <parameters/px4_parameters.h>
|
||||
#include <parameters/px4_parameters.hpp>
|
||||
#include "tinybson/tinybson.h"
|
||||
|
||||
#include <crc32.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <containers/Bitset.hpp>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/perf/perf_counter.h>
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
@ -91,50 +92,20 @@ static char *param_user_file = nullptr;
|
||||
/* autosaving variables */
|
||||
static hrt_abstime last_autosave_timestamp = 0;
|
||||
static struct work_s autosave_work {};
|
||||
static volatile bool autosave_scheduled = false;
|
||||
static px4::atomic<bool> autosave_scheduled{false};
|
||||
static bool autosave_disabled = false;
|
||||
|
||||
/**
|
||||
* Array of static parameter info.
|
||||
*/
|
||||
static const param_info_s *param_info_base = (const param_info_s *) &px4_parameters;
|
||||
#define param_info_count px4_parameters.param_count
|
||||
static constexpr uint16_t param_info_count = sizeof(px4::parameters) / sizeof(param_info_s);
|
||||
static px4::Bitset<param_info_count> params_active; // params found
|
||||
static px4::Bitset<param_info_count> params_changed; // params non-default
|
||||
|
||||
/**
|
||||
* Storage for modified parameters.
|
||||
*/
|
||||
// Storage for modified parameters.
|
||||
struct param_wbuf_s {
|
||||
union param_value_u val;
|
||||
param_t param;
|
||||
param_t param;
|
||||
bool unsaved;
|
||||
};
|
||||
|
||||
|
||||
uint8_t *param_changed_storage = nullptr;
|
||||
int size_param_changed_storage_bytes = 0;
|
||||
const int bits_per_allocation_unit = (sizeof(*param_changed_storage) * 8);
|
||||
|
||||
|
||||
static unsigned
|
||||
get_param_info_count()
|
||||
{
|
||||
/* Singleton creation of and array of bits to track changed values */
|
||||
if (!param_changed_storage) {
|
||||
/* Note that we have a (highly unlikely) race condition here: in the worst case the allocation is done twice */
|
||||
size_param_changed_storage_bytes = (param_info_count / bits_per_allocation_unit) + 1;
|
||||
param_changed_storage = (uint8_t *)calloc(size_param_changed_storage_bytes, 1);
|
||||
|
||||
/* If the allocation fails we need to indicate failure in the
|
||||
* API by returning PARAM_INVALID
|
||||
*/
|
||||
if (param_changed_storage == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return param_info_count;
|
||||
}
|
||||
|
||||
/** flexible array holding modified parameter values */
|
||||
UT_array *param_values{nullptr};
|
||||
|
||||
@ -145,10 +116,6 @@ const UT_icd param_icd = {sizeof(param_wbuf_s), nullptr, nullptr, nullptr};
|
||||
static orb_advert_t param_topic = nullptr;
|
||||
static unsigned int param_instance = 0;
|
||||
|
||||
static void param_set_used_internal(param_t param);
|
||||
|
||||
static param_t param_find_internal(const char *name, bool notification);
|
||||
|
||||
// the following implements an RW-lock using 2 semaphores (used as mutexes). It gives
|
||||
// priority to readers, meaning a writer could suffer from starvation, but in our use-case
|
||||
// we only have short periods of reads and writes are rare.
|
||||
@ -226,10 +193,10 @@ param_init()
|
||||
px4_sem_init(¶m_sem_save, 0, 1);
|
||||
px4_sem_init(&reader_lock_holders_lock, 0, 1);
|
||||
|
||||
param_export_perf = perf_alloc(PC_ELAPSED, "param_export");
|
||||
param_find_perf = perf_alloc(PC_COUNT, "param_find");
|
||||
param_get_perf = perf_alloc(PC_COUNT, "param_get");
|
||||
param_set_perf = perf_alloc(PC_ELAPSED, "param_set");
|
||||
param_export_perf = perf_alloc(PC_ELAPSED, "param: export");
|
||||
param_find_perf = perf_alloc(PC_COUNT, "param: find");
|
||||
param_get_perf = perf_alloc(PC_COUNT, "param: get");
|
||||
param_set_perf = perf_alloc(PC_ELAPSED, "param: set");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,15 +205,10 @@ param_init()
|
||||
* @param param The parameter handle to test.
|
||||
* @return True if the handle is valid.
|
||||
*/
|
||||
static bool
|
||||
handle_in_range(param_t param)
|
||||
{
|
||||
unsigned count = get_param_info_count();
|
||||
return (count && param < count);
|
||||
}
|
||||
static constexpr bool handle_in_range(param_t param) { return (param < param_info_count); }
|
||||
|
||||
/**
|
||||
* Compare two modifid parameter structures to determine ordering.
|
||||
* Compare two modified parameter structures to determine ordering.
|
||||
*
|
||||
* This function is suitable for passing to qsort or bsearch.
|
||||
*/
|
||||
@ -277,23 +239,21 @@ param_compare_values(const void *a, const void *b)
|
||||
static param_wbuf_s *
|
||||
param_find_changed(param_t param)
|
||||
{
|
||||
param_wbuf_s *s = nullptr;
|
||||
|
||||
param_assert_locked();
|
||||
|
||||
if (param_values != nullptr) {
|
||||
if (params_changed[param] && (param_values != nullptr)) {
|
||||
param_wbuf_s key{};
|
||||
key.param = param;
|
||||
s = (param_wbuf_s *)utarray_find(param_values, &key, param_compare_values);
|
||||
return (param_wbuf_s *)utarray_find(param_values, &key, param_compare_values);
|
||||
}
|
||||
|
||||
return s;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
_param_notify_changes()
|
||||
void
|
||||
param_notify_changes()
|
||||
{
|
||||
parameter_update_s pup = {};
|
||||
parameter_update_s pup{};
|
||||
pup.timestamp = hrt_absolute_time();
|
||||
pup.instance = param_instance++;
|
||||
|
||||
@ -309,30 +269,23 @@ _param_notify_changes()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
param_notify_changes()
|
||||
{
|
||||
_param_notify_changes();
|
||||
}
|
||||
|
||||
param_t
|
||||
param_find_internal(const char *name, bool notification)
|
||||
static param_t param_find_internal(const char *name, bool notification)
|
||||
{
|
||||
perf_count(param_find_perf);
|
||||
|
||||
param_t middle;
|
||||
param_t front = 0;
|
||||
param_t last = get_param_info_count();
|
||||
param_t last = param_info_count;
|
||||
|
||||
/* perform a binary search of the known parameters */
|
||||
|
||||
while (front <= last) {
|
||||
middle = front + (last - front) / 2;
|
||||
int ret = strcmp(name, param_info_base[middle].name);
|
||||
int ret = strcmp(name, param_name(middle));
|
||||
|
||||
if (ret == 0) {
|
||||
if (notification) {
|
||||
param_set_used_internal(middle);
|
||||
param_set_used(middle);
|
||||
}
|
||||
|
||||
perf_end(param_find_perf);
|
||||
@ -354,78 +307,50 @@ param_find_internal(const char *name, bool notification)
|
||||
return PARAM_INVALID;
|
||||
}
|
||||
|
||||
param_t
|
||||
param_find(const char *name)
|
||||
param_t param_find(const char *name)
|
||||
{
|
||||
return param_find_internal(name, true);
|
||||
}
|
||||
|
||||
param_t
|
||||
param_find_no_notification(const char *name)
|
||||
param_t param_find_no_notification(const char *name)
|
||||
{
|
||||
return param_find_internal(name, false);
|
||||
}
|
||||
|
||||
unsigned
|
||||
param_count()
|
||||
unsigned param_count()
|
||||
{
|
||||
return get_param_info_count();
|
||||
return param_info_count;
|
||||
}
|
||||
|
||||
unsigned
|
||||
param_count_used()
|
||||
unsigned param_count_used()
|
||||
{
|
||||
unsigned count = 0;
|
||||
|
||||
// ensure the allocation has been done
|
||||
if (get_param_info_count()) {
|
||||
|
||||
for (int i = 0; i < size_param_changed_storage_bytes; i++) {
|
||||
for (int j = 0; j < bits_per_allocation_unit; j++) {
|
||||
if (param_changed_storage[i] & (1 << j)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return params_active.count();
|
||||
}
|
||||
|
||||
param_t
|
||||
param_for_index(unsigned index)
|
||||
param_t param_for_index(unsigned index)
|
||||
{
|
||||
unsigned count = get_param_info_count();
|
||||
|
||||
if (count && index < count) {
|
||||
if (index < param_info_count) {
|
||||
return (param_t)index;
|
||||
}
|
||||
|
||||
return PARAM_INVALID;
|
||||
}
|
||||
|
||||
param_t
|
||||
param_for_used_index(unsigned index)
|
||||
param_t param_for_used_index(unsigned index)
|
||||
{
|
||||
int count = get_param_info_count();
|
||||
|
||||
if (count && (int)index < count) {
|
||||
/* walk all params and count used params */
|
||||
// walk all params and count used params
|
||||
if (index < param_info_count) {
|
||||
unsigned used_count = 0;
|
||||
|
||||
for (int i = 0; i < size_param_changed_storage_bytes; i++) {
|
||||
for (int j = 0; j < bits_per_allocation_unit; j++) {
|
||||
if (param_changed_storage[i] & (1 << j)) {
|
||||
|
||||
/* we found the right used count,
|
||||
* return the param value
|
||||
*/
|
||||
if (index == used_count) {
|
||||
return (param_t)(i * bits_per_allocation_unit + j);
|
||||
}
|
||||
|
||||
used_count++;
|
||||
for (int i = 0; i < params_active.size(); i++) {
|
||||
if (params_active[i]) {
|
||||
// we found the right used count,
|
||||
// return the param value
|
||||
if (index == used_count) {
|
||||
return static_cast<param_t>(i);
|
||||
}
|
||||
|
||||
used_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,8 +358,7 @@ param_for_used_index(unsigned index)
|
||||
return PARAM_INVALID;
|
||||
}
|
||||
|
||||
int
|
||||
param_get_index(param_t param)
|
||||
int param_get_index(param_t param)
|
||||
{
|
||||
if (handle_in_range(param)) {
|
||||
return (unsigned)param;
|
||||
@ -443,8 +367,7 @@ param_get_index(param_t param)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
param_get_used_index(param_t param)
|
||||
int param_get_used_index(param_t param)
|
||||
{
|
||||
/* this tests for out of bounds and does a constant time lookup */
|
||||
if (!param_used(param)) {
|
||||
@ -454,42 +377,46 @@ param_get_used_index(param_t param)
|
||||
/* walk all params and count, now knowing that it has a valid index */
|
||||
int used_count = 0;
|
||||
|
||||
for (int i = 0; i < size_param_changed_storage_bytes; i++) {
|
||||
for (int j = 0; j < bits_per_allocation_unit; j++) {
|
||||
if (param_changed_storage[i] & (1 << j)) {
|
||||
for (int i = 0; i < params_active.size(); i++) {
|
||||
if (params_active[i]) {
|
||||
|
||||
if ((int)param == i * bits_per_allocation_unit + j) {
|
||||
return used_count;
|
||||
}
|
||||
|
||||
used_count++;
|
||||
if (param == i) {
|
||||
return used_count;
|
||||
}
|
||||
|
||||
used_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *
|
||||
param_name(param_t param)
|
||||
const char *param_name(param_t param)
|
||||
{
|
||||
return handle_in_range(param) ? param_info_base[param].name : nullptr;
|
||||
return handle_in_range(param) ? px4::parameters[param].name : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
param_is_volatile(param_t param)
|
||||
param_type_t param_type(param_t param)
|
||||
{
|
||||
return handle_in_range(param) ? param_info_base[param].volatile_param : false;
|
||||
return handle_in_range(param) ? px4::parameters_type[param] : PARAM_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
bool
|
||||
param_value_is_default(param_t param)
|
||||
bool param_is_volatile(param_t param)
|
||||
{
|
||||
struct param_wbuf_s *s;
|
||||
param_lock_reader();
|
||||
s = param_find_changed(param);
|
||||
param_unlock_reader();
|
||||
return s == nullptr;
|
||||
if (handle_in_range(param)) {
|
||||
for (const auto &p : px4::parameters_volatile) {
|
||||
if (static_cast<px4::params>(param) == p) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool param_value_is_default(param_t param)
|
||||
{
|
||||
return handle_in_range(param) && !params_changed[param];
|
||||
}
|
||||
|
||||
bool
|
||||
@ -503,14 +430,7 @@ param_value_unsaved(param_t param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
param_type_t
|
||||
param_type(param_t param)
|
||||
{
|
||||
return handle_in_range(param) ? param_info_base[param].type : PARAM_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
size_t
|
||||
param_size(param_t param)
|
||||
size_t param_size(param_t param)
|
||||
{
|
||||
if (handle_in_range(param)) {
|
||||
switch (param_type(param)) {
|
||||
@ -551,7 +471,7 @@ param_get_value_ptr(param_t param)
|
||||
v = &s->val;
|
||||
|
||||
} else {
|
||||
v = ¶m_info_base[param].val;
|
||||
v = &px4::parameters[param].val;
|
||||
}
|
||||
|
||||
result = v;
|
||||
@ -564,10 +484,21 @@ int
|
||||
param_get(param_t param, void *val)
|
||||
{
|
||||
perf_count(param_get_perf);
|
||||
|
||||
if (!handle_in_range(param)) {
|
||||
PX4_ERR("get: param %d invalid", param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!params_active[param]) {
|
||||
PX4_WARN("get: param %d (%s) not active", param, param_name(param));
|
||||
}
|
||||
|
||||
int result = -1;
|
||||
|
||||
if (val) {
|
||||
param_lock_reader();
|
||||
|
||||
const void *v = param_get_value_ptr(param);
|
||||
|
||||
if (v) {
|
||||
@ -587,11 +518,11 @@ param_get_default_value(param_t param, void *default_val)
|
||||
if (default_val && handle_in_range(param)) {
|
||||
switch (param_type(param)) {
|
||||
case PARAM_TYPE_INT32:
|
||||
memcpy(default_val, ¶m_info_base[param].val.i, param_size(param));
|
||||
memcpy(default_val, &px4::parameters[param].val.i, param_size(param));
|
||||
return 0;
|
||||
|
||||
case PARAM_TYPE_FLOAT:
|
||||
memcpy(default_val, ¶m_info_base[param].val.f, param_size(param));
|
||||
memcpy(default_val, &px4::parameters[param].val.f, param_size(param));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -621,7 +552,7 @@ autosave_worker(void *arg)
|
||||
|
||||
param_lock_writer();
|
||||
last_autosave_timestamp = hrt_absolute_time();
|
||||
autosave_scheduled = false;
|
||||
autosave_scheduled.store(false);
|
||||
disabled = autosave_disabled;
|
||||
param_unlock_writer();
|
||||
|
||||
@ -646,7 +577,7 @@ autosave_worker(void *arg)
|
||||
static void
|
||||
param_autosave()
|
||||
{
|
||||
if (autosave_scheduled || autosave_disabled) {
|
||||
if (autosave_scheduled.load() || autosave_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -663,7 +594,7 @@ param_autosave()
|
||||
delay = rate_limit - last_save_elapsed;
|
||||
}
|
||||
|
||||
autosave_scheduled = true;
|
||||
autosave_scheduled.store(true);
|
||||
work_queue(LPWORK, &autosave_work, (worker_t)&autosave_worker, nullptr, USEC2TICK(delay));
|
||||
}
|
||||
|
||||
@ -672,9 +603,9 @@ param_control_autosave(bool enable)
|
||||
{
|
||||
param_lock_writer();
|
||||
|
||||
if (!enable && autosave_scheduled) {
|
||||
if (!enable && autosave_scheduled.load()) {
|
||||
work_cancel(LPWORK, &autosave_work);
|
||||
autosave_scheduled = false;
|
||||
autosave_scheduled.store(false);
|
||||
}
|
||||
|
||||
autosave_disabled = !enable;
|
||||
@ -685,13 +616,19 @@ static int
|
||||
param_set_internal(param_t param, const void *val, bool mark_saved, bool notify_changes)
|
||||
{
|
||||
int result = -1;
|
||||
bool params_changed = false;
|
||||
bool param_changed = false;
|
||||
|
||||
param_lock_writer();
|
||||
perf_begin(param_set_perf);
|
||||
|
||||
// create the parameter store if it doesn't exist
|
||||
if (param_values == nullptr) {
|
||||
utarray_new(param_values, ¶m_icd);
|
||||
|
||||
// mark all parameters unchanged (default)
|
||||
for (int i = 0; i < params_changed.size(); i++) {
|
||||
params_changed.set(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (param_values == nullptr) {
|
||||
@ -705,11 +642,11 @@ param_set_internal(param_t param, const void *val, bool mark_saved, bool notify_
|
||||
|
||||
switch (param_type(param)) {
|
||||
case PARAM_TYPE_INT32:
|
||||
set_to_default = (param_info_base[param].val.i == *(int32_t *)val);
|
||||
set_to_default = (px4::parameters[param].val.i == *(int32_t *)val);
|
||||
break;
|
||||
|
||||
case PARAM_TYPE_FLOAT:
|
||||
set_to_default = (fabsf(param_info_base[param].val.f - * (float *)val) < FLT_EPSILON);
|
||||
set_to_default = (fabsf(px4::parameters[param].val.f - * (float *)val) < FLT_EPSILON);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -720,7 +657,8 @@ param_set_internal(param_t param, const void *val, bool mark_saved, bool notify_
|
||||
// param in memory and set to non-default value, clear
|
||||
int pos = utarray_eltidx(param_values, s);
|
||||
utarray_erase(param_values, pos, 1);
|
||||
params_changed = true;
|
||||
params_changed.set(param, false);
|
||||
param_changed = true;
|
||||
}
|
||||
|
||||
// do nothing if param not already set and being set to default
|
||||
@ -728,14 +666,15 @@ param_set_internal(param_t param, const void *val, bool mark_saved, bool notify_
|
||||
} else {
|
||||
if (s == nullptr) {
|
||||
/* construct a new parameter */
|
||||
param_wbuf_s buf = {};
|
||||
param_wbuf_s buf{};
|
||||
buf.param = param;
|
||||
|
||||
params_changed = true;
|
||||
param_changed = true;
|
||||
|
||||
/* add it to the array and sort */
|
||||
utarray_push_back(param_values, &buf);
|
||||
utarray_sort(param_values, param_compare_values);
|
||||
params_changed.set(param, true);
|
||||
|
||||
/* find it after sorting */
|
||||
s = param_find_changed(param);
|
||||
@ -744,12 +683,12 @@ param_set_internal(param_t param, const void *val, bool mark_saved, bool notify_
|
||||
/* update the changed value */
|
||||
switch (param_type(param)) {
|
||||
case PARAM_TYPE_INT32:
|
||||
params_changed = params_changed || s->val.i != *(int32_t *)val;
|
||||
param_changed = param_changed || s->val.i != *(int32_t *)val;
|
||||
s->val.i = *(int32_t *)val;
|
||||
break;
|
||||
|
||||
case PARAM_TYPE_FLOAT:
|
||||
params_changed = params_changed || fabsf(s->val.f - * (float *)val) > FLT_EPSILON;
|
||||
param_changed = param_changed || fabsf(s->val.f - * (float *)val) > FLT_EPSILON;
|
||||
s->val.f = *(float *)val;
|
||||
break;
|
||||
|
||||
@ -775,8 +714,8 @@ out:
|
||||
* If we set something, now that we have unlocked, go ahead and advertise that
|
||||
* a thing has been set.
|
||||
*/
|
||||
if (params_changed && notify_changes) {
|
||||
_param_notify_changes();
|
||||
if (param_changed && notify_changes) {
|
||||
param_notify_changes();
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -794,47 +733,30 @@ const void *param_get_value_ptr_external(param_t param)
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
param_set(param_t param, const void *val)
|
||||
int param_set(param_t param, const void *val)
|
||||
{
|
||||
return param_set_internal(param, val, false, true);
|
||||
}
|
||||
|
||||
int
|
||||
param_set_no_notification(param_t param, const void *val)
|
||||
int param_set_no_notification(param_t param, const void *val)
|
||||
{
|
||||
return param_set_internal(param, val, false, false);
|
||||
}
|
||||
|
||||
bool
|
||||
param_used(param_t param)
|
||||
bool param_used(param_t param)
|
||||
{
|
||||
int param_index = param_get_index(param);
|
||||
|
||||
if (param_index < 0) {
|
||||
return false;
|
||||
if (handle_in_range(param)) {
|
||||
return params_active[param];
|
||||
}
|
||||
|
||||
return param_changed_storage[param_index / bits_per_allocation_unit] &
|
||||
(1 << param_index % bits_per_allocation_unit);
|
||||
return false;
|
||||
}
|
||||
|
||||
void param_set_used(param_t param)
|
||||
{
|
||||
param_set_used_internal(param);
|
||||
}
|
||||
|
||||
void param_set_used_internal(param_t param)
|
||||
{
|
||||
int param_index = param_get_index(param);
|
||||
|
||||
if (param_index < 0) {
|
||||
return;
|
||||
if (handle_in_range(param)) {
|
||||
params_active.set(param, true);
|
||||
}
|
||||
|
||||
// FIXME: this needs locking too
|
||||
param_changed_storage[param_index / bits_per_allocation_unit] |=
|
||||
(1 << param_index % bits_per_allocation_unit);
|
||||
}
|
||||
|
||||
static int param_reset_internal(param_t param, bool notify = true)
|
||||
@ -855,6 +777,8 @@ static int param_reset_internal(param_t param, bool notify = true)
|
||||
utarray_erase(param_values, pos, 1);
|
||||
}
|
||||
|
||||
params_changed.set(param, false);
|
||||
|
||||
param_found = true;
|
||||
}
|
||||
|
||||
@ -863,7 +787,7 @@ static int param_reset_internal(param_t param, bool notify = true)
|
||||
param_unlock_writer();
|
||||
|
||||
if (s != nullptr && notify) {
|
||||
_param_notify_changes();
|
||||
param_notify_changes();
|
||||
}
|
||||
|
||||
return (!param_found);
|
||||
@ -879,6 +803,10 @@ param_reset_all_internal(bool auto_save)
|
||||
|
||||
if (param_values != nullptr) {
|
||||
utarray_free(param_values);
|
||||
|
||||
for (int i = 0; i < params_changed.size(); i++) {
|
||||
params_changed.set(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* mark as reset / deleted */
|
||||
@ -890,7 +818,7 @@ param_reset_all_internal(bool auto_save)
|
||||
|
||||
param_unlock_writer();
|
||||
|
||||
_param_notify_changes();
|
||||
param_notify_changes();
|
||||
}
|
||||
|
||||
void
|
||||
@ -902,9 +830,7 @@ param_reset_all()
|
||||
void
|
||||
param_reset_excludes(const char *excludes[], int num_excludes)
|
||||
{
|
||||
param_t param;
|
||||
|
||||
for (param = 0; handle_in_range(param); param++) {
|
||||
for (param_t param = 0; handle_in_range(param); param++) {
|
||||
const char *name = param_name(param);
|
||||
bool exclude = false;
|
||||
|
||||
@ -929,9 +855,7 @@ param_reset_excludes(const char *excludes[], int num_excludes)
|
||||
void
|
||||
param_reset_specific(const char *resets[], int num_resets)
|
||||
{
|
||||
param_t param;
|
||||
|
||||
for (param = 0; handle_in_range(param); param++) {
|
||||
for (param_t param = 0; handle_in_range(param); param++) {
|
||||
const char *name = param_name(param);
|
||||
bool reset = false;
|
||||
|
||||
|
||||
@ -50,9 +50,7 @@ def generate(xml_file, dest='.'):
|
||||
os.path.mkdir(dest)
|
||||
|
||||
template_files = [
|
||||
'px4_parameters.h.jinja',
|
||||
'px4_parameters_public.h.jinja',
|
||||
'px4_parameters.c.jinja',
|
||||
'px4_parameters.hpp.jinja',
|
||||
]
|
||||
for template_file in template_files:
|
||||
template = env.get_template(template_file)
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
{# jinja syntax: http://jinja.pocoo.org/docs/2.9/templates/ #}
|
||||
#include "px4_parameters.h"
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from paramaters.xml
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
const
|
||||
|
||||
struct px4_parameters_t px4_parameters = {
|
||||
{% for param in params %}
|
||||
{
|
||||
"{{ param.attrib["name"] }}",
|
||||
PARAM_TYPE_{{ param.attrib["type"] }},
|
||||
{%- if param.attrib["volatile"] == "true" %}
|
||||
.volatile_param = 1,
|
||||
{%- else %}
|
||||
.volatile_param = 0,
|
||||
{%- endif %}
|
||||
{%- if param.attrib["type"] == "FLOAT" %}
|
||||
.val.f = {{ param.attrib["default"] }}
|
||||
{%- elif param.attrib["type"] == "INT32" %}
|
||||
.val.i = {{ param.attrib["default"] }}
|
||||
{%- endif %}
|
||||
},
|
||||
{% endfor %}
|
||||
{{ params | length }}
|
||||
};
|
||||
|
||||
//extern const struct px4_parameters_t px4_parameters;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
{# vim: set noet ft=jinja fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : #}
|
||||
@ -1,21 +0,0 @@
|
||||
{# jinja syntax: http://jinja.pocoo.org/docs/2.9/templates/ #}
|
||||
#include <stdint.h>
|
||||
#include <parameters/param.h>
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from parameters.xml
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct px4_parameters_t {
|
||||
{%- for param in params %}
|
||||
const struct param_info_s __param__{{ param.attrib["name"] }};
|
||||
{%- endfor %}
|
||||
const unsigned int param_count;
|
||||
};
|
||||
|
||||
extern const struct px4_parameters_t px4_parameters;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
{# vim: set noet ft=jinja fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : #}
|
||||
49
src/lib/parameters/templates/px4_parameters.hpp.jinja
Normal file
49
src/lib/parameters/templates/px4_parameters.hpp.jinja
Normal file
@ -0,0 +1,49 @@
|
||||
{# jinja syntax: http://jinja.pocoo.org/docs/2.9/templates/ #}
|
||||
|
||||
#include <stdint.h>
|
||||
#include <parameters/param.h>
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from parameters.xml
|
||||
|
||||
namespace px4 { {# wrap the enum in a namespace, otherwise we get shadowing errors for MAV_TYPE #}
|
||||
|
||||
/// Enum with all parameters
|
||||
enum class params : uint16_t {
|
||||
{# enums are guaranteed to start with 0 (if the value for the first is not
|
||||
specified), and then incremented by 1 (the implementation depends on that!) #}
|
||||
{%- for param in params %}
|
||||
{{ param.attrib["name"] }},
|
||||
{%- endfor %}
|
||||
|
||||
};
|
||||
|
||||
static constexpr param_info_s parameters[] = {
|
||||
{% for param in params %}
|
||||
{
|
||||
"{{ param.attrib["name"] }}",
|
||||
{%- if param.attrib["type"] == "FLOAT" %}
|
||||
.val = {{ "{" }} .f = {{ param.attrib["default"] }} {{ "}" }},
|
||||
{%- elif param.attrib["type"] == "INT32" %}
|
||||
.val = {{ "{" }} .i = {{ param.attrib["default"] }}{{ "}" }},
|
||||
{%- endif %}
|
||||
},
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
static constexpr param_type_t parameters_type[] = {
|
||||
{% for param in params %}
|
||||
PARAM_TYPE_{{ param.attrib["type"] }},
|
||||
{%- endfor -%}
|
||||
};
|
||||
|
||||
static constexpr params parameters_volatile[] = {
|
||||
{% for param in params %}
|
||||
{%- if param.attrib["volatile"] == "true" %}
|
||||
params::{{ param.attrib["name"] }},
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
|
||||
} // namespace px4
|
||||
@ -1,37 +0,0 @@
|
||||
{# jinja syntax: http://jinja.pocoo.org/docs/2.9/templates/ #}
|
||||
#include <stdint.h>
|
||||
#include <parameters/param.h>
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from parameters.xml
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace px4 { {# wrap the enum in a namespace, otherwise we get shadowing errors for MAV_TYPE #}
|
||||
|
||||
/// Enum with all parameters
|
||||
enum class params {
|
||||
{# enums are guaranteed to start with 0 (if the value for the first is not
|
||||
specified), and then incremented by 1 (the implementation depends on that!) #}
|
||||
{%- for param in params %}
|
||||
{{ param.attrib["name"] }},
|
||||
{%- endfor %}
|
||||
|
||||
_COUNT
|
||||
};
|
||||
|
||||
// All parameter types
|
||||
{# (px4_parameters is marked as extern, so we cannot use it as constexpr) #}
|
||||
static const constexpr int param_types_array[] = {
|
||||
{%- for param in params %}
|
||||
PARAM_TYPE_{{ param.attrib["type"] }}, // {{ param.attrib["name"] }}
|
||||
{%- endfor %}
|
||||
};
|
||||
|
||||
|
||||
} // namespace px4
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user