分享一个自用的、极简的log模块

嵌入式ARM 2022-03-01 12:00

大家好,我是ZhengN。

我们平时开发中,log打印必不可少,仅仅使用printf,则log信息不好定位。一些开源稳定、成熟的log模块功能往往比较强大,而我们可能又不需要那么多功能。

这里简单分享一个我自己用的一个极简的log模块:log颜色可设置、带时间戳、文件、行号、函数。

这个log模块仅包含log.h与log.c两个文件。

log模块代码

log.h:

#ifndef LOG_H
#define LOG_H

#ifdef __cplusplus
extern "C" {
#endif

#define LOG_BUF_SIZE 1024

typedef long long (*get_sys_time_ms_def)(void);

enum log_color
{
    COLOR_NULL  = 0,
    RED    = 1,
    GREEN  = 2,
    YELLOW = 3,
    BLUE   = 4
};

void log_print(enum log_color color, const char *file, int line, const char *func, const char* fmt, ...);
void log_time_register(get_sys_time_ms_def p_get_sys_time_ms);

#define LOG_D(...) log_print(BLUE, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

#ifdef __cplusplus
}
#endif
#endif

log.c:

#include 
#include 
#include "log.h"

static long long default_get_sys_time_ms(void)
{
     return (long long)0;
}

static get_sys_time_ms_def s_get_sys_time_ms = default_get_sys_time_ms;

void log_time_register(get_sys_time_ms_def p_get_sys_time_ms)
{
    s_get_sys_time_ms = p_get_sys_time_ms;
}

void log_print(enum log_color color, const char *file, int line, const char *func, const char* fmt, ...)
{
    va_list ap;
    char buf[LOG_BUF_SIZE] = {0};
    long long time = s_get_sys_time_ms();

    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

 switch(color)
    {
  case COLOR_NULL:
   printf("<%lld ms>[%s:%d %s] %s ", time, file, line, func, buf);
   break;
  case RED:
   printf("\033[31m<%lld ms>[%s:%d %s] %s\033[0m", time, file, line, func, buf);
   break;
  case GREEN:
   printf("\033[32m<%lld ms>[%s:%d %s] %s\033[0m", time, file, line, func, buf);
   break;
  case YELLOW:
   printf("\033[33m<%lld ms>[%s:%d %s] %s\033[0m", time, file, line, func, buf);
   break;
  case BLUE:
   printf("\033[34m<%lld ms>[%s:%d %s] %s\033[0m", time, file, line, func, buf);
   break;
        default:
            break;
    }
}

其中,默认打印ms级的系统时间。因为不同的平台(Linux、Windows、STM32等),获取系统时间的方式都不一样。

使用时,再根据不同的平台自己定义一个获取系统时间的函数,以注册的方式进行绑定。不注册获取时间函数也不影响使用,时间戳打印为0。

log模块测试

1、Linux平台

log_test.c:

#include 
#include 
#include "log.h"

static long long linux_get_sys_time_ms(void)
{
    long long time_ms = 0;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    time_ms = (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;

    return (long long)time_ms;
}

int main(void)
{
    log_time_register(linux_get_sys_time_ms);

    char ch = 'a';
    char str[10] = "ZhengN";
    float float_val = 10.10;
    int num = 88;
    double double_val = 10.123456;
    LOG_D("字符为 %c \n", ch);
    LOG_D("字符串为 %s \n" , str);
    LOG_D("浮点数为 %f \n", float_val);
    LOG_D("整数为 %d\n" , num);
    LOG_D("双精度值为 %lf \n", double_val);
    LOG_D("八进制值为 %o \n", num);
    LOG_D("十六进制值为 %x \n", num);

    return 0;
}

编译,运行:

第18行屏蔽掉:

2、Windows平台

log_test.c:

#include 
#include 
#include "log.h"

static long long win_get_sys_time_ms(void)
{
    long long time_ms = 0;

    time_ms = GetTickCount();

    return time_ms;
}

void test(void)
{
    LOG_D("Hello world\n");
}

int main(void)
{
    log_time_register(win_get_sys_time_ms);

    char ch = 'a';
    char str[10] = "ZhengN";
    float float_val = 10.10;
    int num = 88;
    double double_val = 10.123456;
    LOG_D("字符为 %c \n", ch);
    LOG_D("字符串为 %s \n" , str);
    LOG_D("浮点数为 %f \n", float_val);
    LOG_D("整数为 %d\n" , num);
    LOG_D("双精度值为 %lf \n", double_val);
    LOG_D("八进制值为 %o \n", num);
    LOG_D("十六进制值为 %x \n", num);
    test();

    return 0;
}

编译,运行:

以上就是本次的分享,如果觉得文章不错的话,欢迎收藏、转发!


END

作者:ZhengN
来源:嵌入式大杂烩

版权归原作者所有,如有侵权,请联系删除。

推荐阅读
深度:嵌入式系统的软件架构设计!
最新955不加班的公司名单(2022版)
3年的MCU工程师就写出这样的代码?

→点关注,不迷路←
嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论
  • 当下,智能手机市场正呈现出明显的高端化趋势,更多消费者愿意为高端设备买单,这也推动了智能手机均价的提升。作为中国科技品牌出海的代表,传音控股凭借在折叠屏手机、AI技术、多肤色影像技术等方面的优势,在全球高端手机市场上展现出强大的竞争力。智能手机高端化趋势明显,传音打造AI技术优势12月初,全球市场调研机构Counterpoint发布报告称,2024年三季度,全球智能手机市场出货量达3.07亿部,同比增长2%,连续四个季度保持增长。全球智能手机收入同比增长10%,平均售价增长7%,均创下历史新高。
    电子资讯报 2024-12-24 16:57 30浏览
  • “金字招牌”的户外叙事。2024年的夏天似乎异常炙热,体育迷们的心跳也随之澎湃,全球瞩目的体育盛宴——巴黎奥运会在此刻上映。在这个充满荣耀与梦想的夏天,我们见证了无数激动人心的瞬间:男子4X100米混合泳接力决赛中,潘展乐的最后一棒,气壮山河,中国队的历史性夺冠,让整个泳池沸腾;射击10米气步枪混合团体决赛,黄雨婷和盛李豪的精准射击,为中国队射落首金,展现了年轻一代的力量;乒乓球男单四分之一比赛中,樊振东的惊天逆转令人难以忘怀,凭借坚韧不拔的意志和卓越的技术,成功挺进半决赛,并最终夺冠……在这一
    艾迈斯欧司朗 2024-12-25 19:30 59浏览
  • 概述 Intel 要求用户为其10代FPGA器件使用特定的上电和掉电顺序,这就要求用户在进行FPGA硬件设计的时候必须选择恰当的FPGA供电方案,并合理控制完整的供电上电顺序。经过在Cyclone 10 GX测试板上实际验证,统一上电确实会导致FPGA无法正常工作,具体表现为JTAG接口无法探测或识别到目标器件。上电顺序要求 Cyclone 10 GX,Arria 10以及Stratix 10系列器件所有的电源轨被划分成了三个组合,三组电源轨要求依次上电,如图1所示,为三组电源轨上电顺序示意图。
    coyoo 2024-12-25 14:13 42浏览
  • 今年AI技术的话题不断,随着相关应用服务的陆续推出,AI的趋势已经是一个明确的趋势及方向,这也连带使得AI服务器的出货量开始加速成长。AI服务器因为有着极高的运算效能,伴随而来的即是大量的热能产生,因此散热效能便成为一个格外重要的议题。其实不只AI服务器有着散热的问题,随着Intel及AMD 的CPU规格也不断地在提升,非AI应用的服务器的散热问题也是不容小觑的潜在问题。即便如此,由于目前的液冷技术仍有许多待克服的地方,例如像是建置成本昂贵,机壳、轨道、水路、数据中心等项目都得重新设计来过,维修
    百佳泰测试实验室 2024-12-26 16:33 44浏览
  • RK3506是瑞芯微Rockchip在2024年第四季度全新推出的Arm嵌入式芯片平台,三核Cortex-A7+单核Cortex-M0多核异构设计,CPU频率达1.5Ghz, M0 MCU为200Mhz。RK3506平台各型号芯片该怎么选,看这篇文章就够了。RK3506各型号RK3506有3个型号,分别是RK3506G2、RK3506B、RK3506J,配置参数如图: 配置差异解析总的来说,RK3506各型号间的差异主要体现在内存、工作温度和封装上‌:内存差异‌:RK3506G2‌集成
    Industio_触觉智能 2024-12-25 10:27 23浏览
  • 在PCB设计中,Stub(也称为短桩线或残桩线)对信号传输有以下几个主要影响:1.容性效应导致的阻抗偏低:Stub会导致容性效应,使得阻抗偏低,影响信道的阻抗一致性。Stub越长,阻抗降低得越多。这是因为传输线瞬态阻抗计算公式为:Z = \ sqrt { \ frac { L } { C } }Stub就像并联在传输线上的小电容,Stub越长,电容量越大,阻抗也就越低。2.信号反射:当信号在传输线与Stub的交界处遇到阻抗不匹配时,会产生信号反射。这会导致信号的失真和能量的反向传播,增加了噪声和
    为昕科技 2024-12-24 18:10 25浏览
  • 全球照明技术创新领航者艾迈斯欧司朗,于2024年广州国际照明展览会同期,举办【智慧之光】· 艾迈斯欧司朗-照明应用研讨会,以持续的技术创新,推动光+概念的全面落地。现场还演示了多款领先照明技术,且由资深工程师倾情解读,另有行业大咖深度洞察分享,助你开启“光的无限可能”探索之旅!精彩大咖分享引领未来照明无限遐想艾迈斯欧司朗精心准备了照明领域专业大咖的深度分享,无论是照明领域的资深从业者,还是对照明科技充满好奇的探索者,在这里,您都将大有所获。在艾迈斯欧司朗照明全球产品市场VP Geral
    艾迈斯欧司朗 2024-12-25 20:05 48浏览
  • 在谐振器(无源晶振)S&A250B测试软件中,DLD1到DLD7主要用于分析晶体在不同驱动功率下的阻抗变化。此外,还有其他DLD参数用于反映晶振的磁滞现象,以及其频率和功率特性。这些参数可以帮助工程师全面了解KOAN晶振在不同功率条件下的动态特性,从而优化其应用和性能。磁滞现象晶振的磁滞现象(Hysteresis)是指在驱动功率变化时,晶体的阻抗或频率无法立即恢复至初始状态,而表现出滞后效应。1. DLDH: Hysteresis Ratio (MaxR/MinR)在不同驱动
    koan-xtal 2024-12-26 12:41 54浏览
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-26 09:19 82浏览
  • 据IDTechEx最新预计,到2034年,全球汽车舱内传感(In-Cabin Sensing,ICS)市场将超过85亿美元。若按照增长幅度来看,包含驾驶员监控系统(DMS)、乘员监控系统(OMS)、手势控制和生命体征监测等高级功能在内的舱内传感市场预计2020年到2034年将增长11倍。感光百科:ICS中的光源选择01、政策推动带来的“硬”增长作为其中的增长主力,舱内监控系统应用(包含DMS和OMS等)被推动增长的首要因素正是法规。据统计,中国、欧盟、美国、韩国、印度等主要汽车国家或地区已推出相
    艾迈斯欧司朗 2024-12-25 19:56 56浏览
  • 本文介绍瑞芯微开发板/主板Android系统APK签名文件使用方法,触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,各类接口一应俱全,帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。系统签名文件生成APK系统签名文件,具体可参考此文章方法RK3588主板/开发板Android12系统APK签名文件生成方法,干货满满使用方法第一步,修改APK工程文件app/src/build.gradle,并添加以下内容: android {     na
    Industio_触觉智能 2024-12-26 09:20 61浏览
  • 引言  LIN(Local Interconnect Network)是一种针对汽车电子系统应用的串行通信协议,主要用于汽车电子控制单元(ECU)之间的通信。LIN总线的特点是成本低、速率低、通信距离短、连接节点少,主要用于对带块要求低、实时性要求不高的控制任务,例如车门控制、天窗控制、座椅控制、车内照明等功能。LIN总线采用的是主从式架构,由主节点基于调度表调度网络中的通信。  LIN总线的错误类型  尽管LIN协议设计简单,具有低带
    北汇信息 2024-12-25 14:18 49浏览
  • 新能源汽车市场潮起潮落,只有潮水退去,才能看清谁在裸泳。十年前,一批新能源汽车新势力带着创新的理念和先进的技术,如雨后春笋般涌入中国汽车市场,掀起一场新旧势力的角逐。经历市场的激烈洗礼与投资泡沫的挤压,蔚来、理想、小鹏等新势力车企脱颖而出,刷爆网络。不曾想,今年新势力车企杀出一匹“超级黑马”,爬上新势力车企销量榜前三,将蔚来、小鹏等昔日强者甩在了身后,它就是零跑汽车。公开数据显示,11月份,零跑汽车实现新车交付量约4.02万辆,同比增长117%,单月销量首次突破4万辆;小鹏汽车当月共交付新车约3
    刘旷 2024-12-26 10:53 94浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦