CARPLAY版本整理
This commit is contained in:
32
MXC_A27-PCB4.5-270T/lib/ulog/backend/console_be.c
Normal file
32
MXC_A27-PCB4.5-270T/lib/ulog/backend/console_be.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include "board.h"
|
||||
#include "ulog.h"
|
||||
|
||||
#ifdef ULOG_BACKEND_USING_CONSOLE
|
||||
|
||||
#if defined(ULOG_ASYNC_OUTPUT_BY_THREAD) && ULOG_ASYNC_OUTPUT_THREAD_STACK < 384
|
||||
#error "The thread stack size must more than 384 when using async output by thread (ULOG_ASYNC_OUTPUT_BY_THREAD)"
|
||||
#endif
|
||||
|
||||
static struct ulog_backend console;
|
||||
|
||||
void ulog_console_backend_output(struct ulog_backend *backend, uint32_t level, const char *tag, int is_raw,
|
||||
const char *log, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
putchar(log[i]);
|
||||
}
|
||||
|
||||
int ulog_console_backend_init(void)
|
||||
{
|
||||
console.output = ulog_console_backend_output;
|
||||
|
||||
ulog_backend_register(&console, "console", pdFALSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ULOG_BACKEND_USING_CONSOLE */
|
38
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_easyflash.h
Normal file
38
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_easyflash.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the EasyFlash Library.
|
||||
*
|
||||
* Copyright (c) 2014-2018, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The ulog flash plugin by EasyFlash.
|
||||
* Created on: 2018-10-22
|
||||
*/
|
||||
|
||||
#ifndef _ULOG_EASYFLASH_H_
|
||||
#define _ULOG_EASYFLASH_H_
|
||||
|
||||
int ulog_ef_backend_init(void);
|
||||
void ulog_ef_log_clean(void);
|
||||
void ulog_ef_log_lvl_set(uint32_t level);
|
||||
int ulog_ef_filter_cfg_load(void);
|
||||
void ulog_ef_filter_cfg_save(void);
|
||||
|
||||
#endif /* _ULOG_EASYFLASH_H_ */
|
177
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_easyflash_be.c
Normal file
177
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_easyflash_be.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* This file is part of the EasyFlash Library.
|
||||
*
|
||||
* Copyright (c) 2014-2018, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The ulog backend implementation for EasyFlash.
|
||||
* Created on: 2018-10-22
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <easyflash.h>
|
||||
#include "board.h"
|
||||
|
||||
#define LOG_TAG "easyflash"
|
||||
#include <ulog.h>
|
||||
|
||||
#define ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
|
||||
|
||||
#ifdef ULOG_EASYFLASH_BACKEND_ENABLE
|
||||
|
||||
#if defined(ULOG_ASYNC_OUTPUT_BY_THREAD) && ULOG_ASYNC_OUTPUT_THREAD_STACK < 1024
|
||||
#error "The thread stack size must more than 1024 when using async output by thread (ULOG_ASYNC_OUTPUT_BY_THREAD)"
|
||||
#endif
|
||||
|
||||
static struct ulog_backend flash_backend;
|
||||
static uint32_t log_saving_lvl = LOG_FILTER_LVL_ALL;
|
||||
|
||||
/**
|
||||
* Read and output log to console.
|
||||
*
|
||||
* @param index index for saved log.
|
||||
* Minimum index is 0.
|
||||
* Maximum index is log used flash total size - 1.
|
||||
* @param size
|
||||
*/
|
||||
void read_flash_log(uint8_t *logbuf, size_t index, size_t size)
|
||||
{
|
||||
/* 64 bytes buffer */
|
||||
uint32_t buf[512] = { 0 };
|
||||
size_t log_total_size = ef_log_get_used_size();
|
||||
size_t buf_size = sizeof(buf);
|
||||
size_t read_size = 0;
|
||||
|
||||
/* word alignment for index and size */
|
||||
index = ALIGN_DOWN(index, 4);
|
||||
size = ALIGN_DOWN(size, 4);
|
||||
if (index + size > log_total_size)
|
||||
{
|
||||
printf("The output position and size is out of bound. The max size is %d.\n", log_total_size);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (read_size + buf_size < size)
|
||||
{
|
||||
ef_log_read(index + read_size, buf, buf_size);
|
||||
memcpy(logbuf + read_size, buf, buf_size);
|
||||
read_size += buf_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
ef_log_read(index + read_size, buf, size - read_size);
|
||||
memcpy(logbuf + read_size, buf, size - read_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and output recent log which saved in flash.
|
||||
*
|
||||
* @param size recent log size
|
||||
*/
|
||||
size_t read_recent_flash_log(void *buf, size_t size)
|
||||
{
|
||||
size_t max_size = ef_log_get_used_size();
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (size > max_size)
|
||||
{
|
||||
size = max_size;
|
||||
}
|
||||
|
||||
read_flash_log(buf, max_size - size, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* clean all log which in flash
|
||||
*/
|
||||
void ulog_ef_log_clean(void)
|
||||
{
|
||||
EfErrCode clean_result = EF_NO_ERR;
|
||||
|
||||
/* clean all log which in flash */
|
||||
clean_result = ef_log_clean();
|
||||
|
||||
if (clean_result == EF_NO_ERR)
|
||||
{
|
||||
TRACE_INFO("All logs which in flash is clean OK.");
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_ERROR("Clean logs which in flash has an error!");
|
||||
}
|
||||
}
|
||||
|
||||
static void ulog_easyflash_backend_output(struct ulog_backend *backend, uint32_t level, const char *tag, int is_raw,
|
||||
const char *log, size_t len)
|
||||
{
|
||||
/* write some '\r' for word alignment */
|
||||
char write_overage_c[4] = { '\r', '\r', '\r', '\r' };
|
||||
size_t write_size_temp = 0;
|
||||
EfErrCode result = EF_NO_ERR;
|
||||
|
||||
/* saving level filter for flash log */
|
||||
if (level <= log_saving_lvl)
|
||||
{
|
||||
/* calculate the word alignment write size */
|
||||
write_size_temp = ALIGN_DOWN(len, 4);
|
||||
|
||||
result = ef_log_write((uint32_t *) log, write_size_temp);
|
||||
/* write last word alignment data */
|
||||
if ((result == EF_NO_ERR) && (write_size_temp != len))
|
||||
{
|
||||
memcpy(write_overage_c, log + write_size_temp, len - write_size_temp);
|
||||
ef_log_write((uint32_t *) write_overage_c, sizeof(write_overage_c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flash log saving level. The log which level less than setting will stop saving to flash.
|
||||
*
|
||||
* @param level setting level
|
||||
*/
|
||||
void ulog_ef_log_lvl_set(uint32_t level)
|
||||
{
|
||||
log_saving_lvl = level;
|
||||
}
|
||||
|
||||
int ulog_ef_backend_init(void)
|
||||
{
|
||||
flash_backend.output = ulog_easyflash_backend_output;
|
||||
|
||||
ulog_backend_register(&flash_backend, "easyflash", pdTRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ULOG_EASYFLASH_BACKEND_ENABLE */
|
210
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_easyflash_cfg.c
Normal file
210
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_easyflash_cfg.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* This file is part of the EasyFlash Library.
|
||||
*
|
||||
* Copyright (c) 2014-2018, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The ulog filter configuration store implement by EasyFlash.
|
||||
* Created on: 2018-11-08
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef ULOG_EASYFLASH_CFG_SAVE_ENABLE
|
||||
|
||||
#include <easyflash.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_TAG "easyflash"
|
||||
#include <ulog.h>
|
||||
|
||||
#define ENV_FILTER_GLOBAL_LVL_NAME "ulog.lvl"
|
||||
#define ENV_FILTER_GLOBAL_TAG_NAME "ulog.tag"
|
||||
#define ENV_FILTER_GLOBAL_KW_NAME "ulog.kw"
|
||||
#define ENV_FILTER_TAG_LVL_NAME "ulog.tag_lvl"
|
||||
|
||||
extern size_t ulog_ultoa(char *s, unsigned long int n);
|
||||
|
||||
/**
|
||||
* load the ulog configuration on flash
|
||||
*
|
||||
* @return result, 0 : success, else error
|
||||
*
|
||||
* @note don't using `&` and `##` on log tag definition when using this function.
|
||||
*/
|
||||
int ulog_ef_filter_cfg_load(void)
|
||||
{
|
||||
char *value;
|
||||
|
||||
/* restore the saving global level */
|
||||
if ((value = ef_get_env(ENV_FILTER_GLOBAL_LVL_NAME)) != NULL)
|
||||
{
|
||||
ulog_global_filter_lvl_set(atoi(value));
|
||||
}
|
||||
|
||||
/* restore the saving global tag */
|
||||
if ((value = ef_get_env(ENV_FILTER_GLOBAL_TAG_NAME)) != NULL)
|
||||
{
|
||||
ulog_global_filter_tag_set(value);
|
||||
}
|
||||
|
||||
/* restore the saving global kw */
|
||||
if ((value = ef_get_env(ENV_FILTER_GLOBAL_KW_NAME)) != NULL)
|
||||
{
|
||||
ulog_global_filter_kw_set(value);
|
||||
}
|
||||
|
||||
/* restore the saving tag level list */
|
||||
if ((value = ef_get_env(ENV_FILTER_TAG_LVL_NAME)) != NULL)
|
||||
{
|
||||
char lvl_num[11], tag[ULOG_FILTER_TAG_MAX_LEN + 1], *lvl_pos, *next_node;
|
||||
rt_size_t node_len;
|
||||
/* decode every tag's level */
|
||||
while (1)
|
||||
{
|
||||
/* find every node */
|
||||
if ((next_node = strstr(value, "##")) != NULL)
|
||||
{
|
||||
node_len = next_node - value;
|
||||
}
|
||||
else
|
||||
{
|
||||
node_len = rt_strlen(value);
|
||||
}
|
||||
/* find level pos */
|
||||
lvl_pos = strstr(value, "&");
|
||||
if (lvl_pos != NULL && lvl_pos < value + node_len)
|
||||
{
|
||||
rt_strncpy(tag, value, lvl_pos - value);
|
||||
rt_strncpy(lvl_num, lvl_pos + 1, value + node_len - lvl_pos - 1);
|
||||
tag[lvl_pos - value] = '\0';
|
||||
lvl_num[value + node_len - lvl_pos - 1] = '\0';
|
||||
/* add a tag's level filter */
|
||||
ulog_tag_lvl_filter_set(tag, atoi(lvl_num));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_W("Warning: tag's level decode failed!");
|
||||
break;
|
||||
}
|
||||
|
||||
if (next_node)
|
||||
{
|
||||
value = next_node + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_APP_EXPORT(ulog_ef_filter_cfg_load);
|
||||
|
||||
/**
|
||||
* save the ulog filter configuration to flash
|
||||
*
|
||||
* @note don't using `&` and `##` on log tag definition when using this function.
|
||||
*/
|
||||
void ulog_ef_filter_cfg_save(void)
|
||||
{
|
||||
unsigned char *cfgs = NULL;
|
||||
char lvl_num[11];
|
||||
|
||||
/* set the global level env */
|
||||
{
|
||||
ulog_ultoa(lvl_num, ulog_global_filter_lvl_get());
|
||||
ef_set_env(ENV_FILTER_GLOBAL_LVL_NAME, lvl_num);
|
||||
}
|
||||
|
||||
/* set the global tag env */
|
||||
if (rt_strlen(ulog_global_filter_tag_get()))
|
||||
{
|
||||
ef_set_env(ENV_FILTER_GLOBAL_TAG_NAME, ulog_global_filter_tag_get());
|
||||
}
|
||||
else if(ef_get_env(ENV_FILTER_GLOBAL_TAG_NAME))
|
||||
{
|
||||
ef_del_env(ENV_FILTER_GLOBAL_TAG_NAME);
|
||||
}
|
||||
|
||||
/* set the global kw env */
|
||||
if (rt_strlen(ulog_global_filter_kw_get()))
|
||||
{
|
||||
ef_set_env(ENV_FILTER_GLOBAL_KW_NAME, ulog_global_filter_kw_get());
|
||||
}
|
||||
else if(ef_get_env(ENV_FILTER_GLOBAL_KW_NAME))
|
||||
{
|
||||
ef_del_env(ENV_FILTER_GLOBAL_KW_NAME);
|
||||
}
|
||||
|
||||
/* set the tag's level env */
|
||||
{
|
||||
rt_slist_t *node;
|
||||
ulog_tag_lvl_filter_t tag_lvl = NULL;
|
||||
rt_size_t node_size, tag_len, lvl_len;
|
||||
int cfgs_size = 0;
|
||||
|
||||
for (node = rt_slist_first(ulog_tag_lvl_list_get()); node; node = rt_slist_next(node))
|
||||
{
|
||||
tag_lvl = rt_slist_entry(node, struct ulog_tag_lvl_filter, list);
|
||||
ulog_ultoa(lvl_num, tag_lvl->level);
|
||||
tag_len = rt_strlen(tag_lvl->tag);
|
||||
lvl_len = rt_strlen(lvl_num);
|
||||
/* env string format: tag_name1&tag_lvl1##tag_name2&tag_lvl2## */
|
||||
node_size = tag_len + 1 + lvl_len + 2;
|
||||
cfgs_size += node_size;
|
||||
cfgs = (unsigned char *) rt_realloc(cfgs, cfgs_size);
|
||||
if (cfgs == NULL)
|
||||
{
|
||||
LOG_W("Warning: no memory for save cfgs");
|
||||
goto __exit;
|
||||
}
|
||||
rt_memcpy(cfgs + cfgs_size - node_size , tag_lvl->tag, tag_len);
|
||||
rt_memcpy(cfgs + cfgs_size - node_size + tag_len , "&", 1);
|
||||
rt_memcpy(cfgs + cfgs_size - node_size + tag_len + 1 , lvl_num, lvl_len);
|
||||
rt_memcpy(cfgs + cfgs_size - node_size + tag_len + 1 + lvl_len, "##", 2);
|
||||
}
|
||||
|
||||
if((cfgs)&&(cfgs_size>2))
|
||||
{
|
||||
cfgs[cfgs_size - 2] = '\0';
|
||||
ef_set_env(ENV_FILTER_TAG_LVL_NAME, (char *)cfgs);
|
||||
}
|
||||
else if(ef_get_env(ENV_FILTER_TAG_LVL_NAME))
|
||||
{
|
||||
ef_del_env(ENV_FILTER_TAG_LVL_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
/* save the ulog filter env */
|
||||
ef_save_env();
|
||||
|
||||
if (cfgs)
|
||||
{
|
||||
rt_free(cfgs);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ULOG_EASYFLASH_CFG_SAVE_ENABLE */
|
20
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_file.h
Normal file
20
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_file.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-01-07 ChenYong first version
|
||||
*/
|
||||
|
||||
#ifndef _ULOG_FILE_H_
|
||||
#define _ULOG_FILE_H_
|
||||
|
||||
#define ULOG_FILE_SW_VERSION "1.0.0"
|
||||
#define ULOG_FILE_SW_VERSION_NUM 0x0100000
|
||||
|
||||
int ulog_file_backend_init(void);
|
||||
int ulog_file_backend_deinit(void);
|
||||
|
||||
#endif /* _ULOG_FILE_H_ */
|
154
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_file_be.c
Normal file
154
MXC_A27-PCB4.5-270T/lib/ulog/backend/ulog_file_be.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-01-07 ChenYong first version
|
||||
*/
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <ff_stdio.h>
|
||||
#include "board.h"
|
||||
#include "ulog.h"
|
||||
#include "ulog_file.h"
|
||||
|
||||
#define ULOG_FILE_BE_NAME "file"
|
||||
|
||||
#ifndef ULOG_FILE_ROOT_PATH
|
||||
#define ULOG_FILE_ROOT_PATH "/logs"
|
||||
#endif
|
||||
#ifndef ULOG_FILE_NAME_BASE
|
||||
#define ULOG_FILE_NAME_BASE "ulog.log"
|
||||
#endif
|
||||
|
||||
#ifndef ULOG_FILE_MAX_NUM
|
||||
#define ULOG_FILE_MAX_NUM 5
|
||||
#endif
|
||||
#ifndef ULOG_FILE_MAX_SIZE
|
||||
#define ULOG_FILE_MAX_SIZE (1024 * 512)
|
||||
#endif
|
||||
|
||||
#define ULOG_FILE_PATH_LEN 128
|
||||
|
||||
#ifdef ULOG_FILE_BACKEND_ENABLE
|
||||
|
||||
#if defined(ULOG_ASYNC_OUTPUT_THREAD_STACK) && (ULOG_ASYNC_OUTPUT_THREAD_STACK < 2048)
|
||||
#error "The value of ULOG_ASYNC_OUTPUT_THREAD_STACK must be greater than 2048."
|
||||
#endif
|
||||
|
||||
static struct ulog_backend ulog_file;
|
||||
static char g_file_path[ULOG_FILE_PATH_LEN] = {0};
|
||||
static FF_FILE *g_file_fd = NULL;
|
||||
|
||||
/* rotate the log file xxx.log.n-1 => xxx.log.n, and xxx.log => xxx.log.0 */
|
||||
static int ulog_file_rotate(void)
|
||||
{
|
||||
#define SUFFIX_LEN 10
|
||||
/* mv xxx.log.n-1 => xxx.log.n, and xxx.log => xxx.log.0 */
|
||||
static char old_path[ULOG_FILE_PATH_LEN], new_path[ULOG_FILE_PATH_LEN];
|
||||
int index = 0, err = 0;
|
||||
FF_FILE *file_fd = NULL;
|
||||
size_t base_len = 0;
|
||||
int result = pdTRUE;
|
||||
|
||||
memcpy(old_path, g_file_path, ULOG_FILE_PATH_LEN);
|
||||
memcpy(new_path, g_file_path, ULOG_FILE_PATH_LEN);
|
||||
base_len = strlen(ULOG_FILE_ROOT_PATH) + strlen(ULOG_FILE_NAME_BASE) + 1;
|
||||
|
||||
if (g_file_fd)
|
||||
{
|
||||
ff_fclose(g_file_fd);
|
||||
}
|
||||
|
||||
for (index = ULOG_FILE_MAX_NUM - 2; index >= 0; --index)
|
||||
{
|
||||
snprintf(old_path + base_len, SUFFIX_LEN, index ? ".%d" : "", index - 1);
|
||||
snprintf(new_path + base_len, SUFFIX_LEN, ".%d", index);
|
||||
/* remove the old file */
|
||||
if ((file_fd = ff_fopen(new_path, "rb")) != NULL)
|
||||
{
|
||||
ff_fclose(file_fd);
|
||||
ff_remove(new_path);
|
||||
}
|
||||
/* change the new log file to old file name */
|
||||
if ((file_fd = ff_fopen(old_path , "rb")) != NULL)
|
||||
{
|
||||
ff_fclose(file_fd);
|
||||
err = ff_rename(old_path, new_path, 1);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
result = pdFALSE;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
/* reopen the file */
|
||||
g_file_fd = ff_fopen(g_file_path, "a+");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ulog_file_backend_output(struct ulog_backend *backend, uint32_t level,
|
||||
const char *tag, int is_raw, const char *log, size_t len)
|
||||
{
|
||||
size_t file_size = 0;
|
||||
|
||||
/* check log file directory */
|
||||
if (ff_finddir(ULOG_FILE_ROOT_PATH) == pdFALSE)
|
||||
{
|
||||
ff_mkdir(ULOG_FILE_ROOT_PATH);
|
||||
}
|
||||
|
||||
if (g_file_fd == NULL)
|
||||
{
|
||||
snprintf(g_file_path, ULOG_FILE_PATH_LEN, "%s/%s", ULOG_FILE_ROOT_PATH, ULOG_FILE_NAME_BASE);
|
||||
g_file_fd = ff_fopen(g_file_path, "a+");
|
||||
if (g_file_fd == NULL)
|
||||
{
|
||||
printf("ulog file(%s) open failed.", g_file_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ff_fseek(g_file_fd, 0, FF_SEEK_END);
|
||||
file_size = ff_filelength(g_file_fd);
|
||||
if (file_size > ULOG_FILE_MAX_SIZE)
|
||||
{
|
||||
if (!ulog_file_rotate())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ff_fwrite(log, 1, len, g_file_fd);
|
||||
/* flush file cache */
|
||||
ff_fclose(g_file_fd);
|
||||
g_file_fd = ff_fopen(g_file_path, "a+");
|
||||
}
|
||||
|
||||
/* initialize the ulog file backend */
|
||||
int ulog_file_backend_init(void)
|
||||
{
|
||||
ulog_file.output = ulog_file_backend_output;
|
||||
ulog_backend_register(&ulog_file, ULOG_FILE_BE_NAME, pdFALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* uninitialize the ulog file backend */
|
||||
int ulog_file_backend_deinit(void)
|
||||
{
|
||||
if (g_file_fd)
|
||||
{
|
||||
ff_fclose(g_file_fd);
|
||||
g_file_fd = NULL;
|
||||
}
|
||||
ulog_backend_unregister(&ulog_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ULOG_FILE_BACKEND_ENABLE */
|
Reference in New Issue
Block a user