diff --git a/include/param/param.h b/include/param/param.h index e5e7dd78f..cc959d237 100644 --- a/include/param/param.h +++ b/include/param/param.h @@ -58,6 +58,32 @@ typedef enum { #define PARAM_CTYPE_PARAM_TYPE_STRING char #define PARAM_CTYPE_PARAM_TYPE_DATA char +/* Boundary union for parameter values. This is used to store the min/max values of a parameter in a type-agnostic way. */ +typedef union param_bound_u { + int64_t i; + uint64_t u; + float f; + double d; +} param_bound_t; + +#define PARAM_BMEMBER_PARAM_TYPE_UINT8 u +#define PARAM_BMEMBER_PARAM_TYPE_UINT16 u +#define PARAM_BMEMBER_PARAM_TYPE_UINT32 u +#define PARAM_BMEMBER_PARAM_TYPE_UINT64 u +#define PARAM_BMEMBER_PARAM_TYPE_INT8 i +#define PARAM_BMEMBER_PARAM_TYPE_INT16 i +#define PARAM_BMEMBER_PARAM_TYPE_INT32 i +#define PARAM_BMEMBER_PARAM_TYPE_INT64 i +#define PARAM_BMEMBER_PARAM_TYPE_XINT8 u +#define PARAM_BMEMBER_PARAM_TYPE_XINT16 u +#define PARAM_BMEMBER_PARAM_TYPE_XINT32 u +#define PARAM_BMEMBER_PARAM_TYPE_XINT64 u +#define PARAM_BMEMBER_PARAM_TYPE_FLOAT f +#define PARAM_BMEMBER_PARAM_TYPE_DOUBLE d +#define PARAM_BMEMBER_PARAM_TYPE_STRING i /* unused */ +#define PARAM_BMEMBER_PARAM_TYPE_DATA i /* unused */ +#define PARAM_BMEMBER(_ptype_token) PARAM_BMEMBER_##_ptype_token + /* “Selector” macro */ #define PARAM_CTYPE(_ptype_token) PARAM_CTYPE_##_ptype_token @@ -94,6 +120,7 @@ typedef enum { #define PM_PRIO3 (3 << 12) //! q: Priority of parameter for logging and retrieval (two bits) #define PM_PRIO_MASK (3 << 12) //! q: Priority of parameter for logging and retrieval (two bits) +#define PM_UNUSED (1 << 14) //! unused #define PM_HIDDEN (1 << 15) //! H: Hidden parameter /* Reserved flags: @@ -121,6 +148,9 @@ typedef struct param_s { uint64_t vaddr; /* Virtual address in case of VMEM */ + param_bound_t min; + param_bound_t max; + uint16_t * node; char *name; char *unit; @@ -128,6 +158,7 @@ typedef struct param_s { void * addr; /* Physical address */ const struct vmem_s * vmem; void (*callback)(const struct param_s * param, int offset); + void (*pre_set)(const struct param_s * param, int offset, void * value); #ifdef PARAM_HAVE_TIMESTAMP csp_timestamp_t * timestamp; @@ -211,7 +242,7 @@ static const uint16_t node_self = 0; -#define PARAM_DEFINE_STATIC_RAM(_id, _name, _type, _array_count, _array_step, _flags, _callback, _unit, _physaddr, _docstr) \ +#define PARAM_DEFINE_STATIC_RAM(_id, _name, _type, _array_count, _array_step, _flags, _callback, _unit, _physaddr, _docstr, _min, _max) \ _Static_assert(((_array_count) <= 1) ? 1 : ((_array_step) >= PARAM_SIZEOF(_type)), "param: array_step invalid for array_count"); \ _Static_assert(((_array_count) <= 1) ? 1 : (((_array_step) % PARAM_ALIGNOF(_type)) == 0U),"param: array_step not aligned to type"); \ PARAM_TYPECHECK(_name, _type, _physaddr); \ @@ -233,6 +264,8 @@ static const uint16_t node_self = 0; .addr = (void *)(_physaddr), \ .vaddr = 0, \ .docstr = _docstr, \ + .min = { .PARAM_BMEMBER(_type) = (_min) }, \ + .max = { .PARAM_BMEMBER(_type) = (_max) }, \ } #define PARAM_DEFINE_STATIC_VMEM(_id, _name, _type, _array_count, _array_step, _flags, _callback, _unit, _vmem_name, _vmem_addr, _docstr) \ diff --git a/src/param/param.c b/src/param/param.c index 8bf36eea8..f7e49ce6e 100644 --- a/src/param/param.c +++ b/src/param/param.c @@ -91,12 +91,19 @@ void param_get_data(const param_t * param, void * outbuf, int len) #define param_log(...) #endif -#define PARAM_SET(_type, name_in, _swapfct) \ +#define PARAM_SET(_type, name_in, _swapfct, _bmem) \ void __param_set_##name_in(const param_t * param, _type value, bool do_callback, unsigned int i); \ void __param_set_##name_in(const param_t * param, _type value, bool do_callback, unsigned int i) { \ if (i >= (unsigned int) param->array_size) { \ return; \ } \ + { \ + _type _min = (_type) param->min._bmem; \ + _type _max = (_type) param->max._bmem; \ + if ((value < _min) || (value > _max)) { \ + return; /* out of range: leave stored value unchanged */ \ + } \ + } \ if (param->vmem) { \ if (param->vmem->big_endian == 1) \ value = _swapfct(value); \ @@ -130,16 +137,16 @@ void param_get_data(const param_t * param, void * outbuf, int len) __param_set_##name_in(param, value, false, i); \ } -PARAM_SET(uint8_t, uint8, ) -PARAM_SET(uint16_t, uint16, htobe16) -PARAM_SET(uint32_t, uint32, htobe32) -PARAM_SET(uint64_t, uint64, htobe64) -PARAM_SET(int8_t, int8, ) -PARAM_SET(int16_t, int16, htobe16) -PARAM_SET(int32_t, int32, htobe32) -PARAM_SET(int64_t, int64, htobe64) -PARAM_SET(float, float, ) -PARAM_SET(double, double, ) +PARAM_SET(uint8_t, uint8, , u) +PARAM_SET(uint16_t, uint16, htobe16, u) +PARAM_SET(uint32_t, uint32, htobe32, u) +PARAM_SET(uint64_t, uint64, htobe64, u) +PARAM_SET(int8_t, int8, , i) +PARAM_SET(int16_t, int16, htobe16, i) +PARAM_SET(int32_t, int32, htobe32, i) +PARAM_SET(int64_t, int64, htobe64, i) +PARAM_SET(float, float, , f) +PARAM_SET(double, double, , d) #undef PARAM_SET