mirror of
https://github.com/armink/EasyLogger.git
synced 2025-01-19 07:42:52 +08:00
1、【增加】开启/关闭同步锁功能,保证系统或硬件在出现异常时,EasyLogger依然正常可以工作。
Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
parent
2adfe8a479
commit
3f56ade85f
@ -21,4 +21,8 @@
|
||||
|
||||
`RVMDK` <20><>ΪKeil<69><6C><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||
|
||||
`EWARM` <20><>ΪIAR<41><52><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||
`EWARM` <20><>ΪIAR<41><52><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||
|
||||
## 3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
- 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RTT<54><54><EFBFBD>Լ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>쳣<EFBFBD>Ĺ<EFBFBD><C4B9>ӵķ<D3B5><C4B7><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ϵͳ<CFB5>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD>쳣ʱ<ECB3A3><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>Ȼ<EFBFBD><C8BB><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>档<F2B1A3B4>ο<EFBFBD> `app\src\app_task.c` <20>е<EFBFBD> `assert_hook` <20><> `exception_hook` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
@ -84,8 +84,13 @@ while (0)
|
||||
if (!(EX)) \
|
||||
{ \
|
||||
volatile char dummy = 0; \
|
||||
rt_kprintf("(%s) assert failed at %s:%d \n", #EX, __FUNCTION__, __LINE__);\
|
||||
while (dummy == 0); \
|
||||
if (rt_assert_hook == RT_NULL) \
|
||||
{ \
|
||||
rt_kprintf("(%s) assert failed at %s:%d \n", #EX, __FUNCTION__, __LINE__);\
|
||||
while (dummy == 0); \
|
||||
} else { \
|
||||
rt_assert_hook(#EX, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Macro to check current context */
|
||||
|
@ -510,6 +510,11 @@ rt_uint32_t rt_strcasecmp(const char *a, const char *b);
|
||||
|
||||
void rt_show_version(void);
|
||||
|
||||
#ifdef RT_DEBUG
|
||||
extern void (*rt_assert_hook)(const char* ex, const char* func, rt_size_t line);
|
||||
void rt_assert_set_hook(void (*hook)(const char* ex, const char* func, rt_size_t line));
|
||||
#endif /* RT_DEBUG */
|
||||
|
||||
/*@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1249,6 +1249,19 @@ int __rt_ffs(int value)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RT_DEBUG
|
||||
/* RT_ASSERT(EX)'s hook */
|
||||
void (*rt_assert_hook)(const char* ex, const char* func, rt_size_t line);
|
||||
/**
|
||||
* This function will set a hook function to RT_ASSERT(EX). It will run when the expression is false.
|
||||
*
|
||||
* @param hook the hook function
|
||||
*/
|
||||
void rt_assert_set_hook(void (*hook)(const char* ex, const char* func, rt_size_t line)) {
|
||||
rt_assert_hook = hook;
|
||||
}
|
||||
#endif /* RT_DEBUG */
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) && defined (__GNUC__)
|
||||
#include <sys/types.h>
|
||||
void *memcpy(void *dest, const void *src, size_t n) __attribute__((weak, alias("rt_memcpy")));
|
||||
|
@ -32,6 +32,8 @@ static rt_uint8_t thread_sys_monitor_stack[512];
|
||||
struct rt_thread thread_sys_monitor;
|
||||
|
||||
static void test_elog(void);
|
||||
static void assert_hook(const char* ex, const char* func, rt_size_t line);
|
||||
static rt_err_t exception_hook(void *context);
|
||||
|
||||
/**
|
||||
* System monitor thread.
|
||||
@ -90,6 +92,10 @@ void sys_init_thread(void* parameter){
|
||||
/* set enabled format */
|
||||
elog_set_fmt(ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME /*| ELOG_FMT_P_INFO*/ | ELOG_FMT_T_INFO | ELOG_FMT_DIR
|
||||
/*| ELOG_FMT_FUNC*/ | ELOG_FMT_LINE);
|
||||
/* set hardware exception hook */
|
||||
rt_hw_exception_install(exception_hook);
|
||||
/* set RT-Thread assert hook */
|
||||
rt_assert_set_hook(assert_hook);
|
||||
/* initialize OK and switch to running status */
|
||||
set_system_status(SYSTEM_STATUS_RUN);
|
||||
} else {
|
||||
@ -100,6 +106,45 @@ void sys_init_thread(void* parameter){
|
||||
rt_thread_delete(rt_thread_self());
|
||||
}
|
||||
|
||||
static void assert_hook(const char* ex, const char* func, rt_size_t line) {
|
||||
elog_output_lock_enabled(false);
|
||||
//elog_flash_lock_enabled(false);
|
||||
elog_a("assert", "(%s) has assert failed at %s:%ld.\n", ex, func, line);
|
||||
//elog_flash_flush();
|
||||
while(1);
|
||||
}
|
||||
|
||||
static rt_err_t exception_hook(void *context) {
|
||||
struct exception_stack_frame {
|
||||
rt_uint32_t r0;
|
||||
rt_uint32_t r1;
|
||||
rt_uint32_t r2;
|
||||
rt_uint32_t r3;
|
||||
rt_uint32_t r12;
|
||||
rt_uint32_t lr;
|
||||
rt_uint32_t pc;
|
||||
rt_uint32_t psr;
|
||||
};
|
||||
struct exception_stack_frame *exception_stack = (struct exception_stack_frame *) context;
|
||||
|
||||
elog_output_lock_enabled(false);
|
||||
//elog_flash_lock_enabled(false);
|
||||
|
||||
elog_e("hw_fault", "psr: 0x%08x", exception_stack->psr);
|
||||
elog_e("hw_fault", " pc: 0x%08x", exception_stack->pc);
|
||||
elog_e("hw_fault", " lr: 0x%08x", exception_stack->lr);
|
||||
elog_e("hw_fault", "r12: 0x%08x", exception_stack->r12);
|
||||
elog_e("hw_fault", "r03: 0x%08x", exception_stack->r3);
|
||||
elog_e("hw_fault", "r02: 0x%08x", exception_stack->r2);
|
||||
elog_e("hw_fault", "r01: 0x%08x", exception_stack->r1);
|
||||
elog_e("hw_fault", "r00: 0x%08x", exception_stack->r0);
|
||||
elog_e("hw_fault", "hard fault on thread: %s", rt_thread_self()->name);
|
||||
|
||||
//elog_flash_flush();
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int rt_application_init(void)
|
||||
{
|
||||
rt_thread_t init_thread = NULL;
|
||||
|
@ -61,7 +61,7 @@ extern "C" {
|
||||
/* output newline sign */
|
||||
#define ELOG_NEWLINE_SIGN "\r\n"
|
||||
/* EasyLogger software version number */
|
||||
#define ELOG_SW_VERSION "0.06.24"
|
||||
#define ELOG_SW_VERSION "0.06.25"
|
||||
|
||||
/* EasyLogger assert for developer. */
|
||||
#define ELOG_ASSERT(EXPR) \
|
||||
@ -115,6 +115,7 @@ void elog_set_filter_kw(const char *keyword);
|
||||
void elog_raw(const char *format, ...);
|
||||
void elog_output(uint8_t level, const char *tag, const char *file, const char *func,
|
||||
const long line, const char *format, ...);
|
||||
void elog_output_lock_enabled(bool enabled);
|
||||
|
||||
#ifndef ELOG_OUTPUT_ENABLE
|
||||
|
||||
|
@ -40,7 +40,7 @@ extern "C" {
|
||||
/* EasyLogger flash save plugin's RAM buffer size */
|
||||
#define ELOG_FLASH_BUF_SIZE 1024
|
||||
/* EasyLogger flash save plugin's software version number */
|
||||
#define ELOG_FLASH_SW_VERSION "0.06.10"
|
||||
#define ELOG_FLASH_SW_VERSION "0.06.25"
|
||||
|
||||
/* elog_flash.c */
|
||||
ElogErrCode elog_flash_init(void);
|
||||
@ -50,6 +50,7 @@ void elog_flash_outout_recent(size_t size);
|
||||
void elog_flash_set_filter(uint8_t level,const char *tag,const char *keyword);
|
||||
void elog_flash_write(const char *log, size_t size);
|
||||
void elog_flash_clean(void);
|
||||
void elog_flash_lock_enabled(bool enabled);
|
||||
|
||||
#ifdef ELOG_FLASH_USING_BUF_MODE
|
||||
void elog_flash_flush(void);
|
||||
|
@ -46,6 +46,14 @@ static const char *level_output_info[] = {
|
||||
"D/",
|
||||
"V/",
|
||||
};
|
||||
/* the output lock enable or disable. default is enable */
|
||||
static bool output_lock_enabled = true;
|
||||
/* the output is locked before enable. */
|
||||
static bool output_is_locked_before_enable = false;
|
||||
/* the output is locked before disable. */
|
||||
static bool output_is_locked_before_disable = false;
|
||||
static void output_lock(void);
|
||||
static void output_unlock(void);
|
||||
static bool get_fmt_enabled(size_t set);
|
||||
|
||||
/**
|
||||
@ -166,7 +174,7 @@ void elog_raw(const char *format, ...) {
|
||||
va_start(args, format);
|
||||
|
||||
/* lock output */
|
||||
elog_port_output_lock();
|
||||
output_lock();
|
||||
|
||||
/* package log data to buffer */
|
||||
fmt_result = vsnprintf(log_buf, ELOG_BUF_SIZE, format, args);
|
||||
@ -225,7 +233,7 @@ void elog_output(uint8_t level, const char *tag, const char *file, const char *f
|
||||
va_start(args, format);
|
||||
|
||||
/* lock output */
|
||||
elog_port_output_lock();
|
||||
output_lock();
|
||||
/* package level info */
|
||||
if (get_fmt_enabled(ELOG_FMT_LVL)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, level_output_info[level]);
|
||||
@ -307,7 +315,7 @@ void elog_output(uint8_t level, const char *tag, const char *file, const char *f
|
||||
if (!strstr(log_buf, elog.filter.keyword)) {
|
||||
//TODO <20><><EFBFBD>Կ<EFBFBD><D4BF>Dz<EFBFBD><C7B2><EFBFBD>KMP<4D><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽƥ<CABD><C6A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/* unlock output */
|
||||
elog_port_output_unlock();
|
||||
output_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -325,7 +333,7 @@ void elog_output(uint8_t level, const char *tag, const char *file, const char *f
|
||||
elog_port_output(log_buf, log_len);
|
||||
|
||||
/* unlock output */
|
||||
elog_port_output_unlock();
|
||||
output_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,3 +350,46 @@ static bool get_fmt_enabled(size_t set) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enable or disable logger output lock
|
||||
* @note disable this lock is not recommended except you want output system exception log
|
||||
*
|
||||
* @param enabled true: enable false: disable
|
||||
*/
|
||||
void elog_output_lock_enabled(bool enabled) {
|
||||
output_lock_enabled = enabled;
|
||||
/* it will re-lock or re-unlock before output lock enable */
|
||||
if (output_lock_enabled) {
|
||||
if (!output_is_locked_before_disable && output_is_locked_before_enable) {
|
||||
/* the output lock is unlocked before disable, and the lock will unlocking after enable */
|
||||
elog_port_output_lock();
|
||||
} else if (output_is_locked_before_disable && !output_is_locked_before_enable) {
|
||||
/* the output lock is locked before disable, and the lock will locking after enable */
|
||||
elog_port_output_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lock output
|
||||
*/
|
||||
static void output_lock(void) {
|
||||
if (output_lock_enabled) {
|
||||
elog_port_output_lock();
|
||||
output_is_locked_before_disable = true;
|
||||
} else {
|
||||
output_is_locked_before_enable = true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* unlock output
|
||||
*/
|
||||
static void output_unlock(void) {
|
||||
if (output_lock_enabled) {
|
||||
elog_port_output_unlock();
|
||||
output_is_locked_before_disable = false;
|
||||
} else {
|
||||
output_is_locked_before_enable = false;
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,14 @@ static size_t cur_buf_size = 0;
|
||||
|
||||
/* initialize OK flag */
|
||||
static bool init_ok = false;
|
||||
/* the flash log buffer lock enable or disable. default is enable */
|
||||
static bool log_buf_lock_enabled = true;
|
||||
/* the flash log buffer is locked before enable. */
|
||||
static bool log_buf_is_locked_before_enable = false;
|
||||
/* the flash log buffer is locked before disable. */
|
||||
static bool log_buf_is_locked_before_disable = false;
|
||||
static void log_buf_lock(void);
|
||||
static void log_buf_unlock(void);
|
||||
|
||||
/**
|
||||
* EasyLogger flash save plugin initialize.
|
||||
@ -94,7 +102,7 @@ void elog_flash_outout(size_t index, size_t size) {
|
||||
/* must be call this function after initialize OK */
|
||||
ELOG_ASSERT(init_ok);
|
||||
/* lock flash log buffer */
|
||||
elog_flash_port_lock();
|
||||
log_buf_lock();
|
||||
/* Output all flash saved log. It will use filter */
|
||||
while (true) {
|
||||
if (index + read_size + buf_szie < log_total_size) {
|
||||
@ -118,7 +126,7 @@ void elog_flash_outout(size_t index, size_t size) {
|
||||
}
|
||||
}
|
||||
/* unlock flash log buffer */
|
||||
elog_flash_port_unlock();
|
||||
log_buf_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,7 +171,7 @@ void elog_flash_write(const char *log, size_t size) {
|
||||
ELOG_ASSERT(init_ok);
|
||||
|
||||
/* lock flash log buffer */
|
||||
elog_flash_port_lock();
|
||||
log_buf_lock();
|
||||
|
||||
#ifdef ELOG_FLASH_USING_BUF_MODE
|
||||
while (true) {
|
||||
@ -174,11 +182,11 @@ void elog_flash_write(const char *log, size_t size) {
|
||||
size -= write_size;
|
||||
cur_buf_size += write_size;
|
||||
/* unlock flash log buffer */
|
||||
elog_flash_port_unlock();
|
||||
log_buf_unlock();
|
||||
/* write all buffered log to flash, cur_buf_size will reset */
|
||||
elog_flash_flush();
|
||||
/* lock flash log buffer */
|
||||
elog_flash_port_lock();
|
||||
log_buf_lock();
|
||||
} else {
|
||||
memcpy(log_buf + cur_buf_size, log + write_index, size);
|
||||
cur_buf_size += size;
|
||||
@ -198,7 +206,7 @@ void elog_flash_write(const char *log, size_t size) {
|
||||
#endif
|
||||
|
||||
/* unlock flash log buffer */
|
||||
elog_flash_port_unlock();
|
||||
log_buf_unlock();
|
||||
}
|
||||
|
||||
#ifdef ELOG_FLASH_USING_BUF_MODE
|
||||
@ -211,7 +219,7 @@ void elog_flash_flush(void) {
|
||||
/* must be call this function after initialize OK */
|
||||
ELOG_ASSERT(init_ok);
|
||||
/* lock flash log buffer */
|
||||
elog_flash_port_lock();
|
||||
log_buf_lock();
|
||||
/* flash write is word alignment */
|
||||
if (cur_buf_size % 4 != 0) {
|
||||
write_overage_size = 4 - (cur_buf_size % 4);
|
||||
@ -223,7 +231,7 @@ void elog_flash_flush(void) {
|
||||
/* reset position */
|
||||
cur_buf_size = 0;
|
||||
/* unlock flash log buffer */
|
||||
elog_flash_port_unlock();
|
||||
log_buf_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -236,7 +244,7 @@ void elog_flash_clean(void) {
|
||||
/* must be call this function after initialize OK */
|
||||
ELOG_ASSERT(init_ok);
|
||||
/* lock flash log buffer */
|
||||
elog_flash_port_lock();
|
||||
log_buf_lock();
|
||||
/* clean all log which in flash */
|
||||
clean_result = flash_log_clean();
|
||||
|
||||
@ -246,7 +254,7 @@ void elog_flash_clean(void) {
|
||||
#endif
|
||||
|
||||
/* unlock flash log buffer */
|
||||
elog_flash_port_unlock();
|
||||
log_buf_unlock();
|
||||
|
||||
if(clean_result == FLASH_NO_ERR) {
|
||||
log_i("All logs which in flash is clean OK.");
|
||||
@ -254,3 +262,46 @@ void elog_flash_clean(void) {
|
||||
log_e("Clean logs which in flash has an error!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enable or disable flash plugin lock
|
||||
* @note disable this lock is not recommended except you want output system exception log
|
||||
*
|
||||
* @param enabled true: enable false: disable
|
||||
*/
|
||||
void elog_flash_lock_enabled(bool enabled) {
|
||||
log_buf_lock_enabled = enabled;
|
||||
/* it will re-lock or re-unlock before log buffer lock enable */
|
||||
if (log_buf_lock_enabled) {
|
||||
if (!log_buf_is_locked_before_disable && log_buf_is_locked_before_enable) {
|
||||
/* the log buffer lock is unlocked before disable, and the lock will unlocking after enable */
|
||||
elog_flash_port_lock();
|
||||
} else if (log_buf_is_locked_before_disable && !log_buf_is_locked_before_enable) {
|
||||
/* the log buffer lock is locked before disable, and the lock will locking after enable */
|
||||
elog_flash_port_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lock flash log buffer
|
||||
*/
|
||||
static void log_buf_lock(void) {
|
||||
if (log_buf_lock_enabled) {
|
||||
elog_flash_port_lock();
|
||||
log_buf_is_locked_before_disable = true;
|
||||
} else {
|
||||
log_buf_is_locked_before_enable = true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* unlock flash log buffer
|
||||
*/
|
||||
static void log_buf_unlock(void) {
|
||||
if (log_buf_lock_enabled) {
|
||||
elog_flash_port_unlock();
|
||||
log_buf_is_locked_before_disable = false;
|
||||
} else {
|
||||
log_buf_is_locked_before_enable = false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user