OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5105|回复: 16

利用宏定义__DATE__和__TIME__做软件版本控制

[复制链接]

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
发表于 2020-5-27 17:20:57 | 显示全部楼层 |阅读模式
本帖最后由 jiangyy 于 2020-12-2 17:39 编辑

  大家可能在做项目的时候,遇到版本日期时间的问题,怎么知道我软件版本发布的具体时间和日期,可能有些人使用RTC时间/日期或flash固化时间/日期,每次上电将RTC时间/日期或flash固化时间/日期赋值到某些变量上面,然后通过协议将时间/日期传递给下位机来显示。可是在这里会面临一个问题,如果软件版本迭代比较多(比如隔日或隔月修改一次),那么可能会要手动去修改RTC时间/日期或flash固化时间/日期,而且有时候粗心大意会修改错误,感觉比较繁琐,怎样用一种好的办法,不需要手动去修改?答案肯定是有的,最近在百度搜索到一篇文章,发现MDK5编译器编译的时候,确实有时间/日期的打印信息。具体实现办法如下:

一、建立一个.c文件,.h文件

  1. /*
  2. * bsp_common.c
  3. *
  4. *  Created on: 2020年11月10日
  5. *      Author: jiangyuanyuan
  6. */

  7. #include "bsp_common.h"

  8. #define YEAR ((((__DATE__[7] - '0') * 10 + (__DATE__[8] - '0')) * 10 \
  9.     + (__DATE__[9] - '0')) * 10 + (__DATE__[10] - '0'))

  10. #define MONTH ((__DATE__[1] == 'a' && __DATE__[2] == 'n') ? 1 \
  11.     : __DATE__[2] == 'b' ? 2 \
  12.     : __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? 3 : 4) \
  13.     : __DATE__[2] == 'y' ? 5 \
  14.     : __DATE__[2] == 'n' ? 6 \
  15.     : __DATE__[2] == 'l' ? 7 \
  16.     : __DATE__[2] == 'g' ? 8 \
  17.     : __DATE__[2] == 'p' ? 9 \
  18.     : __DATE__[2] == 't' ? 10 \
  19.     : __DATE__[2] == 'v' ? 11 : 12)

  20. #define DAY ((__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') * 10 \
  21.     + (__DATE__[5] - '0'))

  22. #define HOUR ((__TIME__[0] == ' ' ? 0 : __TIME__[0] - '0') * 10 \
  23.     + (__TIME__[1] - '0'))

  24. #define MINUTE ((__TIME__[3] == ' ' ? 0 : __TIME__[3] - '0') * 10 \
  25.     + (__TIME__[4] - '0'))

  26. #define SECOND ((__TIME__[6] == ' ' ? 0 : __TIME__[6] - '0') * 10 \
  27.     + (__TIME__[7] - '0'))

  28. Soft_Ver sSoft_Ver;
  29. u32 get_ver(void)
  30. {
  31.         u32 ver;
  32.         sSoft_Ver.ucMany = VER_MANY;//Bit26~ Bit31:固件大量改动(主版本),默认值0
  33.         sSoft_Ver.ucLocal = VER_LOCAL;//Bit18~ Bit25:固件局部改动(次版本),默认值0
  34.         sSoft_Ver.ucCustom = VER_CUSTOM;//Bit14~ Bit17:固件细节改动(测试/定制版本),默认值0
  35.         sSoft_Ver.usYear = YEAR - 2019;//Bit10~ Bit13:年(2020 = 1,2034 = 15),默认值1
  36.         sSoft_Ver.ucMonth = MONTH;//Bit06~ Bit9:月(1~12)
  37.         sSoft_Ver.ucDay = DAY;//Bit00~ Bit05:日(1~31)
  38.         ver = sSoft_Ver.ucDay | (sSoft_Ver.ucMonth << 6) | (sSoft_Ver.usYear << 10) | (sSoft_Ver.ucCustom << 14) | (sSoft_Ver.ucLocal << 18) | (sSoft_Ver.ucMany << 26);

  39.         return ver;
  40. //        printf ("Date:%d-%d-%d\r\n", sRevision_Dat.usYear,sRevision_Dat.ucMonth,sRevision_Dat.ucDay);
  41. //        printf ("Time:%d:%d:%d\r\n", sRevision_Dat.ucHour,sRevision_Dat.ucMinute,sRevision_Dat.ucSecond);
  42. }

复制代码
  1. /*
  2. * bsp_common.h
  3. *
  4. *  Created on: 2020年11月10日
  5. *      Author: jiangyuanyuan
  6. */

  7. #ifndef INC_BSP_COMMON_H_
  8. #define INC_BSP_COMMON_H_

  9. #include "stdio.h"
  10. #include "mytype.h"
  11. #include "bsp_sys.h"

  12. #ifdef  COMMON_GLOBALS
  13. #define COMMON_EXT
  14. #else
  15. #define COMMON_EXT  extern
  16. #endif

  17. #ifdef __SINGLE_MODE_               //单模
  18.         #define VER_MANY        1                        //固件大量改动(主版本)
  19.         #define VER_LOCAL   0                        //固件局部改动(次版本)
  20.         #define VER_CUSTOM  0                        //固件细节改动(测试/定制版本)
  21. #else                               //多模
  22.         #define VER_MANY        2                        //固件大量改动(主版本)
  23.         #define VER_LOCAL   0                        //固件局部改动(次版本)
  24.         #define VER_CUSTOM  0                        //固件细节改动(测试/定制版本)
  25. #endif

  26. typedef struct
  27. {
  28.         u8 ucMany:6;
  29.         u8 ucLocal:8;
  30.         u8 ucCustom:4;
  31.         u8 usYear:4;
  32.         u8 ucMonth:4;
  33.         u8 ucDay:6;
  34. }Soft_Ver;

  35. extern Soft_Ver sSoft_Ver;

  36. u32 get_ver(void);
  37. #endif /* INC_BSP_COMMON_H_ */
复制代码

希望上面分享的信息能对你后期的项目有帮助,我在自己的项目用得到。赞一个或者留个小红花,谢谢,爱你么么哒~~





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2018-12-27
在线时间
0 小时
发表于 2020-5-27 17:20:57 | 显示全部楼层
帮顶,大家来帮忙解答一下。。
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-5-27 17:30:43 | 显示全部楼层
华山剑客 发表于 2020-5-27 17:20
帮顶,大家来帮忙解答一下。。

我这是分享,不需要解答,谢谢
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-5-28 14:50:49 | 显示全部楼层
本帖最后由 jiangyy 于 2020-6-2 15:36 编辑

更新一下算法
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-6-2 15:36:14 | 显示全部楼层
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 17:35:15 | 显示全部楼层
已修复代码,已贴上分享给大家。
回复 支持 反对

使用道具 举报

4

主题

84

帖子

1

精华

高级会员

Rank: 4

积分
666
金钱
666
注册时间
2013-10-21
在线时间
88 小时
发表于 2020-12-2 17:49:45 | 显示全部楼层
jiangyy 发表于 2020-12-2 17:35
已修复代码,已贴上分享给大家。

华丽花哨看不懂,这部分代码的意思是把编译器生成代码的时间记录到程序里面,
然后给的那个接口可以查询到生成的时间,作为版本信息吗?
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 18:07:28 | 显示全部楼层
旮旯旭 发表于 2020-12-2 17:49
华丽花哨看不懂,这部分代码的意思是把编译器生成代码的时间记录到程序里面,
然后给的那个接口可以查询 ...

是的,项目一般用得到。
回复 支持 反对

使用道具 举报

4

主题

84

帖子

1

精华

高级会员

Rank: 4

积分
666
金钱
666
注册时间
2013-10-21
在线时间
88 小时
发表于 2020-12-2 18:14:40 | 显示全部楼层
jiangyy 发表于 2020-12-2 18:07
是的,项目一般用得到。

1606903944(1).jpg

试着打印了下 是这个东西,今天学到了不少啊

可以安心的睡个好觉了,嘎嘎!
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 18:28:29 | 显示全部楼层
旮旯旭 发表于 2020-12-2 18:14
试着打印了下 是这个东西,今天学到了不少啊

可以安心的睡个好觉了,嘎嘎!

回复 支持 反对

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2020-12-2 21:39:15 | 显示全部楼层

用时间做软件版本其实作用不大。

真正的软件版本控制是要用git之类的软件版本控制系统,并且软件代码的版本号要有两个特性:
  • 软件版本号能够要编译时自动生成;
  • 软件版本号能够跟版本控制系统挂钩。
git版本控制系统在软件发布时,会对代码仓库用git tag命令打一个标签,如:V0.3,而用命令git describe可以获取代码仓库的直观的版本标记,如:V0.3-15-ga39d965。
于是,就可以要写一个脚本基于git describe命令生成软件版本号头文件,如:version.h,而在IDE的编译步骤中设置在编译工程前执行这个脚本,即可实现这两个特性。
获取生成软件版本号的脚本如下:
  1. #!/usr/bin/python

  2. import sys
  3. import os
  4. import time

  5. version_file_fmt = '''#ifndef VERSION_H_
  6. #define VERSION_H_

  7. #define VERSION "{version}"
  8. #define BUILD   "{build}"
  9. #define CONFIG  "{config}"

  10. #endif /* VERSION_H_ */
  11. '''

  12. filePath = sys.argv[1]
  13. print("Generating: {}".format(filePath))

  14. if len(sys.argv) > 2:
  15.     config = sys.argv[2]
  16. else:
  17.     config = ""

  18. cmd = "git describe --always --dirty"
  19. output = os.popen(cmd)
  20. describe = output.read()

  21. lt = time.localtime()
  22. if 'dirty' in describe:
  23.         dirty = time.strftime("%Y%m%d%H%M", lt)
  24.         version = describe.replace('dirty', dirty)
  25. else:
  26.         version = describe
  27. version = version.replace('\n', '')

  28. build = time.strftime("%Y-%m-%d %H:%M:%S", lt)

  29. version_file_string = version_file_fmt.format(version=version, build=build, config=config)
  30. print("version: {}\nbuild  : {}\nconfig : {}".format(version, build, config))
  31. with open(filePath, 'w') as version_file:
  32.     version_file.write(version_file_string)
复制代码
在STM32CubeIDE的编译设置为:工程属性 -> C/C++ Bulid -> Settings -> Build Steps -> Pre-build steps 选项中运行如下命令:
  1. python  ../../version.py ../Core/Inc/version.h  ${config_name:USB_Camera}
复制代码

其生成的头文件 version.h 如下:
  1. #ifndef VERSION_H_
  2. #define VERSION_H_

  3. #define VERSION "V0.3-15-ga39d965-202011290001"
  4. #define BUILD   "2020-11-29 00:01:41"
  5. #define CONFIG  "Release"

  6. #endif /* VERSION_H_ */
复制代码





回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-9 10:17:42 | 显示全部楼层
ufbycd 发表于 2020-12-2 21:39
用时间做软件版本其实作用不大。

真正的软件版本控制是要用git之类的软件版本控制系统,并且软件代码 ...

非常感谢你的分享和心得,很少有人这么分享自己的劳动成果了,只会一味的索取。
回复 支持 反对

使用道具 举报

10

主题

205

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1322
金钱
1322
注册时间
2015-3-3
在线时间
127 小时
发表于 2021-1-28 08:53:17 | 显示全部楼层
写的不错,赞一个
海纳百川者,荣耀伴一生!
回复 支持 反对

使用道具 举报

10

主题

205

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1322
金钱
1322
注册时间
2015-3-3
在线时间
127 小时
发表于 2021-1-29 08:41:04 | 显示全部楼层
ufbycd 发表于 2020-12-2 21:39
用时间做软件版本其实作用不大。

真正的软件版本控制是要用git之类的软件版本控制系统,并且软件代码 ...

这个思路确实不错
海纳百川者,荣耀伴一生!
回复 支持 反对

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2021-1-29 08:59:03 | 显示全部楼层
shumivan 发表于 2021-1-28 08:53
写的不错,赞一个

谢谢,互相共同学习
回复 支持 反对

使用道具 举报

2

主题

30

帖子

0

精华

高级会员

Rank: 4

积分
582
金钱
582
注册时间
2019-2-24
在线时间
50 小时
发表于 2021-1-30 21:11:07 | 显示全部楼层
留个小红花,谢谢
回复 支持 反对

使用道具 举报

2

主题

14

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2020-6-3
在线时间
3 小时
发表于 2021-2-26 10:57:58 | 显示全部楼层
ufbycd 发表于 2020-12-2 21:39
用时间做软件版本其实作用不大。

真正的软件版本控制是要用git之类的软件版本控制系统,并且软件代码 ...

优秀!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 12:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表