1
0
mirror of https://github.com/NevermindZZT/letter-shell.git synced 2025-01-21 10:02:54 +08:00

315 lines
7.7 KiB
C
Raw Normal View History

2020-08-02 13:07:27 +08:00
/**
* @file log.c
* @author Letter (nevermindzzt@gmail.com)
* @brief log
* @version 1.0.0
* @date 2020-07-30
*
* @copyright (c) 2020 Letter
*
*/
#include "log.h"
#include "stdio.h"
#include "stdarg.h"
#include "shell.h"
#if LOG_USING_COLOR == 1
#define memPrintHead CSI(31) \
" Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" \
2021-05-09 21:24:22 +08:00
CSI(39) \
"\r\n"
2020-08-02 13:07:27 +08:00
#define memPrintAddr CSI(31)"0x%08x: "CSI(39)
#else
2021-05-09 21:24:22 +08:00
#define memPrintHead " Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"
2020-08-02 13:07:27 +08:00
#define memPrintAddr "0x%08x: "
#endif
Log *logList[LOG_MAX_NUMBER] = {0};
static char logBuffer[LOG_BUFFER_SIZE];
2020-08-02 13:07:27 +08:00
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
/**
* @brief log对象
* @param log log对象
*/
static void logLock(Log *log)
{
if (log == LOG_ALL_OBJ)
{
for (short i = 0; i < LOG_MAX_NUMBER; i++)
{
if (logList[i] && logList[i]->active)
{
2021-12-27 10:06:51 +08:00
if (logList[i]->lock)
2021-12-24 12:17:45 +08:00
{
2021-12-27 10:06:51 +08:00
LOG_LOCK(logList[i]);
2021-12-24 12:17:45 +08:00
}
}
}
}
2021-12-27 10:06:51 +08:00
else if (log->lock)
2021-12-24 12:17:45 +08:00
{
2021-12-27 10:06:51 +08:00
LOG_LOCK(log);
2021-12-24 12:17:45 +08:00
}
}
/**
* @brief log对象
* @param log log对象
*/
static void logUnlock(Log *log)
{
if (log == LOG_ALL_OBJ)
{
for (short i = 0; i < LOG_MAX_NUMBER; i++)
{
if (logList[i] && logList[i]->active)
{
2021-12-27 10:06:51 +08:00
if (logList[i]->unlock)
2021-12-24 12:17:45 +08:00
{
2021-12-27 10:06:51 +08:00
LOG_UNLOCK(logList[i]);
2021-12-24 12:17:45 +08:00
}
}
}
}
2021-12-27 10:06:51 +08:00
else if (log->unlock)
2021-12-24 12:17:45 +08:00
{
2021-12-27 10:06:51 +08:00
LOG_UNLOCK(log);
2021-12-24 12:17:45 +08:00
}
}
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
2021-12-24 12:17:45 +08:00
2020-08-02 13:07:27 +08:00
/**
* @brief log对象
*
* @param log log对象
*/
void logRegister(Log *log, Shell *shell)
{
if (shell)
{
log->shell = shell;
2020-10-30 15:09:57 +08:00
#if SHELL_USING_COMPANION == 1
2020-08-02 13:07:27 +08:00
shellCompanionAdd(shell, SHELL_COMPANION_ID_LOG, log);
2020-10-30 15:09:57 +08:00
#endif
2020-08-02 13:07:27 +08:00
}
for (short i = 0; i < LOG_MAX_NUMBER; i++)
{
if (logList[i] == 0)
{
logList[i] = log;
return;
}
}
}
/**
* @brief log对象
*
* @param log log对象
*/
void logUnRegister(Log *log)
{
for (short i = 0; i < LOG_MAX_NUMBER; i++)
{
if (logList[i] == log)
{
logList[i] = 0;
return;
}
}
}
/**
* @brief log日志级别
*
* @param log log对象
* @param level
*/
void logSetLevel(Log *log, LogLevel level)
{
logAssert(log, return);
log->level = level;
}
#if SHELL_USING_COMPANION == 1
SHELL_EXPORT_CMD_AGENCY(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
logSetLevel, logSetLevel, set log level\r\n logSetLevel [level],
(void *)shellCompanionGet(shellGetCurrent(), SHELL_COMPANION_ID_LOG), p1);
#else
2020-08-02 13:07:27 +08:00
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
logSetLevel, logSetLevel, set log level\r\n logSetLevel [log] [level]);
#endif /** SHELL_USING_COMPANION == 1 */
2020-08-02 13:07:27 +08:00
/**
* @brief log写buffer
2020-08-02 13:07:27 +08:00
*
* @param log log对象
* @param level
* @param buffer buffer
* @param len buffer长度
2020-08-02 13:07:27 +08:00
*/
2021-05-09 21:24:22 +08:00
static void logWriteBuffer(Log *log, LogLevel level, char *buffer, short len)
2020-08-02 13:07:27 +08:00
{
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
logLock(log);
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
2020-08-02 13:07:27 +08:00
if (log == LOG_ALL_OBJ)
{
for (short i = 0; i < LOG_MAX_NUMBER; i++)
{
if (logList[i]
&& logList[i]->active
&& logList[i]->level >= level)
{
logList[i]->write(logBuffer, len);
2020-08-02 13:07:27 +08:00
}
}
}
else if (log && log->active && log->level >= level)
{
log->write(logBuffer, len);
2020-08-02 13:07:27 +08:00
}
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
logUnlock(log);
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
2020-08-02 13:07:27 +08:00
}
/**
* @brief log格式化写入数据
*
* @param log log对象
* @param level log级别
* @param fmt
* @param ...
*/
void logWrite(Log *log, LogLevel level, const char *fmt, ...)
{
va_list vargs;
int len;
2021-12-24 12:17:45 +08:00
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
logLock(log);
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
va_start(vargs, fmt);
len = vsnprintf(logBuffer, LOG_BUFFER_SIZE - 1, fmt, vargs);
va_end(vargs);
if (len > LOG_BUFFER_SIZE)
{
len = LOG_BUFFER_SIZE;
}
logWriteBuffer(log, level, logBuffer, len);
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
logUnlock(log);
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
}
2020-08-02 13:07:27 +08:00
/**
* @brief 16
*
* @param log log对象
2021-05-09 21:24:22 +08:00
* @param level
2020-08-02 13:07:27 +08:00
* @param base
* @param length
*/
2021-05-09 21:24:22 +08:00
void logHexDump(Log *log, LogLevel level, void *base, unsigned int length)
2020-08-02 13:07:27 +08:00
{
unsigned char *address;
2021-05-09 21:24:22 +08:00
unsigned int len;
unsigned int printLen = 0;
2020-08-02 13:07:27 +08:00
if (length == 0 || (log != LOG_ALL_OBJ && log->level < level))
2020-08-02 13:07:27 +08:00
{
return;
}
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
logLock(log);
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
len = snprintf(logBuffer, LOG_BUFFER_SIZE - 1, "memory of 0x%08x, size: %d:\r\n%s",
(unsigned int)base, length, memPrintHead);
logWriteBuffer(log, level, logBuffer, len);
2022-06-12 19:45:07 +08:00
len = length;
2020-08-02 13:07:27 +08:00
address = (unsigned char *)((unsigned int)base & (~0x0000000F));
length += (unsigned int)base - (unsigned int)address;
length = (length + 15) & (~0x0000000F);
while (length)
{
printLen += sprintf(logBuffer + printLen, memPrintAddr, (unsigned int)address);
2020-08-02 13:07:27 +08:00
for (int i = 0; i < 16; i++)
{
if ((unsigned int)(address + i) < (unsigned int)base
|| (unsigned int)(address + i) >= (unsigned int)base + len)
{
logBuffer[printLen ++] = ' ';
logBuffer[printLen ++] = ' ';
logBuffer[printLen ++] = ' ';
2020-08-02 13:07:27 +08:00
}
else
{
printLen += sprintf(logBuffer + printLen, "%02x ", *(address + i));
2020-08-02 13:07:27 +08:00
}
}
logBuffer[printLen ++] = '|';
logBuffer[printLen ++] = ' ';
2020-08-02 13:07:27 +08:00
for (int i = 0; i < 16; i++)
{
if ((unsigned int)(address + i) < (unsigned int)base
|| (unsigned int)(address + i) >= (unsigned int)base + len)
{
logBuffer[printLen ++] = ' ';
2020-08-02 13:07:27 +08:00
}
else
{
if (*(address + i) >= 32 && *(address + i) <= 126)
{
printLen += sprintf(logBuffer + printLen, "%c", *(address + i));
2020-08-02 13:07:27 +08:00
}
else
{
logBuffer[printLen ++] = '.';
2020-08-02 13:07:27 +08:00
}
}
}
logBuffer[printLen ++] = ' ';
logBuffer[printLen ++] = '|';
logBuffer[printLen ++] = '\r';
logBuffer[printLen ++] = '\n';
logWriteBuffer(log, level, logBuffer, printLen);
2020-08-02 13:07:27 +08:00
address += 16;
length -= 16;
2020-08-05 12:38:59 +08:00
printLen = 0;
2020-08-02 13:07:27 +08:00
}
2021-12-27 10:06:51 +08:00
#if LOG_USING_LOCK == 1
2021-12-24 12:17:45 +08:00
logUnlock(log);
2021-12-27 10:06:51 +08:00
#endif /* LOG_USING_LOCK == 1 */
2020-08-02 13:07:27 +08:00
}
#if SHELL_USING_COMPANION == 1
SHELL_EXPORT_CMD_AGENCY(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
hexdump, logHexDump, hex dump\r\n hexdump [base] [len],
(void *)shellCompanionGet(shellGetCurrent(), SHELL_COMPANION_ID_LOG), LOG_NONE, (void *)p1, (unsigned int)p2);
#else
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
2021-05-09 21:24:22 +08:00
hexdump, logHexDump, hex dump\r\n hexdump [log] [level] [base] [len]);
#endif /** SHELL_USING_COMPANION == 1 */
2020-08-02 13:07:27 +08:00
#if SHELL_USING_COMPANION == 1
void logSwitchLevel(Shell *shell)
{
Log *log = shellCompanionGet(shell, SHELL_COMPANION_ID_LOG);
SHELL_ASSERT(log, return);
log->level = (LogLevel)(log->level >= LOG_ALL ? LOG_NONE : (log->level + 1));
logPrintln("set log level: %d", log->level);
}
SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x04000000, logSwitchLevel, switch log level);
#endif /** SHELL_USING_COMPANION == 1 */