From 7d73a35805a61a40f49d0840741434ab9548d638 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 4 Mar 2019 23:24:43 -0500 Subject: [PATCH] command: Support evaluating C expressions in DECL_CONSTANT() Signed-off-by: Kevin O'Connor --- scripts/buildcommands.py | 25 +++++++++++++++++++++---- src/command.h | 18 +++++++----------- src/ctr.h | 13 +++++++++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/scripts/buildcommands.py b/scripts/buildcommands.py index 1c3448fe..46e6dc36 100644 --- a/scripts/buildcommands.py +++ b/scripts/buildcommands.py @@ -101,19 +101,36 @@ Handlers.append(HandleStaticStrings()) # Constants ###################################################################### +def decode_integer(value): + value = value.strip() + if len(value) != 7 or value[0] not in '-+': + error("Invalid encoded integer '%s'" % (value,)) + out = sum([(ord(c) - 48) << (i*6) for i, c in enumerate(value[1:])]) + if value[0] == '-': + out -= 1<<32 + return out + # Allow adding build time constants to the data dictionary class HandleConstants: def __init__(self): self.constants = {} - self.ctr_dispatch = { '_DECL_CONSTANT': self.decl_constant } + self.ctr_dispatch = { + '_DECL_CONSTANT': self.decl_constant, + '_DECL_CONSTANT_STR': self.decl_constant_str, + } + def set_value(self, name, value): + if name in self.constants and self.constants[name] != value: + error("Conflicting definition for constant '%s'" % name) + self.constants[name] = value def decl_constant(self, req): + name, value = req.split()[1:] + self.set_value(name, decode_integer(value)) + def decl_constant_str(self, req): name, value = req.split()[1:] value = value.strip() if value.startswith('"') and value.endswith('"'): value = value[1:-1] - if name in self.constants and self.constants[name] != value: - error("Conflicting definition for constant '%s'" % name) - self.constants[name] = value + self.set_value(name, value) def update_data_dictionary(self, data): data['config'] = self.constants def generate_code(self, options): diff --git a/src/command.h b/src/command.h index c924e59d..e0911733 100644 --- a/src/command.h +++ b/src/command.h @@ -7,17 +7,19 @@ #include "ctr.h" // DECL_CTR // Declare a function to run when the specified command is received +#define DECL_COMMAND_FLAGS(FUNC, FLAGS, MSG) \ + DECL_CTR("_DECL_COMMAND " __stringify(FUNC) " " __stringify(FLAGS) " " MSG) #define DECL_COMMAND(FUNC, MSG) \ - _DECL_COMMAND(FUNC, 0, MSG) -#define DECL_COMMAND_FLAGS(FUNC, FLAGS, MSG) \ - _DECL_COMMAND(FUNC, FLAGS, MSG) + DECL_COMMAND_FLAGS(FUNC, 0, MSG) // Flags for command handler declarations. #define HF_IN_SHUTDOWN 0x01 // Handler can run even when in emergency stop // Declare a constant exported to the host -#define DECL_CONSTANT(NAME, VALUE) _DECL_CONSTANT(NAME, __stringify(VALUE)) -#define DECL_CONSTANT_STR(NAME, VALUE) _DECL_CONSTANT(NAME, VALUE) +#define DECL_CONSTANT(NAME, VALUE) \ + DECL_CTR_INT("_DECL_CONSTANT " NAME, (VALUE)) +#define DECL_CONSTANT_STR(NAME, VALUE) \ + DECL_CTR("_DECL_CONSTANT_STR " NAME " " VALUE) // Send an output message (and declare a static message type for it) #define output(FMT, args...) \ @@ -85,12 +87,6 @@ const struct command_encoder *ctr_lookup_encoder(const char *str); const struct command_encoder *ctr_lookup_output(const char *str); uint8_t ctr_lookup_static_string(const char *str); -#define _DECL_COMMAND(FUNC, FLAGS, MSG) \ - DECL_CTR("_DECL_COMMAND " __stringify(FUNC) " " __stringify(FLAGS) " " MSG) - -#define _DECL_CONSTANT(NAME, VALUE) \ - DECL_CTR("_DECL_CONSTANT " NAME " " VALUE) - #define _DECL_ENCODER(FMT) ({ \ DECL_CTR("_DECL_ENCODER " FMT); \ ctr_lookup_encoder(FMT); }) diff --git a/src/ctr.h b/src/ctr.h index 3396644c..959cef45 100644 --- a/src/ctr.h +++ b/src/ctr.h @@ -14,4 +14,17 @@ static char __PASTE(_DECLS_, __LINE__)[] __attribute__((used)) \ __section(".compile_time_request") = (REQUEST) +#define CTR_INT(V, S) ((((uint32_t)(V) >> S) & 0x3f) + 48) + +// Declare a compile time request with an integer expression +#define DECL_CTR_INT(REQUEST, VALUE) \ + static struct { char _r[sizeof(REQUEST)]; char _v[8]; } \ + __PASTE(_DECLI_, __LINE__) __attribute__((used)) \ + __section(".compile_time_request") = { \ + REQUEST " ", { \ + (VALUE) < 0 ? '-' : '+', \ + CTR_INT((VALUE),0), CTR_INT((VALUE),6), \ + CTR_INT((VALUE),12), CTR_INT((VALUE),18), \ + CTR_INT((VALUE),24), CTR_INT((VALUE),30), 0 } } + #endif // ctr.h