monitor: Add support for reading over J-Link RTT
authorAndrzej Kaczmarek <andrzej.kaczmarek@codecoup.pl>
Tue, 20 Feb 2018 14:52:49 +0000 (15:52 +0100)
committerhimanshu <h.himanshu@samsung.com>
Tue, 11 Feb 2020 08:58:20 +0000 (14:28 +0530)
This patch adds support for reading data over J-Link RTT. It can be
used as replacement for TTY when reading from embedded devices since
it's much faster and does block a UART. Data format is the same as
for TTY. At the moment monitor over RTT is only supported by Apache
Mynewt project.

Reading data is done by polling RTT every 1 msec since there is no
blocking API to read something from RTT buffer.

To enable reading from RTT, J-Link configuration needs to be passed via
command line (all parameters except <device> can be skipped to use
default value):
  -J <device>,<serialno=0>,<interface=swd>,<speed=1000>
  -J nrf52,683649029

In some cases J-Link cannot locate RTT buffer in RAM. In such case
RAM area and buffer name should be provided via command line:
  -R <address=0x0>,<area=0x1000>,<buffer=monitor>
  -R 0x20000000,0x10000

Change-Id: Ic9023663c0c3c2bc5bf3b06e702734fffbbf3baa
Signed-off-by: himanshu <h.himanshu@samsung.com>
Makefile.tools
monitor/control.c
monitor/control.h
monitor/main.c

index 9e050a8..39fcff2 100755 (executable)
@@ -39,9 +39,10 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
                                monitor/analyze.h monitor/analyze.c \
                                monitor/intel.h monitor/intel.c \
                                monitor/broadcom.h monitor/broadcom.c \
+                               monitor/jlink.h monitor/jlink.c \
                                monitor/tty.h
 monitor_btmon_LDADD = lib/libbluetooth-internal.la \
-                               src/libshared-mainloop.la @UDEV_LIBS@
+                               src/libshared-mainloop.la @UDEV_LIBS@ -ldl
 endif
 
 if LOGGER
index fcd6ada..713fa84 100755 (executable)
@@ -56,6 +56,7 @@
 #include "ellisys.h"
 #include "tty.h"
 #include "control.h"
+#include "jlink.h"
 
 static struct btsnoop *btsnoop_file = NULL;
 static bool hcidump_fallback = false;
@@ -1415,6 +1416,55 @@ int control_tty(const char *path, unsigned int speed)
        return 0;
 }
 
+static void rtt_callback(int id, void *user_data)
+{
+       struct control_data *data = user_data;
+       ssize_t len;
+
+       do {
+               len = jlink_rtt_read(data->buf + data->offset,
+                               sizeof(data->buf) - data->offset);
+               data->offset += len;
+               process_data(data);
+       } while (len > 0);
+
+       if (mainloop_modify_timeout(id, 1) < 0)
+               mainloop_exit_failure();
+}
+
+int control_rtt(char *jlink, char *rtt)
+{
+       struct control_data *data;
+
+       if (jlink_init() < 0) {
+               fprintf(stderr, "Failed to initialize J-Link library\n");
+               return -EIO;
+       }
+
+       if (jlink_connect(jlink) < 0) {
+               fprintf(stderr, "Failed to connect to target device\n");
+               return -ENODEV;
+       }
+
+       if (jlink_start_rtt(rtt) < 0) {
+               fprintf(stderr, "Failed to initialize RTT\n");
+               return -ENODEV;
+       }
+
+       printf("--- RTT opened ---\n");
+
+       data = new0(struct control_data, 1);
+       data->channel = HCI_CHANNEL_MONITOR;
+       data->fd = -1;
+
+       if (mainloop_add_timeout(1, rtt_callback, data, free_data) < 0) {
+               free(data);
+               return -EIO;
+       }
+
+       return 0;
+}
+
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 bool control_writer(const char *path, int16_t rotate_count, ssize_t file_size)
 #else
index 8e22138..9cffa74 100755 (executable)
@@ -32,6 +32,7 @@ bool control_writer(const char *path);
 void control_reader(const char *path, bool pager);
 void control_server(const char *path);
 int control_tty(const char *path, unsigned int speed);
+int control_rtt(char *jlink, char *rtt);
 int control_tracing(void);
 void control_disable_decoding(void);
 void control_filter_index(uint16_t index);
index aee3764..8ae5e8c 100755 (executable)
@@ -74,6 +74,10 @@ static void usage(void)
                "\t-A, --a2dp             Dump A2DP stream traffic\n"
                "\t-E, --ellisys [ip]     Send Ellisys HCI Injection\n"
                "\t-P, --no-pager         Disable pager usage\n"
+               "\t-J  --jlink <device>,[<serialno>],[<interface>],[<speed>]\n"
+               "\t                       Read data from RTT\n"
+               "\t-R  --rtt [<address>],[<area>],[<name>]\n"
+               "\t                       RTT control block parameters\n"
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
                "\t-C, --count <num>      Save traces by <num> rotation\n"
                "\t-W, --size <num>       Save traces at most <num> size\n"
@@ -101,6 +105,8 @@ static const struct option main_options[] = {
        { "size",    required_argument, NULL, 'W' },
 #endif
        { "no-pager",  no_argument,       NULL, 'P' },
+       { "jlink",     required_argument, NULL, 'J' },
+       { "rtt",       required_argument, NULL, 'R' },
        { "todo",      no_argument,       NULL, '#' },
        { "version",   no_argument,       NULL, 'v' },
        { "help",      no_argument,       NULL, 'h' },
@@ -123,6 +129,8 @@ int main(int argc, char *argv[])
        ssize_t file_size = -1;
 #endif
        const char *str;
+       char *jlink = NULL;
+       char *rtt = NULL;
        int exit_status;
 
        mainloop_init();
@@ -137,8 +145,8 @@ int main(int argc, char *argv[])
                opt = getopt_long(argc, argv, "d:r:w:a:s:p:i:tTSE:C:W:vh",
                                                main_options, NULL);
 #else
-               opt = getopt_long(argc, argv, "r:w:a:s:p:i:d:B:V:tTSAEPvh",
-                                                       main_options, NULL);
+               opt = getopt_long(argc, argv, "r:w:a:s:p:i:d:B:V:tTSAE:PJ:R:vh",
+                                                       main_options, NULL);
 #endif
                if (opt < 0)
                        break;
@@ -218,6 +226,12 @@ int main(int argc, char *argv[])
                        file_size = atoll(optarg);
                        break;
 #endif
+               case 'J':
+                       jlink = optarg;
+                       break;
+               case 'R':
+                       rtt = optarg;
+                       break;
                case '#':
                        packet_todo();
                        lmp_todo();
@@ -278,12 +292,15 @@ int main(int argc, char *argv[])
        if (ellisys_server)
                ellisys_enable(ellisys_server, ellisys_port);
 
-       if (!tty && control_tracing() < 0)
+       if (!tty && !jlink && control_tracing() < 0)
                return EXIT_FAILURE;
 
        if (tty && control_tty(tty, tty_speed) < 0)
                return EXIT_FAILURE;
 
+       if (jlink && control_rtt(jlink, rtt) < 0)
+               return EXIT_FAILURE;
+
        exit_status = mainloop_run_with_signal(signal_callback, NULL);
 
        keys_cleanup();