stm32c8t6 hal 之 EasyLogger移植(一)

 1介绍

本期给大家带来的开源项目是 EasyLogger,一款轻量级且高性能的日志库,作者armink,目前收获 1.1K 个 star,遵循 MIT 开源许可协议。

EasyLogger 是一款超轻量级、高性能的 C/C++ 日志库,非常适合对资源敏感的软件项目,相比之下, EasyLogger 的功能更加简单,提供给用户的接口更少,上手会更快,更多实用功能支持以插件形式进行动态扩展。

目前EasyLogger支持以下功能:

日志输出方式支持串口、Flash、文件等;
日志内容可包含级别、时间戳、线程信息、进程信息等;
支持多种操作系统,支持裸机;
各级别日志支持不同颜色显示;

2代码移植

2.1使用hal库创建异步串口功能

参考我之前的贴子:
使用cube配置stm32c8t6最小系统板串口功能

目前只配置了使用循环等待模式,后续异步模式(使用中断)请看我后面的帖子。

2.2开始移植

  • 在工程文件文件夹下创建文件夹并添加相应文件
|-- easy_logger
|   |-- inc
|   |   |-- elog.h
|   |   `-- elog_cfg.h
|   `-- src
|       |-- elog.c
|       |-- elog_port.c
|       `-- elog_utils.c
  • 在keil中添加文件

  • 添加头文件包含

2.3修改main函数

添加头文件、宏、以及打印代码,相关宏定义以及代码的含义,在后面的章节讨论

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#define LOG_TAG    "main"

#include <elog.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
 * EasyLogger demo
 */
void test_elog(void) {
    /* test log output for all level */
    log_a("Hello EasyLogger!");
    log_e("Hello EasyLogger!");
    log_w("Hello EasyLogger!");
    log_i("Hello EasyLogger!");
    log_d("Hello EasyLogger!");
    log_v("Hello EasyLogger!");
//    elog_raw("Hello EasyLogger!");
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	/* initialize 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_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_FMT_T_INFO | ELOG_FMT_P_INFO));
	elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_T_INFO | ELOG_FMT_P_INFO));
	/* start EasyLogger */
	elog_start();
	
	/* dynamic set enable or disable for output logs (true or false) */
//    elog_set_output_enabled(false);
	/* dynamic set output logs's level (from ELOG_LVL_ASSERT to ELOG_LVL_VERBOSE) */
//    elog_set_filter_lvl(ELOG_LVL_WARN);
	/* dynamic set output logs's filter for tag */
//    elog_set_filter_tag("main");
	/* dynamic set output logs's filter for keyword */
//    elog_set_filter_kw("Hello");
	/* dynamic set output logs's tag filter */
//    elog_set_filter_tag_lvl("main", ELOG_LVL_WARN);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		 /* test logger output */
		test_elog();
		HAL_Delay(1000);
		
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

2.4效果展示

3结语

以上是EasyLogger移植到stm32f103c8t6的过程,以上代码已经上传,代码分析请看后面章节。

对开源项目感兴趣的同学欢迎加入QQ群:766921820

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32C8T6HAL是针对STM32C8T6芯片进行开发的一套HAL,提供了丰富的外设驱动和底层硬件操作接口。而ESP8266是一款WiFi模块,可以通过串口通信与STM32芯片进行通信。在使用ESP8266模块时,可以使用STM32的串口功能来进行通信。 在使用STM32C8T6HAL与ESP8266模块进行串口通信时,需要先配置好串口参数(如波特率、数据位、停止位、校验位等),然后通过HAL提供的函数来进行发送和接收数据。具体步骤如下: 1. 在HAL中初始化串口功能,设置好串口参数。 2. 在代码中写好发送和接收数据的函数。 3. 在主程序中调用发送和接收数据的函数,实现与ESP8266模块的通信。 具体实现过程可以参考以下代码示例: ```c #include "stm32c8t6_hal.h" // 定义串口变量 UART_HandleTypeDef huart1; // 定义接收缓存区和计数器 uint8_t rx_buffer[256]; uint8_t rx_counter = 0; // 发送数据函数 void send_data(uint8_t* data, uint16_t len) { HAL_UART_Transmit(&huart1, data, len, 1000); } // 接收数据回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 将接收到的数据存入缓存区 rx_buffer[rx_counter++] = huart->Instance->DR; // 如果缓存区满了,清空计数器 if (rx_counter >= 256) { rx_counter = 0; } // 继续接收数据 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_counter], 1); } } int main(void) { // 初始化串口1 huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); // 开启中断接收 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_counter], 1); // 发送数据给ESP8266模块 uint8_t send_data[] = "AT+RST\r\n"; send_data(send_data, sizeof(send_data)); // 接收ESP8266模块返回的数据 while (1) { if (rx_counter > 0) { // 处理接收到的数据 // ... // 清空缓存区 rx_counter = 0; memset(rx_buffer, 0, sizeof(rx_buffer)); // 继续接收数据 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_counter], 1); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值