Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
285
sdk/app/debug_log_msi/debug_log_msi.c
Normal file
285
sdk/app/debug_log_msi/debug_log_msi.c
Normal file
@@ -0,0 +1,285 @@
|
||||
// 主要是增加debug流,可以保存log到内存,然后发向流,可以作为定时保存log使用
|
||||
// 这个流就不作保护,所以最好单线程去使用(如果多线程,可以增加锁),可以使用一个
|
||||
// 全局去保存对应的句柄,但是这里就不全局保存也不使用全局(可以创建多个流,每个
|
||||
// 独立的线程可以独立调试)
|
||||
#include "debug_log_msi.h"
|
||||
|
||||
#define DEBUG_LOG_STREAM_MALLOC av_psram_malloc
|
||||
#define DEBUG_LOG_STREAM_FREE av_psram_free
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
#define DEBUG_LOG_MAX_NUM 10
|
||||
#define DEBUG_LOG_CACHE_SIZE (1024 * 4) // 4K
|
||||
|
||||
#define DBG_LOG_FAIL_TIMES (3)
|
||||
|
||||
static int32_t debug_log_action(struct msi *msi, uint32_t cmd_id, uint32_t param1, uint32_t param2)
|
||||
{
|
||||
int32_t ret = RET_OK;
|
||||
struct dbg_log_s *log_s = (struct dbg_log_s *) msi->priv;
|
||||
switch (cmd_id)
|
||||
{
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
fbpool_destroy(&log_s->tx_pool);
|
||||
if (log_s)
|
||||
{
|
||||
STREAM_LIBC_FREE(log_s);
|
||||
msi->priv = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_PRE_DESTROY:
|
||||
{
|
||||
if (log_s)
|
||||
{
|
||||
os_work_cancle2(&log_s->work, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
struct framebuff *fb = (struct framebuff *) param1;
|
||||
if (fb->data)
|
||||
{
|
||||
DEBUG_LOG_STREAM_FREE(fb->data);
|
||||
fb->data = NULL;
|
||||
}
|
||||
fb->rev = 0;
|
||||
fbpool_put(&log_s->tx_pool, fb);
|
||||
// 不需要内核去释放fb
|
||||
ret = RET_OK + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t sync_debug_buf(struct dbg_log_s *log_s)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret = 0;
|
||||
|
||||
struct framebuff *fb = NULL;
|
||||
|
||||
flags = disable_irq();
|
||||
if (log_s->fb && log_s->offset)
|
||||
{
|
||||
fb = log_s->fb;
|
||||
fb->len = log_s->offset;
|
||||
log_s->fb = NULL;
|
||||
log_s->offset = 0;
|
||||
}
|
||||
enable_irq(flags);
|
||||
|
||||
if (fb)
|
||||
{
|
||||
ret = fb->len;
|
||||
msi_output_fb(log_s->s, fb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32 debug_log_sync_work(struct os_work *work)
|
||||
{
|
||||
struct dbg_log_s *log_s = (struct dbg_log_s *) work;
|
||||
sync_debug_buf(log_s);
|
||||
os_run_work_delay(work, 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *dbg_log_msi(const char *host_name)
|
||||
{
|
||||
struct msi *s = NULL;
|
||||
uint8_t isnew;
|
||||
struct dbg_log_s *log_s;
|
||||
s = msi_new(host_name, 0, &isnew);
|
||||
|
||||
if (isnew)
|
||||
{
|
||||
log_s = (struct dbg_log_s *) STREAM_LIBC_ZALLOC(sizeof(struct dbg_log_s));
|
||||
ASSERT(log_s);
|
||||
s->priv = (void *) log_s;
|
||||
s->action = (msi_action) debug_log_action;
|
||||
fbpool_init(&log_s->tx_pool, DEBUG_LOG_MAX_NUM);
|
||||
log_s->s = s;
|
||||
log_s->fb = NULL;
|
||||
log_s->offset = 0;
|
||||
OS_WORK_INIT(&log_s->work, debug_log_sync_work, 0);
|
||||
os_run_work_delay(&log_s->work, 1000);
|
||||
msi_add_output(s, NULL, R_DEBUG_STREAM);
|
||||
s->enable = 1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
uint8_t *get_debug_buf(struct dbg_log_s *log_s, uint32_t *write_len, uint32_t len)
|
||||
{
|
||||
uint8_t *malloc_buf;
|
||||
uint8_t *buf;
|
||||
uint32_t remain_size;
|
||||
uint32_t flags;
|
||||
uint8_t disable_irq_en = 0;
|
||||
uint32_t times = 0;
|
||||
|
||||
struct framebuff *fb = NULL;
|
||||
|
||||
again:
|
||||
flags = disable_irq();
|
||||
if (log_s->fb && (DEBUG_LOG_CACHE_SIZE == log_s->offset))
|
||||
{
|
||||
fb = log_s->fb;
|
||||
fb->len = log_s->offset;
|
||||
log_s->fb = NULL;
|
||||
log_s->offset = 0;
|
||||
}
|
||||
enable_irq(flags);
|
||||
|
||||
if (fb)
|
||||
{
|
||||
msi_output_fb(log_s->s, fb);
|
||||
}
|
||||
|
||||
if (!log_s->fb)
|
||||
{
|
||||
malloc_buf = (uint8_t *) DEBUG_LOG_STREAM_MALLOC(DEBUG_LOG_CACHE_SIZE);
|
||||
if (malloc_buf)
|
||||
{
|
||||
flags = disable_irq();
|
||||
disable_irq_en = 1;
|
||||
if (!log_s->fb)
|
||||
{
|
||||
log_s->fb = fbpool_get(&log_s->tx_pool, 0, log_s->s);
|
||||
if (log_s->fb)
|
||||
{
|
||||
log_s->fb->data = malloc_buf;
|
||||
log_s->offset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG_STREAM_FREE(malloc_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有关闭中断,就关闭中断去操?因为log_s->fb有可能需要同步,会被释放
|
||||
if (!disable_irq_en)
|
||||
{
|
||||
flags = disable_irq();
|
||||
disable_irq_en = 1;
|
||||
}
|
||||
if (log_s->fb)
|
||||
{
|
||||
buf = log_s->fb->data + log_s->offset;
|
||||
remain_size = DEBUG_LOG_CACHE_SIZE - log_s->offset;
|
||||
if (remain_size > len)
|
||||
{
|
||||
*write_len = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*write_len = remain_size;
|
||||
}
|
||||
|
||||
log_s->offset += (*write_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*write_len = 0;
|
||||
buf = NULL;
|
||||
}
|
||||
if (disable_irq_en)
|
||||
{
|
||||
enable_irq(flags);
|
||||
}
|
||||
times++;
|
||||
// 如果保存失败,重新去尝试吧
|
||||
if (!buf && (times < DBG_LOG_FAIL_TIMES))
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
goto again;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
uint8_t *get_debug_buf_interrupt(struct dbg_log_s *log_s, uint32_t *write_len, uint32_t len)
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint32_t remain_size;
|
||||
//uint32_t flags;
|
||||
if (log_s->fb)
|
||||
{
|
||||
buf = log_s->fb->data + log_s->offset;
|
||||
remain_size = DEBUG_LOG_CACHE_SIZE - log_s->offset;
|
||||
if (remain_size >= len)
|
||||
{
|
||||
*write_len = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*write_len = remain_size;
|
||||
log_s->fb->rev = 1; // 标记有数据漏了,log那里可以记录一下
|
||||
}
|
||||
if (!remain_size)
|
||||
{
|
||||
*write_len = 0;
|
||||
buf = NULL;
|
||||
}
|
||||
log_s->offset += (*write_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*write_len = 0;
|
||||
buf = NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
void hgprntf_debug_log_msi(void *priv, char *str, int32 len)
|
||||
{
|
||||
uint32_t in_disable_irq(void);
|
||||
uint8_t *buf;
|
||||
struct dbg_log_s *log_s = (struct dbg_log_s *) priv;
|
||||
if (__in_interrupt() || in_disable_irq())
|
||||
{
|
||||
uint32_t cp_len;
|
||||
if (len == 0)
|
||||
{
|
||||
len = os_strlen(str);
|
||||
}
|
||||
buf = get_debug_buf_interrupt(log_s, &cp_len, len);
|
||||
if (buf)
|
||||
{
|
||||
os_memcpy(buf, str, cp_len);
|
||||
len -= cp_len;
|
||||
str += cp_len;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
len = os_strlen(str);
|
||||
}
|
||||
do
|
||||
{
|
||||
uint32_t cp_len;
|
||||
buf = get_debug_buf(log_s, &cp_len, len);
|
||||
if (buf)
|
||||
{
|
||||
os_memcpy(buf, str, cp_len);
|
||||
len -= cp_len;
|
||||
str += cp_len;
|
||||
}
|
||||
} while (len && buf);
|
||||
}
|
||||
Reference in New Issue
Block a user