[mbedmicro/pyOCD] Add support for RTX (#392)

40 views
Skip to first unread message

Seppo Takalo

unread,
Aug 9, 2018, 11:02:11 AM8/9/18
to mbedmicro/pyOCD, Subscribed

This patch will add support of RTX threads within PyoCD.
Allows GDB to see all running threads from the system and their states.

Tested manually on K64F against current Mbed OS master.


You can view, comment on, or merge this pull request online at:

  https://github.com/mbedmicro/pyOCD/pull/392

Commit Summary

  • Add RTX thread support
  • Display thread states in description + some cleanup

File Changes

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

Chris Reed

unread,
Aug 9, 2018, 4:31:24 PM8/9/18
to mbedmicro/pyOCD, Subscribed

@flit requested changes on this pull request.

Looks good, just a few small changes requested.


In pyOCD/rtos/rtx.py:

> +         0: "Inactive",
+         1: "Ready",
+         2: "Running",
+         3: "Blocked",
+         4: "Terminated",
+    }
+    def __init__(self, targetContext, provider, base):
+        super(RTXTargetThread, self).__init__()
+        self._target_context = targetContext
+        self._provider = provider
+        self._base = base
+        self._thread_context = RTXThreadContext(self._target_context, self)
+        self._has_fpu = self._thread_context.core.has_fpu
+        name_ptr = self._target_context.read32(self._base + NAME_OFFSET)
+        self._name = read_c_string(self._target_context, name_ptr)
+        log.info('RTXTargetThread 0x%x' % base)

Might want to make this a debug log.


In pyOCD/rtos/rtx.py:

> +        # Delay list
+        thread = self._target_context.read32(self._delaylist)
+        while thread:
+            log.debug('found DELAY thread %x' % thread)
+            if not thread in self._threads:
+                self._threads[thread] = RTXTargetThread(self._target_context, self, thread)
+            thread = self._target_context.read32(thread+DELAYNEXT_OFFSET)
+
+        # Wait list
+        thread = self._target_context.read32(self._waitlist)
+        while thread:
+            log.debug('found WAIT thread %x' % thread)
+            if not thread in self._threads:
+                self._threads[thread] = RTXTargetThread(self._target_context, self, thread)
+            thread = self._target_context.read32(thread+DELAYNEXT_OFFSET)
+

You should probably add the code to create the Handler mode pseudo-thread here. This is important so that if you stop in an interrupt handler, it appears as a separate "thread".

Example code copied from Argon (same for FreeRTOS and Zephyr):

        # Create fake handler mode thread.
        if self.get_ipsr() > 0:
            log.debug("creating handler mode thread")
            t = HandlerModeThread(self._target_context, self)
            newThreads[t.unique_id] = t

In pyOCD/rtos/__init__.py:

>  
 RTOS = {
           'Argon' : ArgonThreadProvider,
           'FreeRTOS' : FreeRTOSThreadProvider,
           'Zephyr' : ZephyrThreadProvider,
+          'RTX' : RTXThreadProvider,

Let's make it explicitly RTX5, in case support for earlier RTX versions is added at some point. Same applies to the rtx module name.


In pyOCD/rtos/rtx.py:

> + Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+"""
+from .provider import (TargetThread, ThreadProvider)
+from .common import (read_c_string, HandlerModeThread)
+from ..core.target import Target
+from ..debug.context import DebugContext
+from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index)
+from pyOCD.pyDAPAccess import DAPAccess
+import logging
+
+# Create a logger for this module.
+log = logging.getLogger("RTX")

I'm not sure it matters (are logger names case-sensitive?), but all loggers in pyOCD are lower case.

Chris Reed

unread,
Aug 9, 2018, 4:36:45 PM8/9/18
to mbedmicro/pyOCD, Subscribed

Fyi, see #390. Please sync the RTX support with the changes in that PR.

Seppo Takalo

unread,
Aug 10, 2018, 5:21:43 AM8/10/18
to mbedmicro/pyOCD, Push

@SeppoTakalo pushed 2 commits.

  • c09e85a Rename RTX handler to RTX5
  • 6689b06 Add HandlerModeThread and subsribe to flast&reset events


You are receiving this because you are subscribed to this thread.

View it on GitHub or mute the thread.

Seppo Takalo

unread,
Aug 10, 2018, 5:25:43 AM8/10/18
to mbedmicro/pyOCD, Subscribed

@flit Thanks for your feedback.
Issues you pointed out should be now fixed.

I also tried what it looks like, when the Handlermode thread is enabled.
I created a application that hardfaults on the main.cpp by calling *((int*)0) = 1;, now the debugging seems to stop properly and does not trash the stack frame of the faulting thread.

(gdb) continue
Continuing.
[New Thread 536920668]
[New Thread 536872848]
[New Thread 536875216]
[New Thread 2]
[New Thread 536875288]

Thread 2 received signal SIGSTOP, Stopped (signal).
[Switching to Thread 536920668]
0x00001bd0 in main () at ./main.cpp:29
29	    r = net->connect();
(gdb) info threads
  Id   Target Id         Frame 
* 2    Thread 536920668 (main_thread; Running 0x2000c25c) 0x00001bd0 in main () at ./main.cpp:29
  3    Thread 536872848 (tcpip_thread; Ready 0x20000790) tcpip_thread (arg=0x0 <__isr_vector>) at ./mbed-os/features/lwipstack/lwip/src/api/lwip_tcpip.c:88
  4    Thread 536875216 (idle_thread; Ready 0x200010d0) osRtxIdleThread (argument=0x21db1 <osThreadExit>) at ./mbed-os/rtos/TARGET_CORTEX/mbed_rtx_handlers.c:36
  5    Thread 2 (Handler mode) HardFault_Handler () at except.S:50
  6    Thread 536875288 (timer_thread; Blocked 0x20001118) 0x0001f9d4 in __svcMessageQueueGet (a4=0xffffffff, a3=0x0 <__isr_vector>, a2=0x2000164c <os_timer_thread_stack+748>, a1=0x20001660 <os_timer_mq_cb>) at ./mbed-os/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_msgqueue.c:808
(gdb) bt
#0  0x00001bd0 in main () at ./main.cpp:29
(gdb) thread 5
[Switching to thread 5 (Thread 2)]
#0  HardFault_Handler () at except.S:50
50	except.S: No such file or directory.
(gdb) bt
#0  HardFault_Handler () at except.S:50
#1  <signal handler called>
#2  0x0001e99e in __svcKernelStart () at ./mbed-os/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c:518
#3  osKernelStart () at ./mbed-os/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c:589
#4  0x0001d688 in mbed_start_main () at ./mbed-os/rtos/TARGET_CORTEX/mbed_boot.c:335
#5  0x0001d782 in software_init_hook () at ./mbed-os/rtos/TARGET_CORTEX/mbed_boot.c:664
#6  0x000004da in _start ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) quit

Hardfault handler is shown in separate thread, which shows main stack/interrupt stack as its back trace. The thread that caused the HardFault seems to be still the active one, and properly shows the place where the crash happened. Also it gives the hint Thread 2 received signal SIGSTOP, Stopped (signal). of which thread was causing the stop.

This looks pretty good now.

Chris Reed

unread,
Aug 10, 2018, 4:09:06 PM8/10/18
to mbedmicro/pyOCD, Subscribed

@flit approved this pull request.

Chris Reed

unread,
Aug 10, 2018, 4:09:35 PM8/10/18
to mbedmicro/pyOCD, Subscribed

Looks good! Thanks for the changes.

Chris Reed

unread,
Aug 10, 2018, 4:09:45 PM8/10/18
to mbedmicro/pyOCD, Subscribed

/morph test

Chris Reed

unread,
Aug 10, 2018, 4:53:23 PM8/10/18
to mbedmicro/pyOCD, Subscribed

Merged #392 into master.

Reply all
Reply to author
Forward
0 new messages