From e78d11bc6fe9d78c5c108e056d28cc2525ed66a9 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 18 Sep 2025 21:03:39 -0400 Subject: [PATCH] steppersync: Support sending messages directly from syncemitter Move msg_queue allocation from stepcompress to syncemitter. With this change the pwm_tool module does not need to allocate a stepcompress object. Signed-off-by: Kevin O'Connor --- klippy/chelper/__init__.py | 4 ++-- klippy/chelper/stepcompress.c | 34 ++++++--------------------------- klippy/chelper/stepcompress.h | 7 +++---- klippy/chelper/steppersync.c | 22 +++++++++++++++++---- klippy/chelper/steppersync.h | 2 ++ klippy/extras/motion_queuing.py | 6 +++--- klippy/extras/pwm_tool.py | 10 ++++------ klippy/stepper.py | 3 ++- 8 files changed, 40 insertions(+), 48 deletions(-) diff --git a/klippy/chelper/__init__.py b/klippy/chelper/__init__.py index e7340b204..c0324a07c 100644 --- a/klippy/chelper/__init__.py +++ b/klippy/chelper/__init__.py @@ -48,8 +48,6 @@ defs_stepcompress = """ , uint64_t clock); int stepcompress_queue_msg(struct stepcompress *sc , uint32_t *data, int len); - int stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock - , uint32_t *data, int len); int stepcompress_extract_old(struct stepcompress *sc , struct pull_history_steps *p, int max , uint64_t start_clock, uint64_t end_clock); @@ -61,6 +59,8 @@ defs_stepcompress = """ defs_steppersync = """ struct stepcompress *syncemitter_get_stepcompress(struct syncemitter *se); + void syncemitter_queue_msg(struct syncemitter *se, uint64_t req_clock + , uint32_t *data, int len); struct syncemitter *steppersync_alloc_syncemitter(struct steppersync *ss , char name[16], int alloc_stepcompress); void steppersync_setup_movequeue(struct steppersync *ss diff --git a/klippy/chelper/stepcompress.c b/klippy/chelper/stepcompress.c index 1c74380fb..1426d963e 100644 --- a/klippy/chelper/stepcompress.c +++ b/klippy/chelper/stepcompress.c @@ -38,7 +38,7 @@ struct stepcompress { double mcu_time_offset, mcu_freq, last_step_print_time; // Message generation uint64_t last_step_clock; - struct list_head msg_queue; + struct list_head *msg_queue; uint32_t oid; int32_t queue_step_msgtag, set_next_step_dir_msgtag; int sdir, invert_sdir; @@ -258,13 +258,13 @@ static void sc_thread_free(struct stepcompress *sc); // Allocate a new 'stepcompress' object struct stepcompress * -stepcompress_alloc(char name[16]) +stepcompress_alloc(char name[16], struct list_head *msg_queue) { struct stepcompress *sc = malloc(sizeof(*sc)); memset(sc, 0, sizeof(*sc)); - list_init(&sc->msg_queue); list_init(&sc->history_list); sc->sdir = -1; + sc->msg_queue = msg_queue; int ret = sc_thread_alloc(sc, name); if (ret) @@ -317,7 +317,6 @@ stepcompress_free(struct stepcompress *sc) return; sc_thread_free(sc); free(sc->queue); - message_queue_free(&sc->msg_queue); stepcompress_history_expire(sc, UINT64_MAX); free(sc); } @@ -334,12 +333,6 @@ stepcompress_get_step_dir(struct stepcompress *sc) return sc->next_step_dir; } -struct list_head * -stepcompress_get_msg_queue(struct stepcompress *sc) -{ - return &sc->msg_queue; -} - // Determine the "print time" of the last_step_clock static void calc_last_step_print_time(struct stepcompress *sc) @@ -377,7 +370,7 @@ add_move(struct stepcompress *sc, uint64_t first_clock, struct step_move *move) qm->min_clock = qm->req_clock = sc->last_step_clock; if (move->count == 1 && first_clock >= sc->last_step_clock + CLOCK_DIFF_MAX) qm->req_clock = first_clock; - list_add_tail(&qm->node, &sc->msg_queue); + list_add_tail(&qm->node, sc->msg_queue); sc->last_step_clock = last_clock; // Create and store move in history tracking @@ -441,7 +434,7 @@ set_next_step_dir(struct stepcompress *sc, int sdir) }; struct queue_message *qm = message_alloc_and_encode(msg, 3); qm->req_clock = sc->last_step_clock; - list_add_tail(&qm->node, &sc->msg_queue); + list_add_tail(&qm->node, sc->msg_queue); return 0; } @@ -640,22 +633,7 @@ stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len) struct queue_message *qm = message_alloc_and_encode(data, len); qm->req_clock = sc->last_step_clock; - list_add_tail(&qm->node, &sc->msg_queue); - return 0; -} - -// Queue an mcu command that will consume space in the mcu move queue -int __visible -stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock - , uint32_t *data, int len) -{ - int ret = stepcompress_flush(sc, UINT64_MAX); - if (ret) - return ret; - - struct queue_message *qm = message_alloc_and_encode(data, len); - qm->min_clock = qm->req_clock = req_clock; - list_add_tail(&qm->node, &sc->msg_queue); + list_add_tail(&qm->node, sc->msg_queue); return 0; } diff --git a/klippy/chelper/stepcompress.h b/klippy/chelper/stepcompress.h index 413446daf..25521fa0c 100644 --- a/klippy/chelper/stepcompress.h +++ b/klippy/chelper/stepcompress.h @@ -11,7 +11,9 @@ struct pull_history_steps { int step_count, interval, add; }; -struct stepcompress *stepcompress_alloc(char name[16]); +struct list_head; +struct stepcompress *stepcompress_alloc(char name[16] + , struct list_head *msg_queue); void stepcompress_fill(struct stepcompress *sc, uint32_t oid, uint32_t max_error , int32_t queue_step_msgtag , int32_t set_next_step_dir_msgtag); @@ -21,7 +23,6 @@ void stepcompress_history_expire(struct stepcompress *sc, uint64_t end_clock); void stepcompress_free(struct stepcompress *sc); uint32_t stepcompress_get_oid(struct stepcompress *sc); int stepcompress_get_step_dir(struct stepcompress *sc); -struct list_head *stepcompress_get_msg_queue(struct stepcompress *sc); void stepcompress_set_time(struct stepcompress *sc , double time_offset, double mcu_freq); int stepcompress_append(struct stepcompress *sc, int sdir @@ -33,8 +34,6 @@ int stepcompress_set_last_position(struct stepcompress *sc, uint64_t clock int64_t stepcompress_find_past_position(struct stepcompress *sc , uint64_t clock); int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len); -int stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock - , uint32_t *data, int len); int stepcompress_extract_old(struct stepcompress *sc , struct pull_history_steps *p, int max , uint64_t start_clock, uint64_t end_clock); diff --git a/klippy/chelper/steppersync.c b/klippy/chelper/steppersync.c index 047fde3c3..bf3a55393 100644 --- a/klippy/chelper/steppersync.c +++ b/klippy/chelper/steppersync.c @@ -27,16 +27,29 @@ struct syncemitter { // List node for storage in steppersync list struct list_node ss_node; + // Transmit message queue + struct list_head msg_queue; // Step compression and generation struct stepcompress *sc; }; +// Return this emitters 'struct stepcompress' (or NULL if not allocated) struct stepcompress * __visible syncemitter_get_stepcompress(struct syncemitter *se) { return se->sc; } +// Queue an mcu command that will consume space in the mcu move queue +void __visible +syncemitter_queue_msg(struct syncemitter *se, uint64_t req_clock + , uint32_t *data, int len) +{ + struct queue_message *qm = message_alloc_and_encode(data, len); + qm->min_clock = qm->req_clock = req_clock; + list_add_tail(&qm->node, &se->msg_queue); +} + /**************************************************************** * StepperSync - sort move queue for a micro-controller @@ -65,8 +78,9 @@ steppersync_alloc_syncemitter(struct steppersync *ss, char name[16] struct syncemitter *se = malloc(sizeof(*se)); memset(se, 0, sizeof(*se)); list_add_tail(&se->ss_node, &ss->se_list); + list_init(&se->msg_queue); if (alloc_stepcompress) - se->sc = stepcompress_alloc(name); + se->sc = stepcompress_alloc(name, &se->msg_queue); return se; } @@ -137,10 +151,9 @@ steppersync_flush(struct steppersync *ss, uint64_t move_clock) struct queue_message *qm = NULL; struct syncemitter *se; list_for_each_entry(se, &ss->se_list, ss_node) { - struct list_head *sc_mq = stepcompress_get_msg_queue(se->sc); - if (!list_empty(sc_mq)) { + if (!list_empty(&se->msg_queue)) { struct queue_message *m = list_first_entry( - sc_mq, struct queue_message, node); + &se->msg_queue, struct queue_message, node); if (m->req_clock < req_clock) { qm = m; req_clock = m->req_clock; @@ -205,6 +218,7 @@ steppersyncmgr_free(struct steppersyncmgr *ssm) &ss->se_list, struct syncemitter, ss_node); list_del(&se->ss_node); stepcompress_free(se->sc); + message_queue_free(&se->msg_queue); free(se); } free(ss); diff --git a/klippy/chelper/steppersync.h b/klippy/chelper/steppersync.h index f42d3c85d..6acbef28c 100644 --- a/klippy/chelper/steppersync.h +++ b/klippy/chelper/steppersync.h @@ -5,6 +5,8 @@ struct syncemitter; struct stepcompress *syncemitter_get_stepcompress(struct syncemitter *se); +void syncemitter_queue_msg(struct syncemitter *se, uint64_t req_clock + , uint32_t *data, int len); struct steppersync; struct syncemitter *steppersync_alloc_syncemitter( diff --git a/klippy/extras/motion_queuing.py b/klippy/extras/motion_queuing.py index da1a5a33b..459b6fa72 100644 --- a/klippy/extras/motion_queuing.py +++ b/klippy/extras/motion_queuing.py @@ -77,13 +77,13 @@ class PrinterMotionQueuing: ss = ffi_lib.steppersyncmgr_alloc_steppersync(self.steppersyncmgr) self.steppersyncs.append((mcu, ss)) return ss - def allocate_stepcompress(self, mcu, name): + def allocate_syncemitter(self, mcu, name, alloc_stepcompress=True): name = name.encode("utf-8")[:15] ss = self._lookup_steppersync(mcu) ffi_main, ffi_lib = chelper.get_ffi() - se = ffi_lib.steppersync_alloc_syncemitter(ss, name, True) + se = ffi_lib.steppersync_alloc_syncemitter(ss, name, alloc_stepcompress) self.syncemitters.append(se) - return ffi_lib.syncemitter_get_stepcompress(se) + return se def setup_mcu_movequeue(self, mcu, serialqueue, move_count): # Setup steppersync object for the mcu's main movequeue ffi_main, ffi_lib = chelper.get_ffi() diff --git a/klippy/extras/pwm_tool.py b/klippy/extras/pwm_tool.py index dfa5c682b..a069dd2d8 100644 --- a/klippy/extras/pwm_tool.py +++ b/klippy/extras/pwm_tool.py @@ -18,9 +18,10 @@ class MCU_queued_pwm: printer = mcu.get_printer() sname = config.get_name().split()[-1] self._motion_queuing = printer.load_object(config, 'motion_queuing') - self._stepqueue = self._motion_queuing.allocate_stepcompress(mcu, sname) + self._syncemitter = self._motion_queuing.allocate_syncemitter( + mcu, sname, alloc_stepcompress=False) ffi_main, ffi_lib = chelper.get_ffi() - self._stepcompress_queue_mq_msg = ffi_lib.stepcompress_queue_mq_msg + self._syncemitter_queue_msg = ffi_lib.syncemitter_queue_msg mcu.register_config_callback(self._build_config) self._pin = pin_params['pin'] self._invert = pin_params['invert'] @@ -107,10 +108,7 @@ class MCU_queued_pwm: self._last_clock = clock = max(self._last_clock, clock) self._last_value = val data = (self._set_cmd_tag, self._oid, clock & 0xffffffff, val) - ret = self._stepcompress_queue_mq_msg(self._stepqueue, clock, - data, len(data)) - if ret: - raise error("Internal error in stepcompress") + self._syncemitter_queue_msg(self._syncemitter, clock, data, len(data)) # Notify toolhead so that it will flush this update wakeclock = clock if self._last_value != self._default_value: diff --git a/klippy/stepper.py b/klippy/stepper.py index deb73769e..5fc20d0fa 100644 --- a/klippy/stepper.py +++ b/klippy/stepper.py @@ -45,8 +45,9 @@ class MCU_stepper: self._active_callbacks = [] motion_queuing = printer.load_object(config, 'motion_queuing') sname = self._name.split()[-1] - self._stepqueue = motion_queuing.allocate_stepcompress(mcu, sname) + syncemitter = motion_queuing.allocate_syncemitter(mcu, sname) ffi_main, ffi_lib = chelper.get_ffi() + self._stepqueue = ffi_lib.syncemitter_get_stepcompress(syncemitter) ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir) self._stepper_kinematics = None self._itersolve_check_active = ffi_lib.itersolve_check_active