From 7d70ddeb853da2bd1383ad7f54c1dd1f5c6ab105 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 9 Oct 2025 14:10:54 +0200 Subject: [PATCH] rtos: zephyr: use thread states from modern Zephyr versions The existing thread states were coming from a very old Zephyr version. Align to more modern definitions. Also handle the special case of idle threads which don't have a proper state when not running. Signed-off-by: Mathieu Choplain --- pyocd/rtos/zephyr.py | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/pyocd/rtos/zephyr.py b/pyocd/rtos/zephyr.py index cbde29788..56b1683fb 100644 --- a/pyocd/rtos/zephyr.py +++ b/pyocd/rtos/zephyr.py @@ -147,22 +147,29 @@ def read_core_registers_raw(self, reg_list): class ZephyrThread(TargetThread): """@brief A Zephyr task.""" - READY = 0 + # Keep in sync with include/zephyr/kernel_structs.h + DUMMY = 1 << 0 # attribute rather than state PENDING = 1 << 1 - PRESTART = 1 << 2 + SLEEPING = 1 << 2 DEAD = 1 << 3 SUSPENDED = 1 << 4 - POLLING = 1 << 5 - RUNNING = 1 << 6 + ABORTING = 1 << 5 + SUSPENDING = 1 << 6 + QUEUED = 1 << 7 # thread in ready queue + + # Not a real value; for bookkeeping purposes only + RUNNING = 1 << 31 STATE_NAMES = { - READY : "Ready", + DUMMY : "Dummy", PENDING : "Pending", - PRESTART : "Prestart", + SLEEPING : "Sleeping", DEAD : "Dead", SUSPENDED : "Suspended", - POLLING : "Polling", - RUNNING : "Running", + ABORTING : "Aborting", + SUSPENDING : "Suspending", + QUEUED : "Ready", + RUNNING : "Running" } def __init__(self, targetContext, provider, base, offsets): @@ -172,7 +179,7 @@ def __init__(self, targetContext, provider, base, offsets): self._base = base self._thread_context = ZephyrThreadContext(self._target_context, self) self._offsets = offsets - self._state = ZephyrThread.READY + self._state = ZephyrThread.QUEUED self._priority = 0 self._name = "Unnamed" @@ -224,6 +231,25 @@ def name(self): @property def description(self): + # Idle threads must be handled separately: when not running, + # they are neither SLEEPING, PENDING nor QUEUED and simply + # exist in a "limbo state" outside scheduler consideration. + # + # NOTE: RUNNING state indicates that 'current' of a CPU is + # equal to self._base, unlike all other values which come + # directly from 'base.thread_state'; as such, it will be + # valid even for idle threads, unlike all other values. + # + # HACK: assume threads called "idle" are idle threads. + # A proper method would check that this is one of the threads + # in the "z_idle_threads" array (or that is matches one of + # _kernel.cpus[].idle_thread, which is the same thing). + if self._name == "idle": + if self.state == ZephyrThread.RUNNING: + return "Running; " + else: + return "" + return "%s; Priority %d" % (self.STATE_NAMES.get(self.state, "UNKNOWN"), self.priority) @property