如何把编译时间加入到目标文件中

发布时间:2024-02-01  

01 问题背景:如何保证发布出去的bin文件是最终测试通过的版本?

本文引用地址:

一般的来讲,到了测试后期,master分支就不会频繁的提交了,并且提交也会更加谨慎。但是人为操作总会出现纰漏,希望只要被重新过,那么bin文件就包含新的时间信息,而这个信息是可以从外部通信或printf来查看的。

嵌入式开发中,版本号一般的都是一个int变量或字符串变量。但是若修改了而没有改version变量或宏定义,那么从version上就看不出来文件的变化。最终的版本到底是哪个版本,是否与测试的版本完全一致,这个问题尤为突出。

目标文件中带有时间可以防止代码被改动过,只要代码被重新编译,那么就生成新的时间信息。

git能够记录文件修改信息,但是调试信息或工程配置等,很多文件都是ignore的,这些信息代表着最终的bin文件的运行环境。某些复杂bug情况下,只有运行环境一致,仿真器才能attach到目标文件。

02 如何获取时间:__DATA__  , __ TIME__

这两个宏是日期和时间,格式如下。如果把这两个宏加入到代码,那么就得到了时间的字符串信息。

// Example of __DATE__ string: "Dec 27 2017"
// Example of __TIME__ string: "15:06:19"
const char *BuildInfo = "Version: " VERSION " " __DATE__ " " __TIME__;

代码实现获取日期和时间的方法很多,比如:

unsigned int mk_Build_Date(void){
    int    year = 0, month = 0, day = 0;
    int hour = 0, minute = 0, seconds = 0;
    char m[4] = {0};
    sscanf(__DATE__, "%3s %2d %4d", m, &day, &year);
    for (month = 0; month < 12; month++)
    {
        if (strcmp(m, short_char_months[month]) == 0)
        {
            break;
        }
    }
    sscanf(__TIME__, "%2d:%2d:%2d", &hour, &minute, &seconds);
    #ifdef SHORT_DATA_CHAR__
        printf("[null]  ** Build at:t%04u-%02u-%02us %02u:%02u:%02un",
                year, month, day,
                hour, minute,seconds);
    #else
        printf("[null]  ** Build at:t%04u-%02u-%02u %02u:%02u:%02un",
                year, month, day,
                hour, minute,seconds);
    #endif
    DEBUG("buildDate: %s %sn", __DATE__, __TIME__);
    return 0;
}

把上面的函数加入到代码中,就能获取工程编译的时间。但是如果该代码所在的文件没有被修改,在非build-all情况下,编译器不会再次编译此文件,所以时间信息也就不会被更新。

如果每次都使用re-build all,一来繁琐,二来也不能保证每次都会记得点击build all按钮,靠技术手段来保证每次build都更新时间信息才是正道。

03 如何保证时间每次编译都更新:使用预编译指令,每次更新包含时间宏的文件或对应的链接文件。

在IAR环境下,官方已经给出了解决的方法(Using pre-build actions for time stamping)。

https://www.iar.com/support/tech-notes/ide/build-actions-pre-build-and-post-build/

方法1:修改文件的时间,引起编译器对文件进行重新编译。

cmd /c "touch /cygdrive/d/test.c"

方法虽好,可惜IAR用户大多数是Windows用户,包括我在内,touch是linux命令,必须Cywin环境。如果安装过这个环境的话,那就大功告成了。

Cygwin touch command
You can enter "cygwin-application.exe" on the pre- and post-build command lines, if the environment variable PATH includes the directory where the "cygwin-application.exe" is located.
You can run the Cygwin command "touch" on the pre-build command line, but if you add a file path, for example "touch d:/test.c", the file path is not accepted by Cygwin.
Cygwin expects the POSIX path /cygdrive/d/test.c so the resulting command line would be "touch /cygdrive/d/test.c", however this command cannot be executed directly on the pre- and post-build command. Instead you have to run indirectly using:
cmd /c "touch /cygdrive/d/test.c"
The .bat file (located in project directory) alternative would look like:
Pre-build command line:
 $PROJ_DIR$pre-build.bat
File pre-build.bat:
 touch /cygdrive/d/test.c

方法2:修改文件对应的链接文件,触发编译器重新编译该文件,生成新的链接文件,那么就会生成新的带有时间信息的目标文件。

An alternative to the "touch" command is to have a pre-build action that deletes the object file, for example the Pre-build command line:
cmd /c "del "$OBJ_DIR$test.o""

在pre-build中加入上面的命令,就会在编译前删除test.o文件。在这种模式下,工程代码只要任何位置发生变化,代码重新编译,就会触发删除test.o,然后链接过程发现没有test.o文件,那么就会重新编译一次test.c,那么新的时间信息就会记录下来了。

虽有些曲线救国的味道,但还是很顺利的实现了目标。只要工程的任何地方有改动,生成新的目标文件,那么目标文件中就会带有最新的编译时间。

方法3:直接告诉编译器每次重新编译某个文件更直接,MDK支持此功能。

时隔一年半再次来这里,发现当时自己简直是小白,还洋洋得意曲线救国,实际上舍近求远罢了。如果对工具多一些了解,万万是不会用上面的方法的,当然上面的方法也是通用想法,是通用型知识点,容易想到,也能达到目标。

新的方法,不需要写任何脚本,如果想让代码每次都编译更新DATA 和 TIME两个宏,那么让这个文件每次都编译一次就可以了,不需要删除它的obj文件然后让编译器找不到文件而触发重新编一次,其实直接告诉编译器每次重新编译更直接,MDK支持此功能。

640-2.png

下面是测试的效果:

640-3.png

其它资料:https://stackoverflow.com/questions/11697820/how-to-use-date-and-time-predefined-macros-in-as-two-integers-then-stri

文章来源于:电子产品世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    刻:宏在预编译时刻,const在编译时刻; 2、编译检查:宏不会编译检查,const有编译检查 3、宏可以定义函数、方法等,const不可以 4、大量使用宏会导致预编译时间过长   16、带参......
    最先进的20 nm FPGA和SoC设计环境。Altera成熟可靠的Quartus II软件编译时间是业界最短的,支持性能最高的20 nm FPGA和SoC设计。客户可以使用这一最新版软件所包含的全系列20......
    怎样才能很快找到是哪一个版本的软件出现故障呢? C几种特殊标准定义 __FILE__:正在编译文件的文件名__LINE__:正在编译文件的行号__DATE__:编译时刻的日期字符串 如“Sep 22 2020”__TIME__:编译时刻的时间......
    于车辆电子系统复杂的工况和较高的EMC要求,辐射还可能会影响车内其他电子系统的正常工作。另一方面,以太网控制器的功耗较大,长时间保持工作增加汽车电子系统的消耗。综上,通过车载DoIP边缘节点和测试设备之间的激活......
    日期     char szBuildTime[32];  // 程序编译时间 }AppInfo_t; 2.定义一个只读结构体变量(只读的目的:防止程序改变、节约RAM),赋初值(其中__DATE_ 和__TIME__......
    足迹通常比它们在内存中的权重足迹大得多。因此,对于量化和稀疏性以及人们在权重上所做的所有努力,这很棒。在某些方面,更大的问题被忽略了,那就是激活支配了网络的内存占用,它既占用空间又占用能量和时间,因为你必须四处移动激活......
    字段作为function的参数。该字段表示的时间是以时间节拍为单位。例如如果你想定时一秒,则expires=jiffies+HZ*1。   void (*function)(unsigned long......
    Altera业界成熟可靠的Quartus II软件编译时间缩短了4倍;Altera公司(Nasdaq: ALTR)今天发布业界成熟可靠的最新版Quartus® II开发软件——对于FPGA设计,性能......
    、高速、默认输出电平为高电平 USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位 激活时钟源,激活日历,选择No RTC Output......
    结果   迭代24464次后,从缓存中找到同步头。   不开启编译时间优化时,软件算法用时238ms,硬件CRC用时220ms。   开启编译时间优化后,软件算法用时159ms,硬件CRC用时186ms......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>