pinebuds/platform/hal/hal_trace.h

523 lines
21 KiB
C

/***************************************************************************
*
* Copyright 2015-2019 BES.
* All rights reserved. All unpublished rights reserved.
*
* No part of this work may be used or reproduced in any form or by any
* means, or stored in a database or retrieval system, without prior written
* permission of BES.
*
* Use of this work is governed by a license granted by BES.
* This work contains confidential and proprietary information of
* BES. which is protected by copyright, trade secret,
* trademark and other intellectual property rights.
*
****************************************************************************/
#ifndef __HAL_TRACE_H__
#define __HAL_TRACE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "hal_trace_mod.h"
#include "plat_types.h"
#if 0
#define AUDIO_DEBUG
#define AUDIO_DEBUG_V0_1_0
#define INTERSYS_RAW_DATA_ONLY
#ifdef AUDIO_DEBUG
#undef TRACE_BAUD_RATE
#define TRACE_BAUD_RATE 2000000
#endif
#endif
#if (defined(AUDIO_DEBUG) && !defined(AUDIO_DEBUG_V0_1_0))
#define NO_REL_TRACE
#endif
#if (defined(AUDIO_DEBUG) && !defined(AUDIO_DEBUG_V0_1_0)) || \
defined(INTERSYS_RAW_DATA_ONLY)
#define NO_TRACE
#endif
#if defined(__BT_DEBUG_TPORTS__) || defined(AUDIO_DEBUG_V0_1_0)
#ifndef TPORTS_KEY_COEXIST
#ifndef HAL_TRACE_RX_ENABLE
#define HAL_TRACE_RX_ENABLE
#endif
#ifndef CRASH_REBOOT
#define CRASH_REBOOT
#endif
#endif
#endif
/*
* Total number of core registers stored
*/
#define CRASH_DUMP_REGISTERS_NUM 17
#define CRASH_DUMP_REGISTERS_NUM_BYTES ((CRASH_DUMP_REGISTERS_NUM)*4)
/*
* Number bytes to store from stack
* - this is total, not per PSP/MSP
*/
#define CRASH_DUMP_STACK_NUM_BYTES 384
// Log Attributes
#define LOG_ATTR_ARG_NUM_SHIFT 0
#define LOG_ATTR_ARG_NUM_MASK (0xF << LOG_ATTR_ARG_NUM_SHIFT)
#define LOG_ATTR_ARG_NUM(n) BITFIELD_VAL(LOG_ATTR_ARG_NUM, n)
#define LOG_ATTR_LEVEL_SHIFT 4
#define LOG_ATTR_LEVEL_MASK (0x7 << LOG_ATTR_LEVEL_SHIFT)
#define LOG_ATTR_LEVEL(n) BITFIELD_VAL(LOG_ATTR_LEVEL, n)
#define LOG_ATTR_MOD_SHIFT 7
#define LOG_ATTR_MOD_MASK (0x7F << LOG_ATTR_MOD_SHIFT)
#define LOG_ATTR_MOD(n) BITFIELD_VAL(LOG_ATTR_MOD, n)
#define LOG_ATTR_IMM (1 << 14)
#define LOG_ATTR_NO_LF (1 << 15)
#define LOG_ATTR_NO_TS (1 << 16)
#define LOG_ATTR_NO_ID (1 << 17)
// Count variadic argument number
#define _VAR_ARG_12(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, ...) a12
#define COUNT_ARG_NUM(...) \
_VAR_ARG_12(unused, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#if defined(TRACE_STR_SECTION) && !(defined(ROM_BUILD) || defined(PROGRAMMER))
#define CONCAT_(x, y) x##y
#define CONCATS(x, y) CONCAT_(x, y)
#define __trcname CONCATS(__trc, __LINE__)
#define TRC_STR_LOC \
__attribute__((section(TO_STRING(CONCATS(.trc_str, __LINE__)))))
#define TRC_STR(s) \
(({ \
static const char TRC_STR_LOC __trcname[] = (s); \
__trcname; \
}))
#else
#define TRC_STR_LOC
#define TRC_STR(s) (s)
#endif
#define LOG_DUMMY(attr, str, ...) hal_trace_dummy(str, ##__VA_ARGS__)
#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && !defined(NO_REL_TRACE)
#define REL_LOG(attr, str, ...) \
hal_trace_printf(((attr) & ~LOG_ATTR_ARG_NUM_MASK) | \
LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), \
TRC_STR(str), ##__VA_ARGS__)
#define REL_LOG_RAW_OUTPUT(str, len) hal_trace_output(str, len)
#define REL_LOG_FLUSH() hal_trace_flush_buffer()
#define REL_DUMP8(str, buf, cnt) hal_trace_dump(str, sizeof(uint8_t), cnt, buf)
#define REL_DUMP16(str, buf, cnt) \
hal_trace_dump(str, sizeof(uint16_t), cnt, buf)
#define REL_DUMP32(str, buf, cnt) \
hal_trace_dump(str, sizeof(uint32_t), cnt, buf)
#else
#define REL_LOG(attr, str, ...) hal_trace_dummy(str, ##__VA_ARGS__)
#define REL_LOG_RAW_OUTPUT(str, len) hal_trace_dummy((const char *)str, len)
#define REL_LOG_FLUSH() hal_trace_dummy(NULL)
#define REL_DUMP8(str, buf, cnt) hal_dump_dummy(str, buf, cnt)
#define REL_DUMP16(str, buf, cnt) hal_dump_dummy(str, buf, cnt)
#define REL_DUMP32(str, buf, cnt) hal_dump_dummy(str, buf, cnt)
#endif
#if (!defined(DEBUG) && defined(REL_TRACE_ENABLE)) && !defined(NO_TRACE)
// To avoid warnings on unused variables
#define NORM_LOG(num, str, ...) hal_trace_dummy(str, ##__VA_ARGS__)
#define NORM_LOG_RAW_OUTPUT(str, len) hal_trace_dummy((const char *)str, len)
#define NORM_LOG_FLUSH() hal_trace_dummy(NULL)
#define DUMP8(str, buf, cnt) hal_dump_dummy(str, buf, cnt)
#define DUMP16(str, buf, cnt) hal_dump_dummy(str, buf, cnt)
#define DUMP32(str, buf, cnt) hal_dump_dummy(str, buf, cnt)
#else
#define NORM_LOG REL_LOG
#define NORM_LOG_RAW_OUTPUT REL_LOG_RAW_OUTPUT
#define NORM_LOG_FLUSH REL_TRACE_FLUSH
#define DUMP8 REL_DUMP8
#define DUMP16 REL_DUMP16
#define DUMP32 REL_DUMP32
#endif
#define RLOG_CRITICAL(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | \
LOG_ATTR_LEVEL(LOG_LEVEL_CRITICAL), \
str, ##__VA_ARGS__)
#define RLOG_ERROR(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_ERROR), \
str, ##__VA_ARGS__)
#define RLOG_WARN(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_WARN), \
str, ##__VA_ARGS__)
#define RLOG_NOTIF(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_NOTIF), \
str, ##__VA_ARGS__)
#define RLOG_INFO(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_INFO), \
str, ##__VA_ARGS__)
#define RLOG_DEBUG(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_DEBUG), \
str, ##__VA_ARGS__)
#define RLOG_VERBOSE(attr, str, ...) \
REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_VERBOSE), \
str, ##__VA_ARGS__)
#define LOG_CRITICAL(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | \
LOG_ATTR_LEVEL(LOG_LEVEL_CRITICAL), \
str, ##__VA_ARGS__)
#define LOG_ERROR(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_ERROR), \
str, ##__VA_ARGS__)
#define LOG_WARN(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_WARN), \
str, ##__VA_ARGS__)
#define LOG_NOTIF(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_NOTIF), \
str, ##__VA_ARGS__)
#define LOG_INFO(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_INFO), \
str, ##__VA_ARGS__)
#define LOG_DEBUG(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_DEBUG), \
str, ##__VA_ARGS__)
#define LOG_VERBOSE(attr, str, ...) \
NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | \
LOG_ATTR_LEVEL(LOG_LEVEL_VERBOSE), \
str, ##__VA_ARGS__)
#define REL_TRACE(attr, str, ...) RLOG_NOTIF(attr, str, ##__VA_ARGS__)
#define REL_TRACE_IMM(attr, str, ...) \
RLOG_NOTIF((attr) | LOG_ATTR_IMM, str, ##__VA_ARGS__)
#define REL_TRACE_NOCRLF(attr, str, ...) \
RLOG_NOTIF((attr) | LOG_ATTR_NO_LF, str, ##__VA_ARGS__)
#define REL_TRACE_NOTS(attr, str, ...) \
RLOG_NOTIF((attr) | LOG_ATTR_NO_TS, str, ##__VA_ARGS__)
#define REL_TRACE_IMM_NOTS(attr, str, ...) \
RLOG_NOTIF((attr) | LOG_ATTR_IMM | LOG_ATTR_NO_TS, str, ##__VA_ARGS__)
#define REL_TRACE_NOCRLF_NOTS(attr, str, ...) \
RLOG_NOTIF((attr) | LOG_ATTR_NO_LF | LOG_ATTR_NO_TS, str, ##__VA_ARGS__)
#define REL_FUNC_ENTRY_TRACE() RLOG_NOTIF(1, "%s", __FUNCTION__)
#define REL_TRACE_OUTPUT(str, len) REL_LOG_RAW_OUTPUT(str, len)
#define REL_TRACE_FLUSH() REL_LOG_FLUSH()
#define TRACE(attr, str, ...) LOG_INFO(attr, str, ##__VA_ARGS__)
#define TRACE_IMM(attr, str, ...) \
LOG_INFO((attr) | LOG_ATTR_IMM, str, ##__VA_ARGS__)
#define TRACE_NOCRLF(attr, str, ...) \
LOG_INFO((attr) | LOG_ATTR_NO_LF, str, ##__VA_ARGS__)
#define FUNC_ENTRY_TRACE() LOG_INFO(1, "%s", __FUNCTION__)
#define TRACE_OUTPUT(str, len) NORM_LOG_RAW_OUTPUT(str, len)
#define TRACE_FLUSH() NORM_LOG_FLUSH()
#ifdef BES_AUTOMATE_TEST
#define AUTO_TEST_TRACE(attr, str, ...) \
LOG_INFO(attr, "_AT_" str, ##__VA_ARGS__)
#else
#define AUTO_TEST_TRACE(attr, str, ...) LOG_INFO(attr, str, ##__VA_ARGS__)
#endif
#define TRACE_DUMMY(attr, str, ...) LOG_DUMMY(attr, str, ##__VA_ARGS__)
#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && \
defined(ASSERT_SHOW_FILE_FUNC)
#define ASSERT(cond, str, ...) \
{ \
if (!(cond)) { \
hal_trace_assert_dump(__FILE__, __FUNCTION__, __LINE__, str, \
##__VA_ARGS__); \
} \
}
#define ASSERT_DUMP_ARGS \
const char *file, const char *func, unsigned int line, const char *fmt, ...
#define ASSERT_FMT_ARG_IDX 4
#elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE)
#define ASSERT(cond, str, ...) \
{ \
if (!(cond)) { \
hal_trace_assert_dump(__FILE__, __LINE__, str, ##__VA_ARGS__); \
} \
}
#define ASSERT_DUMP_ARGS \
const char *file, const char *func, unsigned int line, const char *fmt, ...
#define ASSERT_FMT_ARG_IDX 4
#elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FUNC)
#define ASSERT(cond, str, ...) \
{ \
if (!(cond)) { \
hal_trace_assert_dump(__FUNCTION__, __LINE__, str, ##__VA_ARGS__); \
} \
}
#define ASSERT_DUMP_ARGS \
const char *scope, unsigned int line, const char *fmt, ...
#define ASSERT_FMT_ARG_IDX 3
#elif (defined(DEBUG) || defined(REL_TRACE_ENABLE))
#define ASSERT(cond, str, ...) \
{ \
if (!(cond)) { \
hal_trace_assert_dump(str, ##__VA_ARGS__); \
} \
}
#define ASSERT_DUMP_ARGS const char *fmt, ...
#define ASSERT_FMT_ARG_IDX 1
#else
#define ASSERT(cond, str, ...) \
{ \
if (!(cond)) { \
hal_trace_dummy(str, ##__VA_ARGS__); \
hal_trace_assert_dump(NULL); \
} \
}
#define ASSERT_DUMP_ARGS const char *fmt
#define ASSERT_FMT_ARG_IDX 0
#endif
#if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
#define TRACE_FUNC_DECLARE(d, r) d
#else
#ifndef TRACE_FUNC_SPEC
#define TRACE_FUNC_SPEC static inline
#endif
#define TRACE_FUNC_DECLARE(d, r) \
TRACE_FUNC_SPEC d { r; }
#endif
#if defined(__GNUC__) && !defined(NO_CHK_TRC_FMT)
#define TRC_FMT_CHK(sidx, vaidx) \
__attribute__((format(printf, (sidx), (vaidx))))
#else
#define TRC_FMT_CHK(sidx, vaidx)
#endif
#define ASSERT_NODUMP(cond) \
{ \
if (!(cond)) { \
SAFE_PROGRAM_STOP(); \
} \
}
#ifdef CHIP_BEST1000
// Avoid CPU instruction fetch blocking the system bus on BEST1000
#define SAFE_PROGRAM_STOP() \
do { \
asm volatile("nop; nop; nop; nop"); \
} while (1)
#else
#define SAFE_PROGRAM_STOP() \
do { \
} while (1)
#endif
enum HAL_TRACE_TRANSPORT_T {
#ifdef CHIP_HAS_USB
HAL_TRACE_TRANSPORT_USB,
#endif
HAL_TRACE_TRANSPORT_UART0,
#if (CHIP_HAS_UART > 1)
HAL_TRACE_TRANSPORT_UART1,
#endif
#if (CHIP_HAS_UART > 2)
HAL_TRACE_TRANSPORT_UART2,
#endif
HAL_TRACE_TRANSPORT_QTY
};
enum HAL_TRACE_STATE_T {
HAL_TRACE_STATE_CRASH_ASSERT_START,
HAL_TRACE_STATE_CRASH_FAULT_START,
HAL_TRACE_STATE_CRASH_END,
};
enum HAL_TRACE_BUF_STATE_T {
HAL_TRACE_BUF_STATE_FLUSH,
HAL_TRACE_BUF_STATE_NEAR_FULL,
HAL_TRACE_BUF_STATE_FULL,
};
enum HAL_TRACE_CRASH_DUMP_MODULE_T {
HAL_TRACE_CRASH_DUMP_MODULE_SYS = 0,
HAL_TRACE_CRASH_DUMP_MODULE_ID1 = 1,
HAL_TRACE_CRASH_DUMP_MODULE_ID2 = 2,
HAL_TRACE_CRASH_DUMP_MODULE_ID3 = 3,
HAL_TRACE_CRASH_DUMP_MODULE_BT = 4,
HAL_TRACE_CRASH_DUMP_MODULE_END = 5,
};
enum LOG_LEVEL_T {
LOG_LEVEL_CRITICAL = 0,
LOG_LEVEL_ERROR = 1,
LOG_LEVEL_WARN = 2,
LOG_LEVEL_NOTIF = 3,
LOG_LEVEL_INFO = 4,
LOG_LEVEL_DEBUG = 5,
LOG_LEVEL_VERBOSE = 6,
LOG_LEVEL_QTY,
};
typedef void (*HAL_TRACE_CRASH_DUMP_CB_T)(void);
typedef void (*HAL_TRACE_APP_NOTIFY_T)(enum HAL_TRACE_STATE_T state);
typedef void (*HAL_TRACE_APP_OUTPUT_T)(const unsigned char *buf,
unsigned int buf_len);
typedef void (*HAL_TRACE_BUF_CTRL_T)(enum HAL_TRACE_BUF_STATE_T buf_ctrl);
int hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport);
int hal_trace_open_cp(void);
TRACE_FUNC_DECLARE(int hal_trace_switch(enum HAL_TRACE_TRANSPORT_T transport),
return 0);
TRACE_FUNC_DECLARE(int hal_trace_close(void), return 0);
TRACE_FUNC_DECLARE(int hal_trace_enable_log_module(enum LOG_MODULE_T module),
return 0);
TRACE_FUNC_DECLARE(int hal_trace_disable_log_module(enum LOG_MODULE_T module),
return 0);
TRACE_FUNC_DECLARE(int hal_trace_set_log_module(const uint32_t *map,
uint32_t word_cnt),
return 0);
TRACE_FUNC_DECLARE(int hal_trace_set_log_level(enum LOG_LEVEL_T level),
return 0);
TRACE_FUNC_DECLARE(void hal_trace_get_history_buffer(const unsigned char **buf1,
unsigned int *len1,
const unsigned char **buf2,
unsigned int *len2),
{
if (buf1) {
*buf1 = NULL;
}
if (len1) {
*len1 = 0;
}
if (buf2) {
*buf2 = NULL;
}
if (len2) {
*len2 = 0;
}
});
TRACE_FUNC_DECLARE(int hal_trace_output(const unsigned char *buf,
unsigned int buf_len),
return 0);
TRC_FMT_CHK(2, 3)
TRACE_FUNC_DECLARE(int hal_trace_printf(uint32_t attr, const char *fmt, ...),
return 0);
TRACE_FUNC_DECLARE(int hal_trace_dump(const char *fmt, unsigned int size,
unsigned int count, const void *buffer),
return 0);
TRACE_FUNC_DECLARE(int hal_trace_busy(void), return 0);
TRACE_FUNC_DECLARE(int hal_trace_pause(void), return 0);
TRACE_FUNC_DECLARE(int hal_trace_continue(void), return 0);
TRACE_FUNC_DECLARE(int hal_trace_flush_buffer(void), return 0);
TRACE_FUNC_DECLARE(void hal_trace_idle_send(void), return);
TRACE_FUNC_DECLARE(
int hal_trace_crash_dump_register(enum HAL_TRACE_CRASH_DUMP_MODULE_T module,
HAL_TRACE_CRASH_DUMP_CB_T cb),
return 0);
TRACE_FUNC_DECLARE(
void hal_trace_app_register(HAL_TRACE_APP_NOTIFY_T notify_cb,
HAL_TRACE_APP_OUTPUT_T output_cb),
return);
TRACE_FUNC_DECLARE(
void hal_trace_app_custom_register(HAL_TRACE_APP_NOTIFY_T notify_cb,
HAL_TRACE_APP_OUTPUT_T output_cb,
HAL_TRACE_APP_OUTPUT_T crash_custom_cb),
return);
TRACE_FUNC_DECLARE(void hal_trace_cp_register(HAL_TRACE_APP_NOTIFY_T notify_cb,
HAL_TRACE_BUF_CTRL_T buf_cb),
return);
TRACE_FUNC_DECLARE(void hal_trace_print_backtrace(uint32_t addr,
uint32_t search_cnt,
uint32_t print_cnt),
return);
TRACE_FUNC_DECLARE(bool hal_trace_crash_dump_onprocess(void), return false);
TRACE_FUNC_DECLARE(uint32_t hal_trace_get_baudrate(void), return 0);
TRC_FMT_CHK(1, 2)
static inline void hal_trace_dummy(const char *fmt, ...) {}
static inline void hal_dump_dummy(const char *fmt, ...) {}
#if (ASSERT_FMT_ARG_IDX > 0)
TRC_FMT_CHK(ASSERT_FMT_ARG_IDX, ASSERT_FMT_ARG_IDX + 1)
#endif
void NORETURN hal_trace_assert_dump(ASSERT_DUMP_ARGS);
int hal_trace_address_writable(uint32_t addr);
int hal_trace_address_executable(uint32_t addr);
int hal_trace_address_readable(uint32_t addr);
//==============================================================================
// AUDIO_DEBUG
//==============================================================================
#ifdef AUDIO_DEBUG
#define AUDIO_DEBUG_TRACE(str, ...) hal_trace_printf(str, ##__VA_ARGS__)
#define AUDIO_DEBUG_DUMP(buf, cnt) hal_trace_output(buf, cnt)
#endif
//==============================================================================
// INTERSYS_RAW_DATA_ONLY
//==============================================================================
#ifdef INTERSYS_RAW_DATA_ONLY
#define TRACE_RAW(str, ...) hal_trace_printf(str, ##__VA_ARGS__)
#define DUMP8_RAW(str, buf, cnt) hal_trace_dump(str, sizeof(uint8_t), cnt, buf)
#endif
//==============================================================================
// TRACE RX
//==============================================================================
#if defined(_AUTO_TEST_)
#ifndef HAL_TRACE_RX_ENABLE
#define HAL_TRACE_RX_ENABLE
#endif
extern int auto_test_send(char *resp);
#define AUTO_TEST_SEND(str) auto_test_send((char *)str)
#endif
#include "stdio.h"
#define hal_trace_rx_parser(buf, str, ...) sscanf(buf, str, ##__VA_ARGS__)
typedef unsigned int (*HAL_TRACE_RX_CALLBACK_T)(unsigned char *buf,
unsigned int len);
int hal_trace_rx_register(const char *name, HAL_TRACE_RX_CALLBACK_T callback);
int hal_trace_rx_deregister(const char *name);
int hal_trace_rx_reopen();
int hal_trace_rx_open();
#ifdef __cplusplus
}
#endif
#endif