0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ANSIC几种特殊的标准定义 (__FILE__、__LINE__、__STDC__···)

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-20 09:46 次阅读

Ⅰ写在前面

为方便大家阅读,本文内容已经整理成PDF文件:

http://pan.baidu.com/s/1gfHygyn

对于我们大部分使用单片机进行裸机开发的朋友来说,可能很少有人在程序中许多关键的地方打印一些关键信息

有较大系统开发,或复杂系统开发经验的朋友一般都会在程序中输出很多调试信息,如在UCOSfreeRTOSLinux等系统开发调试时打印许多关键信息。

1.我们在使用STM32库开发时,在stm32fxxx_conf.h文件下会发现如下这么一条语句:

#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))

这条语句,对于使用寄存器,开发简单且不大程序的朋友而言,可能他觉得用处不大,它可能就觉得很占资源,且耗时。

其实不然,ST这么设计是有他一定的道理的,对于开发大型、复杂系统的朋友而言,这条语句其实用处很大。每次,程序运行错误之后,它会打印程序代码指定的位置,方便我们在庞大的程序中很快找到错误的位置。

2.我们的系统会随着时间的推移,不断升级更新,也就是需要提交很多版本的可执行文件(hex、bin等)。但是,产品后期使用中,我们对某些设备进行了升级,可能忽略了一些设备,也就是有些设备没有升级,如果出现故障,我们怎样才能很快找到是哪一个版本的软件出现故障呢?

这里就需要我们在程序中添加一些关于版本的信息,我们最基础的就是Vx.x.x.x等这种信息,但对于大型系统而言,这种信息是不够的,还需要更多,比如:编译日期,时间,编译环境的版本等。

Ⅱ几种特殊标准定义

上面说了这么多,就是需要让大家知道,这些特殊标准定义的用途。上面说的只是简单的举例,其实他们的用途还很广泛,掌握了基础之后相信你们都会知道它们更多比较实用的意义。言归正传,下面讲述这些基础的知识。

本文主要讲述下面几个标准定义:

__LINE__:正在编译文件的行号

__FILE__:正在编译文件的文件名

__DATE__:编译时刻的日期字符串 如“Jun 17 2017”

__TIME__:编译时刻的时间字符串 如”1000“

__STDC__:判断该文件是不是标准C程序

1.__FILE__编译文件名称

File中文意思即文件,这里的意思主要是指:正在编译文件对应正在编译文件的路径和文件的名称。

Keil版本对应的路径是相对于工程文件而言的路径,IAR版本路径是相对Windows路径。

比如下面提供源代码工程:

char BuildFile[] = __FILE__;

printf("编译文件路径:%s\n", BuildFile);

Keil:

编译文件路径:App\main.c

IAR:

编译文件路径:C:\Users\Administrator\Desktop\STM32F417ZG(IAR)_ANSIC几种特殊的标准定义\App\main.c

2.__LINE__编译文件行号

上面说的是编译的文件名,是一个字符串,而这里说的是行号,是一个整型变量,这是这两者的区别,所以在我提供工程中可以看到的源代码:

char BuildLine = __LINE__;

printf("编译代码所在行:%d\n", BuildLine);

可以看不是数组的字符串,打印信息:

编译代码所在行:44

一般情况下,__FILE__是和__LINE__结合一起使用,用于打印我们代码信息,方便快速定位代码位置。

3.__DATE__编译日期

__DATE__日期,需要注意的是:这个日期是你在编译时Windows系统的日期,如果对应那部分代码之前编译好了,后面没有编译,这个日期还是之前的日期,而不是后面编译的日期。因此,如果这里用于定版本,就需要在定版本时对工程进行全部重新编译,它才会更新至你最后编译的日期。

代码:

char BuildDate[] = __DATE__;

printf("编译日期:%s\n", BuildDate);

输出结果:

编译日期:Jun 17 2017

4.__TIME__编译时间

这个和__DATE__一样的原理,编译时的时间,也是一个字符串。

再次提醒:用于定版本:需要重新编译,这样才是最后一次编译时间。

代码:

char BuildTime[] = __TIME__;

printf("编译时间:%s\n", BuildTime);

输出结果

编译时间:1115

5.__STDC__标准C代码

这个标准在我们单片机及嵌入式编程中运用的比较少,当要求程序严格遵循ANSIC标准时该标识符被赋值为1,主要是判断我们的程序文件是不是标准C程序。

#ifdef __STDC__

printf("标准C代码文件\n");

#else

printf("非标准C代码文件\n");

#endif

Ⅲ源代码分析与下载

为了方便大家学习,本文提供的源代码比较基础和简单,也方便理论结合实际学习,仅供参考。

我们在之前新建好的Demo工程上添加了如下部分代码:

char BuildLine = __LINE__;

char BuildFile[] = __FILE__;

char BuildDate[] = __DATE__;

char BuildTime[] = __TIME__;

printf("编译文件路径:%s\n", BuildFile);

printf("编译代码所在行:%d\n", BuildLine);

printf("编译日期:%s\n", BuildDate);

printf("编译时间:%s\n", BuildTime);

#ifdef __STDC__

printf("标准C代码文件\n");

#else

printf("非标准C代码文件\n");

#endif

Keil版本输出结果:

编译文件路径:App\main.c

编译代码所在行:44

编译日期:Jun 17 2017

编译时间:1115

标准C代码文件

IAR版本输出结果:

编译文件路径:C:\Users\Administrator\Desktop\STM32F417ZG(IAR)_ANSIC几种特殊的标准定义\App\main.c

编译代码所在行:44

编译日期:Jun 17 2017

编译时间:1100

标准C代码文件

源代码工程(STM32F417ZG_ANSIC几种特殊的标准定义)下载地址:

http://pan.baidu.com/s/1hskScba

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6036

    文章

    44553

    浏览量

    634772
  • 寄存器
    +关注

    关注

    31

    文章

    5336

    浏览量

    120261
  • ANSIC
    +关注

    关注

    0

    文章

    6

    浏览量

    8679
收藏 人收藏

    评论

    相关推荐

    TLV320AIC3106要是LINE IN ,LINE OUT都只用单通道,电路怎么处理?

    大家好,我在使用TLV320AIC3106实现语音对讲功能时,有点疑惑,芯片有LINE1L+,LINE1R+,EVM上面是这两个都是用了,我现在只想用一个通道,问题是不知道是选LINE1L+呢还是
    发表于 10-25 08:01

    室内精准定位的应用范围?室内精准定位的方式有哪些

    什么是室内精准定位?简单来讲就是根据定位功能,实现室内详细的布局,然后利用这一功能去确定到精准的位置。随着我国科技水平的发展迅猛,定位系统也从曾经初级的简单定位发展到了如今的精准定位,取得了重大
    的头像 发表于 07-11 11:52 424次阅读
    室内精<b class='flag-5'>准定</b>位的应用范围?室内精<b class='flag-5'>准定</b>位的方式有哪些

    室内精准定位是什么?室内精准定位的方式有哪些?

    说到室内精准定位很多人可能会比较陌生,因为这一说法并没有大范围推广,又或者说只是很多相关行业的人才知道这样的说法。但是定位这一问题大家都知道吧?尤其是要到一个地方去,都会进行定位导航。那么这一般都是
    的头像 发表于 07-09 16:30 495次阅读

    app \"espsoftap\"如何使用自定义数据?

    ;esp_prov.py\", line 440, inif not custom_data(obj_transport, obj_security, args.custom_data):File
    发表于 06-24 07:57

    网络跳线的标准有哪几种

    网络跳线的标准主要有以下几种: 双绞线标准:双绞线分为屏蔽双绞线(STP)和非屏蔽双绞线(UTP)两种类型。其中,Cat5e是最基本的双绞线标准,而Cat6、Cat6a、Cat7和Ca
    的头像 发表于 06-14 10:42 934次阅读

    stm32h745的特殊引脚如何使用HAL库重定义

    现在手上有块stm32h745ii的板子,想把pc13 pc14 pc15三个特殊引脚重定义为普通io口,找了一下HAL库,好像没有f4库里面能直接调用的接口,有知道的大神麻烦告知一下该如何操作
    发表于 05-24 08:31

    请问CAN数据域的数据格式该如何定义?以什么标准定义

    最近需要实现上位机与下位机的CAN通讯,现在双方苦于不知该如何定义数据格式,尤其是传输浮点数据~~ 起初经过讨论直接根据个人主观意愿定义了双方的数据协议,,,其后,boss要求采用标准进行定义
    发表于 05-09 07:20

    MC SDK5.0导致电机运行时驱动管发热严重,定时器deadtime设置为0怎么解决?

    ) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } 我的修改方法是main.c中包含头文件parameters_conversion.h
    发表于 04-29 08:43

    如何用cubemx做lin通信?

    ; if (HAL_LIN_Init( huart3, UART_LINBREAKDETECTLENGTH_11B) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } }
    发表于 04-26 07:44

    STM32H743 UART DMA数据发送报错的原因?

    = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init( huart4) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } void
    发表于 04-26 06:59

    虚拟串口与STM32通信遇到的疑问求解

    ; if (HAL_RCC_ClockConfig( RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__
    发表于 04-24 08:29

    主循环里不断开启关闭ADC的DMA传输功能,上电有几率死机怎么解决?

    ; if (HAL_ADC_ConfigChannel( hadc1,sConfig) != HAL_OK) _Error_Handler(__FILE__, __LINE__); for(i = 0; i &
    发表于 04-23 07:20

    STM32F0 ADC多通道单次转换,最后一个通道的EOC不置位是为什么?

    = ADC_OVR_DATA_PRESERVED; if (HAL_ADC_Init( hadc) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } sConfig.Channel
    发表于 04-16 06:34

    STM32F103VET6使用定时器DMA做比较输出PWM,输出波形第一次不正确是怎么回事?

    ) { Error_Handler(__FILE__, __LINE__); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL
    发表于 03-28 07:27

    请问STM32G071如何通过DWT实现us精准定时?

    STM32G071怎样通过DWT实现us精准定时?,各位大佬有实现的吗?
    发表于 03-20 06:59