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