Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Example Script] swo_read_stimulus() returns empty List. Even if num_bytes is not zero. #207

Open
cogito666 opened this issue Aug 15, 2024 · 3 comments

Comments

@cogito666
Copy link

cogito666 commented Aug 15, 2024

import pylink

try:
    import StringIO
except ImportError:
    import io as StringIO
import string
import sys
import time


def serial_wire_viewer(jlink_serial, device):
    """Implements a Serial Wire Viewer (SWV).

    A Serial Wire Viewer (SWV) allows us implement real-time logging of output
    from a connected device over Serial Wire Output (SWO).

    Args:
      jlink_serial (str): the J-Link serial number
      device (str): the target CPU

    Returns:
      Always returns ``0``.

    Raises:
      JLinkException: on error
    """
    buf = StringIO.StringIO()
    jlink = pylink.JLink(log=buf.write, detailed_log=buf.write)
    jlink.open(serial_no=jlink_serial)

    # Use Serial Wire Debug as the target interface.  Need this in order to use
    # Serial Wire Output.
    jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
    jlink.connect(device, verbose=True)
    # jlink.connect(chip_name='NRF52832_XXAA', verbose=True)


    jlink.coresight_configure()
    jlink.set_reset_strategy(pylink.enums.JLinkResetStrategyCortexM3.RESETPIN)

    # Have to halt the CPU before getitng its speed.
    jlink.reset()
    jlink.halt()

    cpu_speed = jlink.cpu_speed()
    swo_speed = jlink.swo_supported_speeds(cpu_speed, 10)[0]

    # Output the selected SWO speed to the console
    sys.stdout.write(f'swo_speed: {swo_speed}\n\n')
    sys.stdout.write(f'swo_speed: {swo_speed}\n\n')

    # Start logging serial wire output.
    jlink.swo_start(swo_speed)
    jlink.swo_flush()

    # Output the information about the program.
    sys.stdout.write('Serial Wire Viewer\n')
    sys.stdout.write('Press Ctrl-C to Exit\n')
    sys.stdout.write('Reading data from port 0:\n\n')

    # Reset the core without halting so that it runs.
    jlink.reset(ms=10, halt=False)

    # Use the `try` loop to catch a keyboard interrupt in order to stop logging
    # serial wire output.
    try:
        while True:
            # Check for any bytes in the stream.
            num_bytes = jlink.swo_num_bytes()
            sys.stdout.write(f'num_bytes: {num_bytes}\n\n')

            if num_bytes == 0:
                # If no bytes exist, sleep for a bit before trying again.
                time.sleep(1)
                continue

            data = jlink.swo_read_stimulus(0, num_bytes)
            # data = jlink.swo_read(0, num_bytes)
            # sys.stdout.write(f'data: {data}\n\n')

            sys.stdout.write(''.join(map(chr, data)))
            sys.stdout.flush()
    except KeyboardInterrupt:
        pass

    sys.stdout.write('\n')

    # Stop logging serial wire output.
    jlink.swo_stop()

    return 0


if __name__ == '__main__':
    exit(serial_wire_viewer(sys.argv[1], sys.argv[2]))

I am using upper script for nRF52DK.

When I run the script, num_bytes is not zero.
But the swo_read_stimulus() returns empty list.
What's wrong? Am I missing something?

I am using nrf52832 target CPU and it's programmed using Zephyr RTOS.

image

@cogito666 cogito666 changed the title [Example Script] swo_read_stimulus() returns empty even if num_bytes is not zero [Example Script] swo_read_stimulus() returns empty List. Even if num_bytes is not zero. Aug 15, 2024
@hkpeprah
Copy link
Contributor

I don't think I have used swo_read_stimulus(); the example application is for use with swo_read().

@cogito666
Copy link
Author

I don't think I have used swo_read_stimulus(); the example application is for use with swo_read().

Oh, thanks for letting me know.
The previous code from document.. Maybe it's out dated.
https://pylink.readthedocs.io/en/latest/swd.html

Anyway as you mentioned, I tested with the script in Example.
Below is the log in my IDE (PyCharm)


Serial Wire Viewer
Press Ctrl-C to Exit
Reading data from port 0:

ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running
ERROR:pylink.jlink:Cannot read register 0 (R0) while CPU is running

Is this log indicates that my CPU is locked? or has it something to do with the APP-PROTECT?

`

@hkpeprah
Copy link
Contributor

The SWD example is for cases where you are using SWD in your target to write data when a debugger is attached. Your firmware must be using SWD debug, and implementing write() to trigger a vector catch. There's an example here in the semihosting section on Memfault's blog of doing that: https://interrupt.memfault.com/blog/printf-on-embedded#semihosting

// Based on the implementation here:
// https://github.com/bminor/newlib/blob/1a0908203606527b6ac0ed438669b5bcd247a5f9/newlib/libc/sys/arm/syscalls.c#L314-L338
// And here:
// https://github.com/bminor/newlib/blob/69f4c4029183fb26d2fcae00790881620c1978a3/newlib/libc/sys/arm/swi.h#L74-L89
int _write(int file, uint8_t *ptr, int len) {
  int data[3] = {file, (int) ptr, len};
  __asm__("mov r0, %0 \n mov r1, %1 \n bkpt #0xAB"
          : : "r" (5), "r" (&data) : "r0", "r1", "memory");
  return len;
}

The SWV is used for Serial Wire Output (SWO), and similarly, you must implement a _write() in your firmware that outputs data to SWO. You also need to assign a GPIO for use with SWO. They have an example section on that as well: https://interrupt.memfault.com/blog/printf-on-embedded#serial-wire-output-swo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants