1 /*
2 * Copyright (c) 2019 Intel corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /* Disable syscall tracing for all calls from this compilation unit to avoid
8 * undefined symbols as the macros are not expanded recursively
9 */
10 #define DISABLE_SYSCALL_TRACING
11
12 #include <errno.h>
13 #include <ctype.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/device.h>
16 #include <zephyr/drivers/uart.h>
17 #include <zephyr/sys/__assert.h>
18 #include <tracing_core.h>
19 #include <tracing_buffer.h>
20 #include <tracing_backend.h>
21
22
23 static const struct device *const tracing_uart_dev =
24 DEVICE_DT_GET(DT_CHOSEN(zephyr_tracing_uart));
25
26 #ifdef CONFIG_TRACING_HANDLE_HOST_CMD
uart_isr(const struct device * dev,void * user_data)27 static void uart_isr(const struct device *dev, void *user_data)
28 {
29 int rx;
30 uint8_t byte;
31 static uint8_t *cmd;
32 static uint32_t length, cur;
33
34 ARG_UNUSED(user_data);
35
36 while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
37 if (!uart_irq_rx_ready(dev)) {
38 continue;
39 }
40
41 rx = uart_fifo_read(dev, &byte, 1);
42 if (rx < 0) {
43 uart_irq_rx_disable(dev);
44 return;
45 }
46
47 if (!cmd) {
48 length = tracing_cmd_buffer_alloc(&cmd);
49 }
50
51 if (isprint(byte) == 0) {
52 if (byte == '\r') {
53 cmd[cur] = '\0';
54 tracing_cmd_handle(cmd, cur);
55 cmd = NULL;
56 cur = 0U;
57 }
58
59 continue;
60 }
61
62 if (cur < length - 1) {
63 cmd[cur++] = byte;
64 }
65 }
66 }
67 #endif
68
tracing_backend_uart_output(const struct tracing_backend * backend,uint8_t * data,uint32_t length)69 static void tracing_backend_uart_output(
70 const struct tracing_backend *backend,
71 uint8_t *data, uint32_t length)
72 {
73 for (uint32_t i = 0; i < length; i++) {
74 uart_poll_out(tracing_uart_dev, data[i]);
75 }
76 }
77
tracing_backend_uart_init(void)78 static void tracing_backend_uart_init(void)
79 {
80 __ASSERT(device_is_ready(tracing_uart_dev), "uart backend is not ready");
81
82 #ifdef CONFIG_TRACING_HANDLE_HOST_CMD
83 uart_irq_rx_disable(tracing_uart_dev);
84 uart_irq_tx_disable(tracing_uart_dev);
85
86 uart_irq_callback_set(tracing_uart_dev, uart_isr);
87
88 while (uart_irq_rx_ready(tracing_uart_dev)) {
89 uint8_t c;
90
91 uart_fifo_read(tracing_uart_dev, &c, 1);
92 }
93
94 uart_irq_rx_enable(tracing_uart_dev);
95 #endif
96 }
97
98 const struct tracing_backend_api tracing_backend_uart_api = {
99 .init = tracing_backend_uart_init,
100 .output = tracing_backend_uart_output
101 };
102
103 TRACING_BACKEND_DEFINE(tracing_backend_uart, tracing_backend_uart_api);
104