GD32单片机裸机ezlogger日志系统移植详解

 github代码源地址:GitHub – armink/EasyLogger: An ultra-lightweight(ROM<1.6K, RAM<0.3k), high-performance C/C++ log library. | 一款超轻量级(ROM<1.6K, RAM<0.3k)、高性能的 C/C++ 日志库

一、移植文件

在User目录下新建easylogger文件夹,将demon目录下elog_cfg.h和elog_port.c,以及demon文件夹外部的easylogger内的elog_utils.c、elog.c、elog.h拷贝到自己新建的easylogger文件夹

makefile添加easylogger目录

在elog_port.c中,引用的是ST的固件库配置文件,需要改为GD的固件库文件,根据自己的芯片型号更改

#include <gd32f30x_libopt.h>

二、使用RTC获取当前时间

在例程的ezlogger系统中,获取当前时间的函数是elog_port_get_time(),此函数在裸机demon中没有实际定义,需要我们自己编写

这里我们使用RTC进行计时。在gd官方例程库中有RTC配置方法。其中需要根据硬件情况选择时钟源,GD例程为RCU_LXTAL外部低速时钟源。本代码外接8M晶振,所以使用RCU_HXTAL外部高速时钟源。

rtc_prescaler_set()函数是设置预分频值,根据实际需要设置。本程序是基于外部8M晶振128分频秒中断设置

//RTC初始化
void rtc_configuration(void)
{    
    //设置中断优先级
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(RTC_IRQn,1,0);

    /* enable PMU and BKPI clocks */
    rcu_periph_clock_enable(RCU_BKPI);
    rcu_periph_clock_enable(RCU_PMU);
    /* allow access to BKP domain */
    pmu_backup_write_enable();

    /* reset backup domain */
    bkp_deinit();

    /* enable LXTAL */
    rcu_osci_on(RCU_HXTAL);
    /* wait till LXTAL is ready */
    rcu_osci_stab_wait(RCU_HXTAL);
    
    /* select RCU_LXTAL as RTC clock source */
    rcu_rtc_clock_config(RCU_RTCSRC_HXTAL_DIV_128);

    /* enable RTC Clock */
    rcu_periph_clock_enable(RCU_RTC);

    /* wait for RTC registers synchronization */
    rtc_register_sync_wait();

    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();

    /* enable the RTC second interrupt*/
    rtc_interrupt_enable(RTC_INT_SECOND);

    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
    /* set RTC prescaler: set RTC period to 1s */
    rtc_prescaler_set(62500 - 1);

    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
}

注意编写RTC中断服务函数,没有清除中断标志位程序会跑飞

//RTC中断服务函数
void RTC_IRQHandler(void)
{
    if (rtc_flag_get(RTC_FLAG_SECOND) != RESET)
	{
        /* clear the RTC second interrupt flag*/
        rtc_flag_clear(RTC_FLAG_SECOND);

        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
    }
}

完成后可以使用串口打印进行验证

RTC主要用到两个库函数:

rtc_counter_set()设置当前时间戳

rtc_counter_get()获取当前时间戳

注意在设置RTC时间时,在操作前后需要使用函数rtc_lwoff_wait等待写操作完成

在elog_port.c文件中修改函数elog_port_get_time

const char *elog_port_get_time(void) 
{
    time_t timestamp = rtc_counter_get() + 28800;
    struct tm *time_info;
    char datetime[20];  // 存储结果,格式:YYYY-MM-DD HH:MM:SS

    // 将时间戳转换为时间结构体
    time_info = localtime(&timestamp);
    
    // 格式化时间到 char 数组
    snprintf(datetime, 20, "%04d-%02d-%02d %02d:%02d:%02d",
           time_info->tm_year + 1900,  // tm_year 从 1900 开始
           time_info->tm_mon + 1,      // tm_mon 从 0 开始(0-11)
           time_info->tm_day,
           time_info->tm_hour,
           time_info->tm_min,
           time_info->tm_sec);

    return datetime;
}

因为格里尼治时间与北京时间相差28800秒,所以在程序中做补偿

使用localtime函数进行格式转换,将时间戳转换为char型

定义时间结构体

//时间结构体
struct tm{
    int tm_sec;     /* seconds after the minute - [0,59] */
    int tm_min;     /* minutes after the hour - [0,59] */
    int tm_hour;    /* hours since midnight - [0,23] */
    int tm_mday;    /* day of the month - [1,31] */
    int tm_mon;     /* months since January - [0,11] */
    int tm_year;    /* years since 1900 */
    int tm_wday;    /* days since Sunday - [0,6] */
    int tm_yday;    /* days since January 1 - [0,365] */
    int tm_isdst;   /* daylight savings time flag */
};

三、完善FLASH功能

这里使用为5Q128外部FLASH

使用GD例程和正点例程。正点例程会检测写入地址是否有数据,有数据会先擦除

driver_flash.c

#include "driver_gd25qxx.h"
#include "gd32f30x.h"
#include <string.h>

#define WRITE            0x02     /* write to memory instruction */
#define WRSR             0x01     /* write status register instruction */
#define WREN             0x06     /* write enable instruction */

#define READ             0x03     /* read from memory instruction */
#define RDSR             0x05     /* read status register instruction  */
#define RDID             0x9F     /* read identification */
#define SE               0x20     /* sector erase instruction */
#define BE               0xC7     /* bulk erase instruction */

#define WIP_FLAG         0x01     /* write in progress(wip)flag */
#define DUMMY_BYTE       0xFF

/*!
    \brief      initialize SPI0 GPIO and parameter
    \param[in]  none
    \param[out] none
    \retval     none
*/
void driver_spi_flash_init(void)
{
    spi_parameter_struct spi_init_struct;

    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_SPI1);

    /* SPI1_SCK(PB13), SPI1_MISO(PB14) and SPI1_MOSI(PB15) GPIO pin configuration */
    gpio_init(SPI1_MOSI_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPI1_MOSI_PIN | SPI1_SCK_PIN);
    gpio_init(SPI1_MISO_PORT,GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SPI1_MISO_PIN);
    /* CS */
    gpio_init(SPI1_CS_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SPI1_CS_PIN);
  
    //spi_disable(SPI1);
    spi_i2s_deinit(SPI1);

    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_16;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    
    spi_init(SPI1, &spi_init_struct);

    /* enable SPI1 */
    spi_enable(SPI1);
}

/*!
    \brief      erase the specified flash sector
    \param[in]  sector_addr: address of the sector to erase
    \param[out] none
    \retval     none
*/
void driver_spi_flash_sector_erase(uint32_t sector_addr)
{
    /* send write enable instruction */
    driver_spi_flash_write_enable();

    /* sector erase */
    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();
    /* send sector erase instruction */
    driver_spi_flash_send_byte(SE);
    /* send sector_addr high nibble address byte */
    driver_spi_flash_send_byte((sector_addr & 0xFF0000) >> 16);
    /* send sector_addr medium nibble address byte */
    driver_spi_flash_send_byte((sector_addr & 0xFF00) >> 8);
    /* send sector_addr low nibble address byte */
    driver_spi_flash_send_byte(sector_addr & 0xFF);
    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();

    /* wait the end of flash writing */
    driver_spi_flash_wait_for_write_end();
}

/*!
    \brief      erase the entire flash
    \param[in]  none
    \param[out] none
    \retval     none
*/
void driver_spi_flash_bulk_erase(void)
{
    /* send write enable instruction */
    driver_spi_flash_write_enable();

    /* bulk erase */
    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();
    /* send bulk erase instruction  */
    driver_spi_flash_send_byte(BE);
    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();

    /* wait the end of flash writing */
    driver_spi_flash_wait_for_write_end();
}

/*!
    \brief      write more than one byte to the flash
    \param[in]  pbuffer: pointer to the buffer
    \param[in]  write_addr: flash's internal address to write
    \param[in]  num_byte_to_write: number of bytes to write to the flash
    \param[out] none
    \retval     none
*/
void driver_spi_flash_page_write(uint8_t* pbuffer, uint32_t write_addr, uint16_t num_byte_to_write)
{
    /* enable the write access to the flash */
    driver_spi_flash_write_enable();

    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();

    /* send "write to memory" instruction */
    driver_spi_flash_send_byte(WRITE);
    /* send write_addr high nibble address byte to write to */
    driver_spi_flash_send_byte((write_addr & 0xFF0000) >> 16);
    /* send write_addr medium nibble address byte to write to */
    driver_spi_flash_send_byte((write_addr & 0xFF00) >> 8);
    /* send write_addr low nibble address byte to write to */
    driver_spi_flash_send_byte(write_addr & 0xFF);

    /* while there is data to be written on the flash */
    while(num_byte_to_write--)
    {
        /* send the current byte */
        driver_spi_flash_send_byte(*pbuffer);
        /* point on the next byte to be written */
        pbuffer++;
    }

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();

    /* wait the end of flash writing */
    driver_spi_flash_wait_for_write_end();
}

static void norflash_write_nocheck(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
    uint16_t pageremain;
    pageremain = 256 - addr % 256;  /* 单页剩余的字节数 */

    if (datalen <= pageremain)      /* 不大于256个字节 */
    {
        pageremain = datalen;
    }

    while (1)
    {
        /* 当写入字节比页内剩余地址还少的时候, 一次性写完
         * 当写入直接比页内剩余地址还多的时候, 先写完整个页内剩余地址, 然后根据剩余长度进行不同处理
         */
        driver_spi_flash_page_write(pbuf, addr, pageremain);

        if (datalen == pageremain)      /* 写入结束了 */
        {
            break;
        }
        else                            /* datalen > pageremain */
        {
            pbuf += pageremain;         /* pbuf指针地址偏移,前面已经写了pageremain字节 */
            addr += pageremain;         /* 写地址偏移,前面已经写了pageremain字节 */
            datalen -= pageremain;      /* 写入总长度减去已经写入了的字节数 */

            if (datalen > 256)          /* 剩余数据还大于一页,可以一次写一页 */
            {
                pageremain = 256;       /* 一次可以写入256个字节 */
            }
            else                        /* 剩余数据小于一页,可以一次写完 */
            {
                pageremain = datalen;   /* 不够256个字节了 */
            }
        }
    }
}

uint8_t g_norflash_buf[4096];   /* 扇区缓存 */

void norflash_write(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
    uint32_t secpos;
    uint16_t secoff;
    uint16_t secremain;
    uint16_t i;
    uint8_t *norflash_buf;

    norflash_buf = g_norflash_buf;
    secpos = addr / 4096;       /* 扇区地址 */
    secoff = addr % 4096;       /* 在扇区内的偏移 */
    secremain = 4096 - secoff;  /* 扇区剩余空间大小 */

    //printf("ad:%X,nb:%X\r\n", addr, datalen); /* 测试用 */
    if (datalen <= secremain)
    {
        secremain = datalen;    /* 不大于4096个字节 */
    }

    while (1)
    {
        norflash_read(norflash_buf, secpos * 4096, 4096);   /* 读出整个扇区的内容 */

        for (i = 0; i < secremain; i++)     /* 校验数据 */
        {
            if (norflash_buf[secoff + i] != 0XFF)
            {
                break;                      /* 需要擦除, 直接退出for循环 */
            }
        }

        if (i < secremain)                  /* 需要擦除 */
        {
            driver_spi_flash_sector_erase(secpos);  /* 擦除这个扇区 */

            for (i = 0; i < secremain; i++) /* 复制 */
            {
                norflash_buf[i + secoff] = pbuf[i];
            }

            norflash_write_nocheck(norflash_buf, secpos * 4096, 4096);  /* 写入整个扇区 */
        }
        else    /* 写已经擦除了的,直接写入扇区剩余区间. */
        {
            norflash_write_nocheck(pbuf, addr, secremain);              /* 直接写扇区 */
        }

        if (datalen == secremain)
        {
            break;  /* 写入结束了 */
        }
        else        /* 写入未结束 */
        {
            secpos++;               /* 扇区地址增1 */
            secoff = 0;             /* 偏移位置为0 */

            pbuf += secremain;      /* 指针偏移 */
            addr += secremain;      /* 写地址偏移 */
            datalen -= secremain;   /* 字节数递减 */

            if (datalen > 4096)
            {
                secremain = 4096;   /* 下一个扇区还是写不完 */
            }
            else
            {
                secremain = datalen;/* 下一个扇区可以写完了 */
            }
        }
    }
}

/*!
    \brief      read a block of data from the flash
    \param[in]  pbuffer: pointer to the buffer that receives the data read from the flash
    \param[in]  read_addr: flash's internal address to read from
    \param[in]  num_byte_to_read: number of bytes to read from the flash
    \param[out] none
    \retval     none
*/
void norflash_read(uint8_t* pbuffer, uint32_t read_addr, uint16_t num_byte_to_read)
{
    /* select the flash: chip slect low */
    SPI_FLASH_CS_LOW();

    /* send "read from memory " instruction */
    driver_spi_flash_send_byte(READ);

    /* send read_addr high nibble address byte to read from */
    driver_spi_flash_send_byte((read_addr & 0xFF0000) >> 16);
    /* send read_addr medium nibble address byte to read from */
    driver_spi_flash_send_byte((read_addr& 0xFF00) >> 8);
    /* send read_addr low nibble address byte to read from */
    driver_spi_flash_send_byte(read_addr & 0xFF);

    /* while there is data to be read */
    while(num_byte_to_read--){
        /* read a byte from the flash */
        *pbuffer = driver_spi_flash_send_byte(DUMMY_BYTE);
        /* point to the next location where the byte read will be saved */
        pbuffer++;
    }

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();
}

/*!
    \brief      read flash identification
    \param[in]  none
    \param[out] none
    \retval     flash identification
*/
uint32_t driver_spi_flash_read_id(void)
{
    uint32_t temp = 0, temp0 = 0, temp1 = 0, temp2 = 0;

    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();

    /* send "RDID " instruction */
    driver_spi_flash_send_byte(0x90);
    driver_spi_flash_send_byte(0x0);
    driver_spi_flash_send_byte(0x0);
    driver_spi_flash_send_byte(0x0);
    temp0 = driver_spi_flash_send_byte(0xFF);
    temp1 = driver_spi_flash_send_byte(0xFF);
    // /* read a byte from the flash */
    // temp0 = driver_spi_flash_send_byte(DUMMY_BYTE);

    // /* read a byte from the flash */
    // temp1 = driver_spi_flash_send_byte(DUMMY_BYTE);

    // /* read a byte from the flash */
    // temp2 = driver_spi_flash_send_byte(DUMMY_BYTE);

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();

    //temp = (temp0 << 16) | (temp1 << 8) | temp2;
    temp = (temp0 << 8) | temp1 ;    
    return temp;
}

/*!
    \brief      initiate a read data byte (read) sequence from the flash
    \param[in]  read_addr: flash's internal address to read from
    \param[out] none
    \retval     none
*/
void driver_spi_flash_start_read_sequence(uint32_t read_addr)
{
    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();

    /* send "read from memory " instruction */
    driver_spi_flash_send_byte(READ);

    /* send the 24-bit address of the address to read from */
    /* send read_addr high nibble address byte */
    driver_spi_flash_send_byte((read_addr & 0xFF0000) >> 16);
    /* send read_addr medium nibble address byte */
    driver_spi_flash_send_byte((read_addr& 0xFF00) >> 8);
    /* send read_addr low nibble address byte */
    driver_spi_flash_send_byte(read_addr & 0xFF);
}

/*!
    \brief      read a byte from the SPI flash
    \param[in]  none
    \param[out] none
    \retval     byte read from the SPI flash
*/
uint8_t driver_spi_flash_read_byte(void)
{
    return(driver_spi_flash_send_byte(DUMMY_BYTE));
}

/*!
    \brief      send a byte through the SPI interface and return the byte received from the SPI bus
    \param[in]  byte: byte to send
    \param[out] none
    \retval     the value of the received byte
*/
uint8_t driver_spi_flash_send_byte(uint8_t byte)
{
    /* loop while data register in not emplty */
    while (RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_TBE));

    /* send byte through the SPI0 peripheral */
    spi_i2s_data_transmit(SPI1,byte);

    /* wait to receive a byte */
    while(RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_RBNE));

    /* return the byte read from the SPI bus */
    return(spi_i2s_data_receive(SPI1));
}

/*!
    \brief      send a half word through the SPI interface and return the half word received from the SPI bus
    \param[in]  half_word: half word to send
    \param[out] none
    \retval     the value of the received byte
*/
uint16_t driver_spi_flash_send_halfword(uint16_t half_word)
{
    /* loop while data register in not emplty */
    while(RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_TBE));

    /* send half word through the SPI0 peripheral */
    spi_i2s_data_transmit(SPI1,half_word);

    /* wait to receive a half word */
    while(RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_RBNE));

    /* return the half word read from the SPI bus */
    return spi_i2s_data_receive(SPI1);
}

/*!
    \brief      enable the write access to the flash
    \param[in]  none
    \param[out] none
    \retval     none
*/
void driver_spi_flash_write_enable(void)
{
    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();

    /* send "write enable" instruction */
    driver_spi_flash_send_byte(WREN);

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();
}

/*!
    \brief      poll the status of the write in progress(wip) flag in the flash's status register
    \param[in]  none
    \param[out] none
    \retval     none
*/
void driver_spi_flash_wait_for_write_end(void)
{
    uint8_t flash_status = 0;

    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();

    /* send "read status register" instruction */
    driver_spi_flash_send_byte(RDSR);

    /* loop as long as the memory is busy with a write cycle */
    do{
        /* send a dummy byte to generate the clock needed by the flash
        and put the value of the status register in flash_status variable */
        flash_status = driver_spi_flash_send_byte(DUMMY_BYTE);
    }while((flash_status & WIP_FLAG) == SET);

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();
}

driver_flash.h

#ifndef DRIVER_GD25QXX_H
#define DRIVER_GD25QXX_H

#include "gd32f30x.h"
#include "systick.h"

#define  SPI_FLASH_PAGE_SIZE           (4096)
#define  SPI_FLASH_CS_LOW()            gpio_bit_reset(GPIOD, GPIO_PIN_8)
#define  SPI_FLASH_CS_HIGH()           gpio_bit_set(GPIOD, GPIO_PIN_8)

#define SPI1_MOSI_PORT                  (GPIOB)
#define SPI1_MOSI_PIN                   (GPIO_PIN_15)
#define SPI1_MISO_PORT                  (GPIOB)
#define SPI1_MISO_PIN                   (GPIO_PIN_14)
#define SPI1_SCK_PORT                   (GPIOB)
#define SPI1_SCK_PIN                    (GPIO_PIN_13)
#define SPI1_CS_PORT                    (GPIOD)
#define SPI1_CS_PIN                     (GPIO_PIN_8)

/* initialize SPI0 GPIO and parameter */
void driver_spi_flash_init(void);
/* erase the specified flash sector */
void driver_spi_flash_sector_erase(uint32_t sector_addr);
/* erase the entire flash */
void driver_spi_flash_bulk_erase(void);
/* write more than one byte to the flash */
void norflash_read(uint8_t* pbuffer,uint32_t write_addr,uint16_t num_byte_to_write);
/* write block of data to the flash */
void norflash_write(uint8_t* pbuffer,uint32_t write_addr,uint16_t num_byte_to_write);
/* read a block of data from the flash */
void driver_spi_flash_buffer_read(uint8_t* pbuffer,uint32_t read_addr,uint16_t num_byte_to_read);
/* read flash identification */
uint32_t driver_spi_flash_read_id(void);
/* initiate a read data byte (read) sequence from the flash */
void driver_spi_flash_start_read_sequence(uint32_t read_addr);
/* read a byte from the SPI flash */
uint8_t driver_spi_flash_read_byte(void);
/* send a byte through the SPI interface and return the byte received from the SPI bus */
uint8_t driver_spi_flash_send_byte(uint8_t byte);
/* send a half word through the SPI interface and return the half word received from the SPI bus */
uint16_t driver_spi_flash_send_halfword(uint16_t half_word);
/* enable the write access to the flash */
void driver_spi_flash_write_enable(void);
/* poll the status of the write in progress (wip) flag in the flash's status register */
void driver_spi_flash_wait_for_write_end(void);

#endif /* GD25QXX_H */

同样在elog_port.c文件中函数elog_port_output需要自己编写

这里的变量ul_lendth是全局变量,有需要可以将该变量更新到单片机内置flash,这里不再赘述

//将日志写入flash
void flash_log(uint8_t *pbuffer, uint32_t ul_lendth)
{
	norflash_write(pbuffer, gul_flash_addr, ul_lendth);
	gul_flash_addr += ul_lendth;
}

elog_port.c中

void elog_port_output(const char *log, size_t size) 
{
    flash_log(log, size);
}

四、导入接口

最后需要导入ezlogger系统几个重要函数,即关于日志系统的初始化、配置、启动和使用

//初始化spiflash,rtc
void mylog_init(void)
{
	elog_init();
	//设置日志格式
	elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
	elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
	elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
	elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
	elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
	elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
	elog_start();

	uint32_t RTCSRC_FLAG = 0; 
	//flash初始化
	driver_spi_flash_init();
	
	//RTC初始化
	rtc_configuration();

	//ezlogger日志系统初始化
	elog_start();
}

1.elog_init:elog初始化函数

2.elog_set_fmt:日志设置函数,第一个参数是日志等级,然后是日志需要显示哪些信息

3.flash和RTC初始化函数

4.elog_start:启动elog函数

elog_output(ELOG_LVL_VERBOSE, "test", __FILE__, __func__, __LINE__, "mian  running");

函数elog_output就是我们要用的写日志的函数,他的参数分别是:

日志等级-标签-文件名-函数名-行数-日志内容

实际运行见下图

ezlogger一些设置项:

1.设置可打印等级:

在接口函数elog_init中有一条函数elog_set_filter_lvl(ELOG_LVL_VERBOSE);

默认函数的效果是设置ELOG_LVL_VERBOSE等级及更高等级的日志可被打印

2.设置日志输出格式:

函数elog_set_fmt可以设置指定等级的日志输出何种格式,如输出tag、func、line、time等,第一个参数是对应的日志等级,第二个参数是输出内容。

在默认设置中,ELOG_LVL_ASSERT等级的日志会打印全部信息,因为裸机系统没有线程和进程的信息,所以在这去掉,修改代码如下

/* macro definition for all formats */
#define ELOG_FMT_ALL    (ELOG_FMT_LVL|ELOG_FMT_TAG|ELOG_FMT_TIME| \
    ELOG_FMT_DIR|ELOG_FMT_FUNC|ELOG_FMT_LINE)

作者:姜饼人GO

物联沃分享整理
物联沃-IOTWORD物联网 » GD32单片机裸机ezlogger日志系统移植详解

发表回复