STM32F105RB在FreeRTOS系统下移植使用EasyLogger

前言

本博客记录了使用STM32F105RB时在FreeRTOS系统下如何移植EasyLogger。

用到的软件有:keil5、J_Link RTT Viewer


参考链接

  1. freertos移植easylogger_freertos easylogger-CSDN博客
  2. 【嵌入式小技巧】STM32 实现 SEGGER RTT 打印(超详细)-CSDN博客

移植步骤

一、EasyLogger

1.下载

链接: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++ 日志库

2.将下载的压缩包解压

解压之后会有以下几个文件,其中主要用到的是./easylogger中的内容

3.将它移植到需要用到的工程目录中

4.打开工程,将./easylogger/port/以及./easylogger/src中的.c文件添加进工程

这里我只添加了./port中的.c文件以及./src中必要添加的文件

同时添加头文件路径

至此,EasyLogger已经移植成功,但在使用前还需进行一些必要的配置。

5.配置elog_cfg.h

这里我直接放代码了,需要改动的地方可以去开头参考链接1的博客了解;

/*
 * This file is part of the EasyLogger Library.
 *
 * Copyright (c) 2015-2016, 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.
 *
 * Function: It is the configure head file for this library.
 * Created on: 2015-07-30
 */

#ifndef _ELOG_CFG_H_
#define _ELOG_CFG_H_
/*---------------------------------------------------------------------------*/
/* enable log output. */
#define ELOG_OUTPUT_ENABLE
/* setting static output log level. range: from ELOG_LVL_ASSERT to ELOG_LVL_VERBOSE */
#define ELOG_OUTPUT_LVL                          ELOG_LVL_VERBOSE
/* enable assert check */
#define ELOG_ASSERT_ENABLE
/* buffer size for every line's log */
#define ELOG_LINE_BUF_SIZE                       1024
/* output line number max length */
#define ELOG_LINE_NUM_MAX_LEN                    5
/* output filter's tag max length */
#define ELOG_FILTER_TAG_MAX_LEN                  30
/* output filter's keyword max length */
#define ELOG_FILTER_KW_MAX_LEN                   16
/* output filter's tag level max num */
#define ELOG_FILTER_TAG_LVL_MAX_NUM              5
/* output newline sign */
#define ELOG_NEWLINE_SIGN                        "\r\n"
/*---------------------------------------------------------------------------*/
/* enable log color */
#define ELOG_COLOR_ENABLE
/* change the some level logs to not default color if you want */
#define ELOG_COLOR_ASSERT                        (F_MAGENTA B_NULL S_NORMAL)
#define ELOG_COLOR_ERROR                         (F_RED B_NULL S_NORMAL)
#define ELOG_COLOR_WARN                          (F_YELLOW B_NULL S_NORMAL)
#define ELOG_COLOR_INFO                          (F_CYAN B_NULL S_NORMAL)
#define ELOG_COLOR_DEBUG                         (F_GREEN B_NULL S_NORMAL)
#define ELOG_COLOR_VERBOSE                       (F_BLUE B_NULL S_NORMAL)
/*---------------------------------------------------------------------------*/
/* enable log fmt */
/* comment it if you don't want to output them at all */
#define ELOG_FMT_USING_FUNC
#define ELOG_FMT_USING_DIR
#define ELOG_FMT_USING_LINE
/*---------------------------------------------------------------------------*/
/* enable asynchronous output mode */
//#define ELOG_ASYNC_OUTPUT_ENABLE
/* the highest output level for async mode, other level will sync output */
#define ELOG_ASYNC_OUTPUT_LVL                    ELOG_LVL_ASSERT
/* buffer size for asynchronous output mode */
#define ELOG_ASYNC_OUTPUT_BUF_SIZE               (ELOG_LINE_BUF_SIZE * 10)
/* each asynchronous output's log which must end with newline sign */
#define ELOG_ASYNC_LINE_OUTPUT
/* asynchronous output mode using POSIX pthread implementation */
#define ELOG_ASYNC_OUTPUT_USING_PTHREAD
/*---------------------------------------------------------------------------*/
/* enable buffered output mode */
//#define ELOG_BUF_OUTPUT_ENABLE
/* buffer size for buffered output mode */
#define ELOG_BUF_OUTPUT_BUF_SIZE                 (ELOG_LINE_BUF_SIZE * 10)

#endif /* _ELOG_CFG_H_ */

6.配置elog_port.c

我这里配置的代码与参考链接1的内容有些许不同,可以自行选择参考

注意:在此处编译可能会报错,原因是我头文件中引入了RTT的头文件,如果你是打算跟我用同一个日志打印工具那这里就不影响,可以继续跟着我一步步配置,如果你不打算用RTT,那可以把RTT的头文件删除。

/*
 * This file is part of the EasyLogger Library.
 *
 * Copyright (c) 2015, 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.
 *
 * Function: Portable interface for each platform.
 * Created on: 2015-04-28
 */
 
#include <elog.h>
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "SEGGER_RTT.h"
#include "SEGGER_RTT_Conf.h"


//! 日志互斥信号量句柄
static SemaphoreHandle_t LogMutexSemaphore = NULL; 

/**
 * EasyLogger port initialize
 *
 * @return result
 */
ElogErrCode elog_port_init(void) {
    ElogErrCode result = ELOG_NO_ERR;

    /* add your code here */
    //! 创建互斥信号值
    LogMutexSemaphore = xSemaphoreCreateMutex();
    if (LogMutexSemaphore == NULL) {
        printf("elog sem create fail\r\n");
        result =  ELOG_SEM_FAIL;	//!< 注意:ElogErrCode 枚举中没有这个类型,需要添加一个错误类型
    }

    return result;
}

/**
 * EasyLogger port deinitialize
 *
 */
void elog_port_deinit(void) {

    /* add your code here */

}

/**
 * output log port interface
 *
 * @param log output of log
 * @param size log size
 */
void elog_port_output(const char *log, size_t size) {
    
    /* add your code here */
    //! %s 表示字符串输出,
    //! .<十进制数> 是精度控制格式符,输出字符时表示输出字符的位数,
    //! 在精度控制时,小数点后的十进制数可以使用 * 来占位,
    //! 在后面提供一个变量作为精度控制的具体值
    SEGGER_RTT_Write(0, log, size);
}

/**
 * output lock
 */
void elog_port_output_lock(void) {
    
    /* add your code here */
    if (NULL != LogMutexSemaphore)
    {
        xSemaphoreTake(LogMutexSemaphore, portMAX_DELAY); //!< 等待互斥信号量
    }   
}

/**
 * output unlock
 */
void elog_port_output_unlock(void) {
    
    /* add your code here */
    if (NULL != LogMutexSemaphore)
    {
        xSemaphoreGive(LogMutexSemaphore); //!< 发送互斥信号量
    } 
}

/**
 * get current time interface
 *
 * @return current time
 */
const char *elog_port_get_time(void) {
    
    /* add your code here */
    static char cur_system_time[16] = { 0 };

#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    {
#endif
        TickType_t tick = xTaskGetTickCount();
        snprintf(cur_system_time, 16, "%d.%.3d", (tick / configTICK_RATE_HZ), tick % configTICK_RATE_HZ);
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    }
#endif 

    return cur_system_time;
}

/**
 * get current process name interface
 *
 * @return current process name
 */
const char *elog_port_get_p_info(void) {
    
    /* add your code here */
    return "";
}

/**
 * get current thread name interface
 *
 * @return current thread name
 */
const char *elog_port_get_t_info(void) {
    
    /* add your code here */
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    {
#endif
        return pcTaskGetName(xTaskGetCurrentTaskHandle());
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    }
#endif 

    return "";
}

/**
 * init easylogger,这个函数是我们自己添加的,便于用户直接调用,需要在elog.h中添加声明
 */
void easylogger_init(void)
{
    /* init Easylogger */
	elog_init();

	/* set EasyLogger log format */
    elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
	elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TIME | ELOG_FMT_T_INFO);
	elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_T_INFO);
	elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL);
	elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);

	/*Eenbale color*/
	elog_set_text_color_enabled(true);

	/* start EasyLogger */
	elog_start();
    
}

 至此关于EasyLogger的改动已经结束了,接下来将进行RTT的配置


二、配置J-Link RTT Viewer

1.下载J-Link全家桶

去J-Link官网下载合适的版本

SEGGER - The Embedded Experts - Downloads - J-Link / J-Trace

下载后安装后就有J-Link全家桶了

我们一会要用的就是红框中的程序,但在此之前要进行一些配置

2.添加RTT进工程

在安装的全家桶中找到这个文件夹

进去后点击RTT

解压

解压后得到以下内容

将他们全部拷贝到keil5工程目录下,并将.c文件添加进工程中

并且添加头文件路径

至此,RTT也移植完成了,接下来将进行使用RTT打印日志信息


三、打印日志

1.在main文件中编写测试代码

#include "stm32f10x.h"                  // Device header

#include <stdio.h>
#include <stdlib.h>


#include "FreeRTOS.h"
#include "task.h"

#include "elog.h"


#define THREAD_STACKSIZE  1024
#define DEFAULT_THREAD_PRIO 2

TaskHandle_t task1_handler = NULL;
TaskHandle_t task2_handler = NULL;


void test(void *parameter)
{
	int *hh = (int *)parameter;
	while(1)
	{
		
		log_a("%d:  Hello EasyLogger!", *hh);
		log_e("%d: Hello EasyLogger!", *hh);
		log_w("%d: Hello EasyLogger!", *hh);
		log_i("%d: Hello EasyLogger!", *hh);
		log_d("%d: Hello EasyLogger!", *hh);
		log_v("%d: Hello EasyLogger!", *hh);


		vTaskDelay(1/portTICK_PERIOD_MS);
	}

}

void main_task(void *p)
{


	int testNum = 1;
    xTaskCreate(test, ( const char * const)"task1", THREAD_STACKSIZE, (void *)&testNum, DEFAULT_THREAD_PRIO, &task1_handler);

    int testNum1 = 2;
    xTaskCreate(test, ( const char * const)"task2", THREAD_STACKSIZE, (void *)&testNum1, DEFAULT_THREAD_PRIO, &task2_handler);
		//sys_thread_new("system_init_thread", system_init_thread, &i, THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
    vTaskDelete(NULL);
}

int main(void)
{

	easylogger_init();
	TaskHandle_t xHandle = NULL;
	xTaskCreate(main_task, "main_task", THREAD_STACKSIZE, NULL, DEFAULT_THREAD_PRIO, &xHandle);
	vTaskStartScheduler();
	while (1);
    return 0;
}

编译下载,并且J-Link不要断开

2.打开RTT Viewer

打开后进行以下操作

第二步时选择自己对应的板子型号

配置之后就可以正常显示日志内容啦


四、最后再说一下怎么使用elog打印函数


总结

这是本人在学习移植elog时总结的笔记,也是我的第一篇博客,如有不全,希望谅解与补充,若对你有帮助,还请留下一个赞以示鼓励呀!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值