zephyr/subsys/debug/tracing/tracing_backend_uart.c
Wentong Wu 8ccc04de6a tracing: add infrastructure for collection of tracing data
First, this commit adds user interface in tracing_format.h which
can trace both string format and data format packet.

Second, it adds method both for asynchronous and synchronous way.
For asynchronous method, tracing packet will be buffered in tracing
buffer first, tracing thread will output the stream data with the
help of tracing backend when tracing thread get scheduled.

Third, it adds UART and USB tracing backend for asynchronous
tracing method, and adds POSIX tracing backend for synchronous
tracing way.

Also it can receive command from host to dynamically enable and
disable tracing to have host capture tracing data conveniently.

Signed-off-by: Wentong Wu <wentong.wu@intel.com>
2020-02-05 23:54:26 -05:00

96 lines
1.7 KiB
C

/*
* Copyright (c) 2019 Intel corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <ctype.h>
#include <kernel.h>
#include <device.h>
#include <drivers/uart.h>
#include <sys/__assert.h>
#include <tracing_core.h>
#include <tracing_buffer.h>
#include <tracing_backend.h>
static struct device *dev;
#ifdef CONFIG_TRACING_HANDLE_HOST_CMD
static void uart_isr(struct device *dev)
{
int rx;
u8_t byte;
static u8_t *cmd;
static u32_t length, cur;
while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
if (!uart_irq_rx_ready(dev)) {
continue;
}
rx = uart_fifo_read(dev, &byte, 1);
if (rx < 0) {
uart_irq_rx_disable(dev);
return;
}
if (!cmd) {
length = tracing_cmd_buffer_alloc(&cmd);
}
if (!isprint(byte)) {
if (byte == '\r') {
cmd[cur] = '\0';
tracing_cmd_handle(cmd, cur);
cmd = NULL;
cur = 0U;
}
continue;
}
if (cur < length - 1) {
cmd[cur++] = byte;
}
}
}
#endif
static void tracing_backend_uart_output(
const struct tracing_backend *backend,
u8_t *data, u32_t length)
{
for (u32_t i = 0; i < length; i++) {
uart_poll_out(dev, data[i]);
}
}
static void tracing_backend_uart_init(void)
{
dev = device_get_binding(CONFIG_TRACING_BACKEND_UART_NAME);
__ASSERT(dev, "uart backend binding failed");
#ifdef CONFIG_TRACING_HANDLE_HOST_CMD
uart_irq_rx_disable(dev);
uart_irq_tx_disable(dev);
uart_irq_callback_set(dev, uart_isr);
while (uart_irq_rx_ready(dev)) {
u8_t c;
uart_fifo_read(dev, &c, 1);
}
uart_irq_rx_enable(dev);
#endif
}
const struct tracing_backend_api tracing_backend_uart_api = {
.init = tracing_backend_uart_init,
.output = tracing_backend_uart_output
};
TRACING_BACKEND_DEFINE(tracing_backend_uart, tracing_backend_uart_api);