From 950d2796840ee764882b44c736470e8927d5798e Mon Sep 17 00:00:00 2001 From: edvard Date: Fri, 26 Jun 2026 12:47:54 +0200 Subject: [PATCH 1/5] feat(limits): initial suggestion for limits --- include/param/param.h | 34 ++++++++++++++++++++++++++++++++-- src/param/param.c | 26 ++++++++++++++++---------- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/include/param/param.h b/include/param/param.h index e5e7dd78f..0eee0e542 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_RANGE (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; /* active only when PM_RANGE set */ + param_bound_t max; + uint16_t * node; char *name; char *unit; @@ -211,7 +241,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); \ @@ -226,7 +256,7 @@ static const uint16_t node_self = 0; .name = #_name, \ .array_size = _array_count < 1 ? 1 : _array_count, \ .array_step = _array_step, \ - .mask = _flags, \ + .mask = (_flags) | PM_RANGE, \ .unit = _unit, \ .callback = _callback, \ PARAM_TIMESTAMP_INIT(_name) \ diff --git a/src/param/param.c b/src/param/param.c index 8bf36eea8..1968c34c9 100644 --- a/src/param/param.c +++ b/src/param/param.c @@ -97,6 +97,12 @@ void param_get_data(const param_t * param, void * outbuf, int len) if (i >= (unsigned int) param->array_size) { \ return; \ } \ + { \ + __typeof__(param->min._bmem) _v = (__typeof__(param->min._bmem)) value; \ + if ((_v < param->min._bmem) || (_v > param->max._bmem)) { \ + return; /* out of range: leave stored value unchanged */ \ + } \ + } \ if (param->vmem) { \ if (param->vmem->big_endian == 1) \ value = _swapfct(value); \ @@ -130,16 +136,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 From 4995d42d42535009f20e8420a338e85f94cbf1a5 Mon Sep 17 00:00:00 2001 From: edvard Date: Fri, 26 Jun 2026 13:02:22 +0200 Subject: [PATCH 2/5] fix(limit): remove flag from old draft impl --- include/param/param.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/param/param.h b/include/param/param.h index 0eee0e542..772663e7f 100644 --- a/include/param/param.h +++ b/include/param/param.h @@ -148,7 +148,7 @@ typedef struct param_s { uint64_t vaddr; /* Virtual address in case of VMEM */ - param_bound_t min; /* active only when PM_RANGE set */ + param_bound_t min; param_bound_t max; uint16_t * node; @@ -256,7 +256,7 @@ static const uint16_t node_self = 0; .name = #_name, \ .array_size = _array_count < 1 ? 1 : _array_count, \ .array_step = _array_step, \ - .mask = (_flags) | PM_RANGE, \ + .mask = _flags, \ .unit = _unit, \ .callback = _callback, \ PARAM_TIMESTAMP_INIT(_name) \ From 71a165f6a86fd71010f8976c36a192e81dca10e5 Mon Sep 17 00:00:00 2001 From: edvard Date: Fri, 26 Jun 2026 13:33:39 +0200 Subject: [PATCH 3/5] fix(limit): remove flag from old draft impl --- include/param/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/param/param.h b/include/param/param.h index 772663e7f..af9463f3b 100644 --- a/include/param/param.h +++ b/include/param/param.h @@ -120,7 +120,7 @@ typedef union param_bound_u { #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_RANGE (1 << 14) //! unused +#define PM_UNUSED (1 << 14) //! unused #define PM_HIDDEN (1 << 15) //! H: Hidden parameter /* Reserved flags: From 3e3f432e4e23cc7fd587f0ccfc0562880b2a22fb Mon Sep 17 00:00:00 2001 From: edvard Date: Mon, 29 Jun 2026 09:34:12 +0200 Subject: [PATCH 4/5] fix(limits): assign min max using union --- include/param/param.h | 3 +++ src/param/param.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/param/param.h b/include/param/param.h index af9463f3b..cc959d237 100644 --- a/include/param/param.h +++ b/include/param/param.h @@ -158,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; @@ -263,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 1968c34c9..2546c1867 100644 --- a/src/param/param.c +++ b/src/param/param.c @@ -91,7 +91,7 @@ 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) { \ From f29306c6d13a797a56701938bcf178ee9b5fe9ce Mon Sep 17 00:00:00 2001 From: edvard Date: Mon, 29 Jun 2026 10:18:55 +0200 Subject: [PATCH 5/5] fix(limits): just use the _type to cast makes compare smaller type as it is right now --- src/param/param.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/param/param.c b/src/param/param.c index 2546c1867..f7e49ce6e 100644 --- a/src/param/param.c +++ b/src/param/param.c @@ -98,8 +98,9 @@ void param_get_data(const param_t * param, void * outbuf, int len) return; \ } \ { \ - __typeof__(param->min._bmem) _v = (__typeof__(param->min._bmem)) value; \ - if ((_v < param->min._bmem) || (_v > param->max._bmem)) { \ + _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 */ \ } \ } \