搜索
bottom↓
回复: 78

程序中添加自动更新的编译时间

  [复制链接]

出0入0汤圆

发表于 2016-8-19 13:46:14 | 显示全部楼层 |阅读模式
本帖最后由 铁驴不倒! 于 2016-8-19 16:54 编辑

由于经常拿不同版本的程序烧到设备中去测试,又没有什么合适的地方标注软件版本号,因此将代码版本加入代码中就十分必要了,这样就可以通过设备查看到代码版本从而方便问题的定位。
本来想用SVN版本号来着,结果我用的tortoiseSVN没有SVN命令行,就用编译时间了,也不错。

1.程序启动的时候串口打印编译时间
  1.   
  2. #define PRINTER_COMPLIE_TIME __DATE__ " " __TIME__
  3.   ....
  4.   DBGSTR( DBG_N "Complie Time     : " PRINTER_COMPLIE_TIME DBG_N);
复制代码


2.上面的代码写在main.c里,要想让它每次编译都更新,需在build时强制其重新编译。强制重新编译,请参照14楼提供的方法!


OK,这样每次build都会重新重编main.c,设备启动的时候都会显示软件编译时间了~

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2016-8-19 13:52:02 来自手机 | 显示全部楼层
方法不错,学习了

出0入0汤圆

发表于 2016-8-19 14:18:53 | 显示全部楼层
赞一个,非常试用的方法

出0入0汤圆

发表于 2016-8-19 14:20:39 来自手机 | 显示全部楼层
不删除.o也会更新编译时间。

出0入90汤圆

发表于 2016-8-19 14:24:11 | 显示全部楼层
有没有办法指定编译时间到HEX或者BIN文件的具体位置呢?

出0入0汤圆

 楼主| 发表于 2016-8-19 14:46:50 | 显示全部楼层
waterghost 发表于 2016-8-19 14:20
不删除.o也会更新编译时间。

不删除.o的情况下如果.c文件没修改,Build的时候是不会重新编译的,.o直接链接了,那.o里就是上一次编译的时间啦

出0入0汤圆

 楼主| 发表于 2016-8-19 14:54:18 | 显示全部楼层
honami520 发表于 2016-8-19 14:24
有没有办法指定编译时间到HEX或者BIN文件的具体位置呢?

想了一下,没想出什么办法。。。
这个需求是怎么来的呢?

出0入0汤圆

发表于 2016-8-19 15:08:01 | 显示全部楼层
honami520 发表于 2016-8-19 14:24
有没有办法指定编译时间到HEX或者BIN文件的具体位置呢?
  1. const char DataTime[] __attribute__((at(0x10000))) = __DATE__ __TIME__ ; /* RO */
复制代码





  1.     __RL_RTX_VER                             0x00000481   Number         0  rt_system.o ABSOLUTE
  2.     DataTime                                 0x00010000   Data          20  rtx_blinky.o(.ARM.__AT_0x00010000)
  3.     __Vectors                                0x08000000   Data           4  startup_stm32f030x8.o(RESET)
  4.     __Vectors_End                            0x080000b4   Data           0  startup_stm32f030x8.o(RESET)
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-19 15:08:49 | 显示全部楼层
铁驴不倒! 发表于 2016-8-19 14:54
想了一下,没想出什么办法。。。
这个需求是怎么来的呢?

做个exe能实现, 批处理也行, 就是处理时间日期转换成hex麻烦点

我做过个exe实现的功能之一有这个

出0入0汤圆

发表于 2016-8-19 15:11:03 | 显示全部楼层
  1. 9.60 __attribute__((at(address))) variable attribute
  2. This variable attribute enables you to specify the absolute address of a variable.

  3. Syntax

  4. __attribute__((at(address)))
  5. Where:
  6. address
  7. is the desired address of the variable.
  8. Usage
  9. The variable is placed in its own section, and the section containing the variable is given an appropriate type by the compiler:
  10. Read-only variables are placed in a section of type RO.
  11. Initialized read-write variables are placed in a section of type RW.
  12. Variables explicitly initialized to zero are placed in:
  13. A section of type ZI in RVCT 4.0 and later.
  14. A section of type RW (not ZI) in RVCT 3.1 and earlier. Such variables are not candidates for the ZI-to-RW optimization of the compiler.
  15. Uninitialized variables are placed in a section of type ZI.
  16. Note

  17. GNU compilers do not support this variable attribute.
  18. Restrictions
  19. The linker is not always able to place sections produced by the at variable attribute.
  20. The compiler faults use of the at attribute when it is used on declarations with incomplete types.
  21. Errors
  22. The linker gives an error message if it is not possible to place a section at a specified address.
  23. Example
  24. const int x1 __attribute__((at(0x10000))) = 10; /* RO */
  25. int x2 __attribute__((at(0x12000))) = 10; /* RW */
  26. int x3 __attribute__((at(0x14000))) = 0; /* RVCT 3.1 and earlier: RW.
  27.                                           * RVCT 4.0 and later: ZI. */
  28. int x4 __attribute__((at(0x16000))); /* ZI */
  29. Related information

  30. Placement of __at sections at a specific address
复制代码

出0入0汤圆

发表于 2016-8-19 15:19:00 | 显示全部楼层
IAR EWARM

  1. #pragma location=0x08001000
  2. __root const char DataTime[] = __DATE__ __TIME__;
复制代码



  1. DataTime                0x08001000   0x14  Data  Gb  main.o [1]
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-19 15:20:02 | 显示全部楼层
#pragma location


Syntax

#pragma location={address|register|NAME}


Parameters

Description Use this pragma directive to specify:

address The absolute address of the global or static variable or function for which you want an absolute location.

register An identifier that corresponds to one of the ARM core registers R4–R11.

NAME A user-defined section name; cannot be a section name predefined for use by the compiler and linker.

Description

Use this pragma directive to specify:

The location—the absolute address—of the global or static variable whose declaration follows the pragma directive.

The variables must be declared __no_init.



An identifier specifying a register. The variable defined after the pragma directive is placed in the register.

The variable must be declared as __no_init and have file scope.


A string specifying a section for placing either a variable or function whose declaration follows the pragma directive.

Do not place variables that would normally be in different sections

(for example, variables declared as __no_init and variables declared as const) in the same named section.

  1. #pragma location=0xFFFF0400
  2. __no_init volatile char PORT1;
  3. /* PORT1 is located at address 0xFFFF0400 */

  4. #pragma location=R8
  5. __no_init int TASK;
  6. /* TASK is placed in R8 */

  7. #pragma location="FLASH"
  8. char PORT2;
  9. /* PORT2 is located in section FLASH */

  10. /* A better way is to use a corresponding mechanism */
  11. #define FLASH _Pragma("location="FLASH"")
  12. FLASH int i; /* i is placed in the FLASH section */
复制代码

出0入0汤圆

发表于 2016-8-19 15:21:55 | 显示全部楼层
学习了,这个很有用,谢谢!

出0入0汤圆

发表于 2016-8-19 15:51:11 | 显示全部楼层
在Keil里面,想要每次都编译a.c文件,只要在a.c文件上右键,选择options for file 'a.c', 把Properties页里面的Always Build前的勾,勾成黑色就行了,不管有没有修改这个文件,每次编译都会编译这个文件的。

出0入0汤圆

发表于 2016-8-19 15:56:38 | 显示全部楼层
有那位大神愿意讲解一下。
表示看不懂。

出0入90汤圆

发表于 2016-8-19 16:22:38 | 显示全部楼层

牛逼,竟然真的有方法,学习了,多谢告知

出0入0汤圆

 楼主| 发表于 2016-8-19 16:48:02 | 显示全部楼层


这个方法需要想办法给它分配出一个FLASH上的空间,而代码和数据可能占用那个空间,所以并不能随意指定它保存的位置。
据手册上看,FLASH启动的时候0x0000-0x0007 FFFF应该是FLASH的别名,0x1 0000也就应该是指向了0x0801 0000,那么就有可能覆盖FLASH中的代码或数据或者被覆盖呀!
层主如何解决这个问题呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2016-8-19 16:50:06 | 显示全部楼层
落叶随风 发表于 2016-8-19 15:51
在Keil里面,想要每次都编译a.c文件,只要在a.c文件上右键,选择options for file 'a.c', 把Properties页 ...

KEIL有这个功能啊 NICE
我就是没找到这功能
学习了!

出0入0汤圆

发表于 2016-8-19 16:56:18 | 显示全部楼层
铁驴不倒! 发表于 2016-8-19 16:48
这个方法需要想办法给它分配出一个FLASH上的空间,而代码和数据可能占用那个空间,所以并不能随意指定它 ...

用at指定地址,如果有冲突的话,编译器会报错的,要是我没记错的话。

另外可以用scatter文件,然后指定section,这样就不用去指定地址了,编译器会在这个section里自动分配,比较方便。

出0入0汤圆

发表于 2016-8-19 16:57:19 | 显示全部楼层
铁驴不倒! 发表于 2016-8-19 16:48
这个方法需要想办法给它分配出一个FLASH上的空间,而代码和数据可能占用那个空间,所以并不能随意指定它 ...

只是随意指定了一个地址用于演示。
你可以根据情况指定地址,这个地址编译器会自动跳过的。

出0入0汤圆

发表于 2016-8-19 16:58:13 | 显示全部楼层
落叶随风 发表于 2016-8-19 16:56
用at指定地址,如果有冲突的话,编译器会报错的,要是我没记错的话。

另外可以用scatter文件,然后指定s ...

是的,可以通过配置文件来指定,EWARM也有此功能。

出0入22汤圆

发表于 2016-8-19 20:48:58 来自手机 | 显示全部楼层
我通常是定义一个常量,然后生成bin,自己再写个exe搜索那个常量来进行修改。

出0入4汤圆

发表于 2016-8-20 23:47:26 | 显示全部楼层
落叶随风 发表于 2016-8-19 15:51
在Keil里面,想要每次都编译a.c文件,只要在a.c文件上右键,选择options for file 'a.c', 把Properties页 ...

不知道您是否知道在IAR下如何强制编译一个.c文件? 一直不知道如何设置。

出0入0汤圆

发表于 2016-8-21 00:43:19 | 显示全部楼层
都是好办法,mark

出0入0汤圆

发表于 2016-8-21 10:15:16 | 显示全部楼层
不错,要是把生成的日期能自动成20160810这样子的就更好了。我是在程序中加了一个月份的转换,感觉麻烦。在STC项目中,用了DATA1,就是这种日期。但在STM中好像不能用。

出0入0汤圆

发表于 2016-8-21 17:42:33 | 显示全部楼层
huchunlei 发表于 2016-8-20 23:47
不知道您是否知道在IAR下如何强制编译一个.c文件? 一直不知道如何设置。 ...

如果有任何.c文件变化的情况下,可以做到强制编译另外一个 .c文件, 即使这个文件没有改动。

  1. cmd /c "del "$OBJ_DIR$\datetime.o""
复制代码


如果没有任何.c文件变化的情况下, 不知道怎样设置才可以做到。

只有通过Rebuild All来强制重新编译所有文件吗?


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-21 17:44:56 | 显示全部楼层
dulala 发表于 2016-8-21 10:15
不错,要是把生成的日期能自动成20160810这样子的就更好了。我是在程序中加了一个月份的转换,感觉麻烦。在 ...

datetime.h

  1. #ifndef __DATE_TIME__H__
  2. #define __DATE_TIME__H__

  3. // __DATE__
  4. // Aug 31 2016#0
  5. // 0123456789A
  6. //
  7. // Aug 31 2016
  8. //        789A
  9. #define __DATE_YEAR_VAL__             \
  10. ( ( ( ( __DATE__  [7] - '0' )   * 10  \
  11.     + ( __DATE__  [8] - '0' ) ) * 10  \
  12.     + ( __DATE__  [9] - '0' ) ) * 10  \
  13.     + ( __DATE__ [10] - '0' ) )

  14. //
  15. // const char * months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  16. //
  17. // Aug 31 2016
  18. // 012
  19. // 1   2   3   4   5   6   7   8   9   10  11  12
  20. // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
  21. //   *       ^   ^       *
  22. //
  23. #define __DATE_MONTH_VAL__            \
  24. ( __DATE__ [2] == 'n' ? ( __DATE__ [1] == 'a' ? 1 : 6 ) \
  25. : __DATE__ [2] == 'b' ? 2                               \
  26. : __DATE__ [2] == 'r' ? ( __DATE__ [0] == 'M' ? 3 : 4)  \
  27. : __DATE__ [2] == 'y' ? 5             \
  28. : __DATE__ [2] == 'l' ? 7             \
  29. : __DATE__ [2] == 'g' ? 8             \
  30. : __DATE__ [2] == 'p' ? 9             \
  31. : __DATE__ [2] == 't' ? 10            \
  32. : __DATE__ [2] == 'v' ? 11 : 12 )

  33. // Aug 31 2016
  34. //     45
  35. #define __DATE_DAY_VAL__              \
  36. ( ( __DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 + (__DATE__ [5] - '0') )


  37. #define BCD_DIGIT(digit) "0123456789"[ ( digit ) ]

  38. #define __DATE_MONTH_HI_VAL__         ( __DATE_MONTH_VAL__ / 10  )
  39. #define __DATE_MONTH_LO_VAL__         ( __DATE_MONTH_VAL__ % 10 )

  40. #define __DATE_DAY_HI_VAL__           ( __DATE_DAY_VAL__ / 10  )
  41. #define __DATE_DAY_LO_VAL__           ( __DATE_DAY_VAL__ % 10 )

  42. #define __DATE_YEAR_0_VAL__           ( __DATE_YEAR_VAL__ / 1000 )
  43. #define __DATE_YEAR_1_VAL__           ( __DATE_YEAR_VAL__ / 100 )
  44. #define __DATE_YEAR_2_VAL__           ( __DATE_YEAR_VAL__ / 10 )
  45. #define __DATE_YEAR_3_VAL__           ( __DATE_YEAR_VAL__ % 10 )

  46. // Aug 31 2016
  47. //        789A
  48. #define __DATE_YEAR_CH0__             BCD_DIGIT( ( __DATE__[ 7] - 0x30 ) )
  49. #define __DATE_YEAR_CH1__             BCD_DIGIT( ( __DATE__[ 8] - 0x30 ) )
  50. #define __DATE_YEAR_CH2__             BCD_DIGIT( ( __DATE__[ 9] - 0x30 ) )
  51. #define __DATE_YEAR_CH3__             BCD_DIGIT( ( __DATE__[10] - 0x30 ) )

  52. #define __DATE_YEAR_STR__             \
  53.   __DATE_YEAR_CH0__, __DATE_YEAR_CH1__, __DATE_YEAR_CH2__, __DATE_YEAR_CH3__

  54. #define __DATE_MONTH_CH0__            BCD_DIGIT(  __DATE_MONTH_HI_VAL__  )
  55. #define __DATE_MONTH_CH1__            BCD_DIGIT(  __DATE_MONTH_LO_VAL__  )

  56. #define __DATE_MONTH_STR__            \
  57.   __DATE_MONTH_CH0__, __DATE_MONTH_CH1__

  58. #define __DATE_DAY_CH0__              BCD_DIGIT(  __DATE_DAY_HI_VAL__  )
  59. #define __DATE_DAY_CH1__              BCD_DIGIT(  __DATE_DAY_LO_VAL__  )

  60. #define __DATE_DAY_STR__              \
  61.   __DATE_DAY_CH0__, __DATE_DAY_CH1__

  62. #define __DATE_YEAR_MONTH_DAY_STR__   \
  63.   __DATE_YEAR_STR__, __DATE_MONTH_STR__, __DATE_DAY_STR__

  64. // __TIME__
  65. // 23:59:59#0
  66. // 01234567
  67. //
  68. #define __TIME_HOUR_VAL__             \
  69.   ( ( __TIME__  [0] - '0' )   * 10    \
  70.   + ( __TIME__  [1] - '0' ) )

  71. #define __TIME_MIN_VAL__              \
  72.   ( ( __TIME__  [3] - '0' )   * 10    \
  73.   + ( __TIME__  [4] - '0' ) )

  74. #define __TIME_SEC_VAL__              \
  75.   ( ( __TIME__  [6] - '0' )   * 10    \
  76.   + ( __TIME__  [7] - '0' ) )


  77. #define __TIME_HOUR_CH0__             BCD_DIGIT(  __TIME_HOUR_VAL__ / 10  )
  78. #define __TIME_HOUR_CH1__             BCD_DIGIT(  __TIME_HOUR_VAL__ % 10  )

  79. #define __TIME_HOUR_STR__             \
  80.   __TIME_HOUR_CH0__, __TIME_HOUR_CH1__

  81. #define __TIME_MIN_CH0__              BCD_DIGIT(  __TIME_MIN_VAL__ / 10  )
  82. #define __TIME_MIN_CH1__              BCD_DIGIT(  __TIME_MIN_VAL__ % 10  )

  83. #define __TIME_MIN_STR__              \
  84.   __TIME_MIN_CH0__, __TIME_MIN_CH1__

  85. #define __TIME_SEC_CH0__              BCD_DIGIT(  __TIME_SEC_VAL__ / 10  )
  86. #define __TIME_SEC_CH1__              BCD_DIGIT(  __TIME_SEC_VAL__ % 10  )

  87. #define __TIME_SEC_STR__              \
  88.   __TIME_SEC_CH0__, __TIME_SEC_CH1__

  89. #define __TIEM_HOUR_MIN_SEC_STR__     \
  90.   __TIME_HOUR_STR__, __TIME_MIN_STR__, __TIME_SEC_STR__

  91. #define __DATE_TIME_STR__             \
  92.   __DATE_YEAR_MONTH_DAY_STR__, __TIEM_HOUR_MIN_SEC_STR__

  93. #endif /* __DATE_TIME__H__ */

复制代码


datetime.c

  1. #include "datetime.h"

  2. __root const char DataTime[] = __DATE__ __TIME__;

  3. __root const int data_year_val = __DATE_YEAR_VAL__;
  4. __root const int data_month_val = __DATE_MONTH_VAL__;
  5. __root const int data_day_val = __DATE_DAY_VAL__;

  6. __root const char date_str[] = { __DATE_YEAR_MONTH_DAY_STR__, 0 };
  7. __root const char time_str[] = { __TIEM_HOUR_MIN_SEC_STR__, 0 };

  8. __root const char date_time_str[] = { __DATE_TIME_STR__, 0 };
复制代码

通过上面的图片设置, 当有任何.c文件变化时,来强制重新编译过 datetime.c

出0入0汤圆

发表于 2016-8-22 08:22:48 | 显示全部楼层
huchunlei 发表于 2016-8-20 23:47
不知道您是否知道在IAR下如何强制编译一个.c文件? 一直不知道如何设置。 ...

实在抱歉,我没用过IAR,不知道怎么设置,帮不了您。

出0入0汤圆

 楼主| 发表于 2016-8-22 08:23:55 | 显示全部楼层

请问这段是从哪个手册里 怎么找到的呢?

出0入0汤圆

 楼主| 发表于 2016-8-22 08:25:41 | 显示全部楼层

这个datetime模块 是自己写的~?

出0入0汤圆

 楼主| 发表于 2016-8-22 08:32:54 | 显示全部楼层

__root const char DataTime[] = __DATE__ __TIME__;
这个__root是什么意思?是自己写的?

出0入0汤圆

发表于 2016-8-22 08:43:43 | 显示全部楼层
牛人呀,学习了的

出0入0汤圆

发表于 2016-8-22 09:34:10 | 显示全部楼层
铁驴不倒! 发表于 2016-8-22 08:25
这个datetime模块 是自己写的~?

先搜索然后编码。

出0入0汤圆

发表于 2016-8-22 09:35:44 | 显示全部楼层
铁驴不倒! 发表于 2016-8-22 08:32
__root const char DataTime[] = __DATE__ __TIME__;
这个__root是什么意思?是自己写的? ...

__root 即使没有使用这个变量,也会在生产的文件中包含此变量。

__root
The __root attribute can be used on either a function or a variable to ensure that, when the module containing the function or variable is linked, the function or variable is also included, whether or not it is referenced by the rest of the program.

By default only the part of the runtime library calling main and any interrupt vectors are root. All other functions and variables are included in the linked output only if they are referenced by the rest of the program.

The __root keyword is placed in front of the type, for example to place settings in non-volatile memory:

__root int settings[10];

The #pragma object_attribute directive can also be used. The following declaration is equivalent to the previous one:

#pragma object_attribute=__root
int settings[10];

Note: The __root keyword cannot be used in typedefs.

出0入0汤圆

发表于 2016-8-22 09:36:47 | 显示全部楼层
__root 保证没有使用的函数或者变量也能够包含在目标代码中

__root 关键字保证没有使用的函数或者变量也能够包含在目标代码中.
定义存放在__flash 空间的数据在程序编译时会自动生成代码嵌入到flash代码中,对于程序没有使用也要求编译的数据(比如可以在代码中嵌入你的版本号,时间等)必须加关键字__root 限制。


  1. #i nclude<iom8.h>  
  2. __root __flash unsigned char p @ 0x10 =0x56;  
  3. void main(void)  
  4. {  
  5.   
  6. }  
复制代码



程序没有使用P变量,编译也会生成该代码。  
  1. :020000020000FC  
  2. :1000000016C018951895189518951895189518955F  
  3. :10001000569518951895189518951895189518953A  
  4. :10002000189518951895089500008895FECF0FE94A  
  5. :100030000DBF00E00EBFC0E8D0E003D0F4DFF4DF76  
  6. :06004000F3CF01E008957A  
  7. :0400000300000000F9  
  8. :00000001FF
复制代码

出0入0汤圆

发表于 2016-8-22 09:44:13 | 显示全部楼层
有用,多谢。看来都对编译器很熟悉

出0入0汤圆

发表于 2016-8-22 10:04:27 | 显示全部楼层
真心不错,这个要对使用的编译器很了解才能用

出0入0汤圆

发表于 2016-8-22 11:22:33 | 显示全部楼层
honami520 发表于 2016-8-19 14:24
有没有办法指定编译时间到HEX或者BIN文件的具体位置呢?

可以,赋值直接操作即可

  1.     switch(__DATE__[0])//月份转换
  2.     {
  3.         case 'J':
  4.         {
  5.             if((__DATE__[1] == 'a') && (__DATE__[2] == 'n')) memcpy(&date[4], "01", 2);//01月
  6.             else if((__DATE__[1] == 'u') && (__DATE__[2] == 'n')) memcpy(&date[4], "06", 2);//06月
  7.             else if((__DATE__[1] == 'u') && (__DATE__[2] == 'l')) memcpy(&date[4], "07", 2);//07月
  8.         }break;
  9.         
  10.         case 'F':
  11.         {
  12.             memcpy(&date[4], "02", 2);//02月
  13.         }break;
  14.         
  15.         case 'M':
  16.         {
  17.             if((__DATE__[1] == 'a') && (__DATE__[2] == 'r')) memcpy(&date[4], "03", 2);//03月
  18.             else if((__DATE__[1] == 'a') && (__DATE__[2] == 'y')) memcpy(&date[4], "05", 2);//05月            
  19.         }break;
  20.         
  21.         case 'A':
  22.         {
  23.             if((__DATE__[1] == 'p') && (__DATE__[2] == 'r')) memcpy(&date[4], "04", 2);//04月
  24.             else if((__DATE__[1] == 'u') && (__DATE__[2] == 'g')) memcpy(&date[4], "08", 2);//08月              
  25.         }break;
  26.         
  27.         case 'S':
  28.         {
  29.             memcpy(&date[4], "09", 2);//09月
  30.         }break;
  31.         
  32.         case 'O':
  33.         {
  34.             memcpy(&date[4], "10", 2);//10月
  35.         }break;
  36.         
  37.         case 'N':
  38.         {
  39.             memcpy(&date[4], "11", 2);//11月
  40.         }break;
  41.         
  42.         case 'D':
  43.         {
  44.             memcpy(&date[4], "12", 2);//12月
  45.         }break;
  46.             
  47.         default: break;
  48.     }
  49.    
  50.     //日
  51.     if(__DATE__[4] == ' ') date[6] = '0';
  52.     else date[6] = __DATE__[4];

  53.     if(__DATE__[5] == ' ') date[7] = '0';
  54.     else date[7] = __DATE__[5];
复制代码


ps:英文的看着不顺眼,顺便转换成数字的格式(例:20160822)

出0入0汤圆

发表于 2016-8-22 13:12:42 | 显示全部楼层
程序中添加自动更新的编译时间   mark

出0入0汤圆

发表于 2016-8-22 13:27:50 来自手机 | 显示全部楼层
很有用,收藏了,说不定那天用到

出0入0汤圆

发表于 2016-8-22 15:00:44 | 显示全部楼层
落叶随风 发表于 2016-8-19 15:51
在Keil里面,想要每次都编译a.c文件,只要在a.c文件上右键,选择options for file 'a.c', 把Properties页 ...


这个可以,虽然多一点编译时间,但对放Data文件不大的项目,影响很少

出0入4汤圆

发表于 2016-8-22 21:12:48 | 显示全部楼层
shangdawei 发表于 2016-8-21 17:42
如果有任何.c文件变化的情况下,可以做到强制编译另外一个 .c文件, 即使这个文件没有改动。

非常感谢,看来IAR是没有直接提供这个功能, 但是你这个方法也不错, 实现了功能。   这个问题也困惑我很久了,终于有办法解决了

出0入0汤圆

发表于 2016-8-22 22:43:34 | 显示全部楼层
huchunlei 发表于 2016-8-22 21:12
非常感谢,看来IAR是没有直接提供这个功能, 但是你这个方法也不错, 实现了功能。   这个问题也困惑我很 ...



放到这里效果更好,即使没有文件修改,每一次编译都会重新编译 datetime.c 这个文件.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-22 22:46:06 | 显示全部楼层
这样就实现了类似KEIL的强制编译某个(些)文件的功能,
只需要把需要强制编译的文件对应的*.o在编译之后都删除了,下一次编译自然就会重新编译。

出0入0汤圆

发表于 2016-8-22 22:59:35 | 显示全部楼层
本帖最后由 shangdawei 于 2016-8-22 23:02 编辑

通过使用批处理文件来删除多个文件:

post-build.bat

  1. echo off
  2. cmd /c "del %1\datetime.o"
  3. rem cmd /c "del %1\xxxxxxxx.o"
  4. rem cmd /c "del %1\yyyyyyyy.o"
  5. echo on
复制代码




  1. $PROJ_DIR$\post-build.bat "$OBJ_DIR$"
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-22 23:22:26 | 显示全部楼层
牛人,先搜藏了

出0入0汤圆

发表于 2016-8-23 08:32:10 | 显示全部楼层
学习了,MARK1

出0入0汤圆

发表于 2016-8-23 08:37:18 | 显示全部楼层
MARK..............

出0入0汤圆

发表于 2016-8-23 14:47:14 | 显示全部楼层
我是写了个exe,在.s文件头部定义了一个4字节变量COMPILETIME,在向量表保留区用DCD COMPILETIME

出0入0汤圆

发表于 2016-8-23 22:17:00 | 显示全部楼层
keil可以这样么?

出0入0汤圆

发表于 2016-8-23 22:53:27 | 显示全部楼层

可以直接设置,不用这么麻烦了

http://www.amobbs.com/forum.php? ... 038&pid=9392076

出0入0汤圆

发表于 2016-8-23 23:30:30 | 显示全部楼层
shangdawei 发表于 2016-8-23 22:53
可以直接设置,不用这么麻烦了

http://www.amobbs.com/forum.php?mod=redirect&goto=findpost&ptid=5658 ...

那#define PRINTER_COMPLIE_TIME __DATE__ " " __TIME__ 的原理是什么呢?有人么文档支持么?

出0入0汤圆

发表于 2016-8-24 01:17:57 | 显示全部楼层
kaomantou 发表于 2016-8-23 23:30
那#define PRINTER_COMPLIE_TIME __DATE__ " " __TIME__ 的原理是什么呢?有人么文档支持么? ...

ANSI C标准中有几个标准预定义宏(也是常用的):

__LINE__:在源代码中插入当前源代码行号;
__FILE__:在源文件中插入当前源文件名;
__DATE__:在源文件中插入当前的编译日期
__TIME__:在源文件中插入当前编译时间;
__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;
__cplusplus:当编写C++程序时该标识符被定义

  1. // 演示 __FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__ 的使用

  2. #include "stdio.h"

  3. void testFunc(void){
  4.     printf("File = %s\nLine = %d\nFunc=%s\nDate=%s\nTime=%s\n",
  5.         __FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__);
  6. }

  7. int main(int argc, char* argv[])
  8. {
  9.     testFunc();
  10.     getchar();
  11.     return 0;
  12. }
复制代码


VC2010编译通过,运行结果为:

  1. File = c:\test\test__func__.cpp
  2. Line = 8
  3. Func=testFunc
  4. Date=Sep 7 2012
  5. Time=00:15:42
复制代码

出0入0汤圆

 楼主| 发表于 2016-9-28 16:30:05 | 显示全部楼层
shangdawei 发表于 2016-8-22 09:36
__root 保证没有使用的函数或者变量也能够包含在目标代码中

__root 关键字保证没有使用的函数或者变量也能 ...

多谢回复! 学习了 __root

出0入0汤圆

发表于 2016-9-28 16:58:15 | 显示全部楼层
多谢,楼主、shangdawei分享,

出0入0汤圆

 楼主| 发表于 2016-10-20 09:56:43 | 显示全部楼层
lianglee 发表于 2016-9-28 17:17
为什么不研究下生成的HEX中,自动变以当前时间为文件名来进行命名呢。

我很想做这个。 ...

上面说的是如何将编译时间植入代码中供程序使用。
你的意思是要把编出的目标文件自动重命名吗? 那只要写一个批处理文件在编译完成后自动执行就重命名就行啦

出0入0汤圆

发表于 2016-10-20 16:51:45 来自手机 | 显示全部楼层
这招不错,学习了

出0入0汤圆

发表于 2016-10-20 22:25:00 | 显示全部楼层
学习了,等会试一下

出0入0汤圆

发表于 2016-10-21 16:04:41 | 显示全部楼层
程序中添加自动更新的编译时间   mark

出0入16汤圆

发表于 2016-10-21 16:53:01 | 显示全部楼层
这功能用了十年了。但需要注意的是,这个时间是该代码所在那个源文件的编译时间,不是最终镜像的编译时间。比如你的代码项目有10个C源文件,而这段代码在A文件中,你修改的时候只修改了B文件,编译生产镜像如果不是全部编译一遍则最后镜像中包含的时间信息还是上次的A文件的编译日期和时间。如果你要正确使用这个功能,最好每次生成最终镜像都全部源文件编译一边来生产新的时间信息,或者在这部分代码所在的源文件增删空格促使其被重新编译。

出0入16汤圆

发表于 2016-10-21 16:55:29 | 显示全部楼层
lianglee 发表于 2016-9-28 17:17
为什么不研究下生成的HEX中,自动变以当前时间为文件名来进行命名呢。

我很想做这个。 ...

自己写个批处理程序,添加到编译器的after biuld的动作中去即可。我以前自己写过程序可以把每次编译后的文件自动加密、文件名加时间和校验码。

出0入270汤圆

发表于 2016-10-21 19:17:43 | 显示全部楼层
--keep __NPK_*

出0入0汤圆

发表于 2016-10-21 19:32:20 | 显示全部楼层

学习了,大神人物

出0入0汤圆

发表于 2016-10-21 21:25:20 | 显示全部楼层
mark 时间自动编译

出0入0汤圆

发表于 2016-10-21 23:02:42 | 显示全部楼层
Elex 发表于 2016-10-21 16:53
这功能用了十年了。但需要注意的是,这个时间是该代码所在那个源文件的编译时间,不是最终镜像的编译时间。 ...

有道理,现在的编译器太智能,没有变化的文件不会编译。

出0入0汤圆

发表于 2016-10-21 23:09:56 | 显示全部楼层
很有用.....赞一个!

出0入0汤圆

发表于 2016-10-22 11:07:54 | 显示全部楼层
多谢楼主分享,收藏了。      

出0入8汤圆

发表于 2016-10-22 11:17:22 | 显示全部楼层
yu2008 发表于 2016-10-21 23:02
有道理,现在的编译器太智能,没有变化的文件不会编译。

此种的理想解决方案是:
利用 pre build 来做一些动作,实现指定源码文件的实时构建,而不用每次 rebuild 全部构建。

可以去参考 IDE 的手册,一些 IDE,提供了便捷的命令
或者 自己写脚本去处理。

出0入0汤圆

发表于 2016-10-22 13:44:54 | 显示全部楼层
落叶随风 发表于 2016-8-19 15:51
在Keil里面,想要每次都编译a.c文件,只要在a.c文件上右键,选择options for file 'a.c', 把Properties页 ...

这个好 可以指定每次编译

出0入0汤圆

发表于 2016-10-22 14:50:46 | 显示全部楼层
好方法,顶一个

出0入0汤圆

发表于 2016-10-23 17:06:54 来自手机 | 显示全部楼层
实用,谢谢分享

出0入8汤圆

发表于 2016-10-23 21:48:29 来自手机 | 显示全部楼层
mark.......

出0入0汤圆

发表于 2016-10-23 21:58:33 | 显示全部楼层
这个很有用,谢谢!

出0入0汤圆

发表于 2016-10-23 22:07:01 | 显示全部楼层
高手啊,又学到一招了。

出0入0汤圆

发表于 2016-10-24 08:57:57 来自手机 | 显示全部楼层
很好的教程

出0入0汤圆

发表于 2016-10-24 16:46:23 | 显示全部楼层
编译器里面有好多关键字,比如IAR,就像上面大神@shangdawei所说,受教了,像你学习...

出0入0汤圆

发表于 2016-10-24 16:59:18 | 显示全部楼层
好贴。。。。 学习了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 04:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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