1
0
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:
armink 2015-06-25 14:28:18 +08:00
parent 2adfe8a479
commit 3f56ade85f
9 changed files with 195 additions and 19 deletions

View File

@ -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>

View File

@ -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 */

View File

@ -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

View File

@ -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")));

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}