嵌入式小技巧
前言
最近有时上班摸鱼刷手的的时候,看到一些公众号里的有关嵌入式的一些文章,感觉有些文章写的还挺不错的,于是准备稍微整理记录一下。
① 固件版本信息
1.使用背景
在工作中对于版本信息管理十分重要,有时由于客户众多,如果没有有效的管理好软件版本,就会导致后期维护费时费力。
2.实现方式
1.定义一个结构体,里面定义一些软件版本相关的信息
typedef struct
{
char szVersion[32]; // 软件版本
char szBuildDate[32]; // 程序编译日期
char szBuildTime[32]; // 程序编译时间
}AppInfo_t;
2.定义一个只读结构体变量(只读的目的:防止程序改变、节约RAM),赋初值(其中__DATE_
和__TIME__
是C语言中的内置宏,分别是当前的编译日期和编译时间)。
const AppInfo_t sg_tAppInfo =
{
"MiniHeating_V0.1.0",
__DATE__,
__TIME__,
};
3.通过Easylogger初始化后打印,将版本信息输出到串口log上
void elog_system_init(void)
{
/*init 初始化*/
elog_init();
/*配置不同输出基本的输出信息*/
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_DIR | ELOG_FMT_FUNC | ELOG_FMT_LINE);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_DIR | ELOG_FMT_FUNC | ELOG_FMT_LINE);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_DIR | ELOG_FMT_FUNC | ELOG_FMT_LINE);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_LVL | ELOG_FMT_TAG);
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_LVL | ELOG_FMT_TAG);
/*elog开始*/
elog_start();
/*打印版本信息*/
elog_i(TAG,"Version : %s",sg_tAppInfo.szVersion);
elog_i(TAG,"buildDate : %s",sg_tAppInfo.szBuildDate);
elog_i(TAG,"buildTime : %s",sg_tAppInfo.szBuildTime);
}
4.下载程序后,通过串口工具在MCU上电就能收到版本信息的打印
注意:若main文件没有重新编译,编译时间是不会发生改变的。
② 比较两个数大小宏定义
1.使用背景
常规方式:
#define MIN(a,b) ((a) < (b) ? (a) : (b))
在使用这个时候若这样写:
least = MIN(i++, j++);
就会出现错误
least = ((i++) < (j++) ? (i++) : (j++));
无论谁大谁小,最后结果都会多加一次。
2.优化后的方法
#define MIN(x,y) {
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void)(&_x = &_y); \
_x < _y ? _x : _y; \
})
其中 (void)(&x==&y)
是用于检查 x 和 y 的类型是否相同。它有两个作用:
- 一是用来给用户提示一个警告。对于不同类型的指针比较,编译器会发出一个警告,提示两种数据的类型不同。
- 二是两个数进行比较运算,运算的结果却没有用到,有些编译器可能会给出一个 warning,加一个(void)后,就可以消除这个警告。
求最大值方法类似,可自行尝试。
本文来自博客园,作者:一月一星辰,转载请注明原文链接:https://www.cnblogs.com/tangwc/p/17599297.html