Clion开发STM32之ESP8266系列(二)

前言

  1. 上一篇Clion开发STM32之ESP8266系列(一)

本篇主要内容

  1. 日志输出日志驱动编写
  2. 模块解耦的通用配置编写

正文

项目结构

Clion开发STM32之ESP8266系列(二)_第1张图片

日志输出日志驱动编写

头文件

/*******************************************************************************
 * @author scl
 * @email [email protected]
 ******************************************************************************/

#ifndef STM32F103VET6_ESP8266_SYS_CORE_PRINTF_H
#define STM32F103VET6_ESP8266_SYS_CORE_PRINTF_H
#include "sys_core_conf.h"
/**
 * @brief 自定义格式化打印输出
 * @param format
 * @param ...
 */
void os_ps(char *format, ...);
/**
 * @brief 源数据记录
 * @param data 数据
 * @param len  数据长度
 */
void os_log(uint8_t *data, uint16_t len);

/**
 * 设置日志回调(如果没有设置,os_ps和os_log不生效)
 * @param call
 */
void os_log_call_set(common_send_call_back call);
#endif //STM32F103VET6_ESP8266_SYS_CORE_PRINTF_H

源文件

/*******************************************************************************
 * @author scl
 * @email [email protected]
 ******************************************************************************/

#include "sys_core_printf.h"
#include 

static common_send_call_back log_cal = NULL;
static char os_tx_buf[512];

void os_ps(char *format, ...) {
    if (log_cal != NULL) {
        va_list v_args;
        va_start(v_args, format);
        // 如果成功,则返回写入的字符总数,否则返回一个负数。
        int len = vsnprintf((char *) &os_tx_buf[0], (size_t)
                sizeof(os_tx_buf), (char const *) format, v_args);
        va_end(v_args);
        if (len > 0) {
            log_cal(os_tx_buf, len);
        }
    }
}

void os_log(uint8_t *data, uint16_t len) {
    if (log_cal != NULL) {
        log_cal(data, len);
    }
}

/**
 *
 * @param call 日志记录回调注册
 */
void os_log_call_set(common_send_call_back call) {
    log_cal = call;
}

模块解耦的通用配置编写

参考我的这篇文章:模块解耦的通用配置编写

链接文件修改

Clion开发STM32之ESP8266系列(二)_第2张图片

  /* 添加驱动初始化段名 */
 .driver.init :
  {
    /*展示当前驱动初始化起始地址*/
    __driver_init_start = .;
    /*这里对驱动进行排序(这里就是所有注册驱动的地址,在生成的时候自动分配地址(可以是结构体或函数的指针))*/
    KEEP (*(SORT(.driver_init*)))
    /*展示当前驱动初始化结束地址*/
    __driver_init_end = .;
    . = ALIGN(4);
  } >FLASH

增加配置定义

/*******************************************************************************
 * @author scl
 * @email [email protected]
 ******************************************************************************/

#ifndef STM32F103VET6_ESP8266_SYS_CORE_CONF_H
#define STM32F103VET6_ESP8266_SYS_CORE_CONF_H

#include "sys_core_include.h"
/* 宏定义一下 编译器的特性 */
#define sys_section(x)   __attribute__((section(x)))
#define sys_used         __attribute__((used))
/**
 * @brief 发送数据回调
 */
typedef void (*common_send_call_back)(void *data, uint16_t len);
/* 类型定义 驱动初始化函数类型 */
typedef void (*driver_init_fn)(void);
/* 宏定义驱动模块导出宏定义*/
#define DRIVER_EXPORT(dr_name, init_fn) sys_used const  driver_init_fn __fn_##dr_name sys_section(".driver_init."#dr_name) = init_fn
#endif //STM32F103VET6_ESP8266_SYS_CORE_CONF_H

修改驱动初始化入口函数编写

/*******************************************************************************
 * @author scl
 * @email [email protected]
 ******************************************************************************/

#include "app_conf.h"

extern driver_init_fn __driver_init_start[];
extern driver_init_fn __driver_init_end[];

void app_driver_init() {
    for (const driver_init_fn *driver_init = __driver_init_start; driver_init < __driver_init_end; driver_init++) {
        (*driver_init)(); // 执行函数
    }
}

通过驱动初始化注册日志文件

在main函数中添加驱动初始化的入口函数

Clion开发STM32之ESP8266系列(二)_第3张图片

创建日志驱动配置文件

测试

日志调试
Clion开发STM32之ESP8266系列(二)_第4张图片Clion开发STM32之ESP8266系列(二)_第5张图片Clion开发STM32之ESP8266系列(二)_第6张图片

Clion开发STM32之ESP8266系列(二)_第7张图片
Clion开发STM32之ESP8266系列(二)_第8张图片

你可能感兴趣的:(STM32从0开始记录,stm32,单片机,嵌入式硬件)