聊聊预编译#Error的使用,你学会了吗?

开发 前端
相信大家也看出来了,这样管理参数地址,就显得很合理,不会想增加一个参数时,不知道哪个扇区是空闲的,找到了一个扇区,还是担心受怕,害怕和别的参数存储地址冲突将其覆盖。

​引言

说到预编译,大家立刻就能想到#define、#if、#ifdef和#ifndef等熟悉的预编译命令。其实#include,我们通常放在源文件用来包含头文件,它也是预编译命令。当然这不是这篇文章的重点。

这篇文章主要讲解下#error预编译命令,对于什么是预编译,预编译的作用等基础知识点不再讲解,不懂的同学请自行百度。

在MCU的开发中,我们经常需要用到Flash存储一些参数,且通常情况下有很多参数需要存储。

一般采用一个扇区存储一种类型的参数(可能造成Flash空间浪费),但对于一些内部Flash容量很大的MCU,这样做也是可行的。

示例demo如下:

#define PARA_BATTERY_ADDR   0x08019000  //存储电池参数#define PARA_ETH_ADDR    0x0801B800  //存储网络参数..........#define PARA_USER_CONFIG_ADDR 0x0801C400 //存储用户参数

很多开发工程师喜欢这样做,如果参数少时还好,当有很多参数时,这将是一个噩梦。如果这些参数分散在各个文件中,阅读这份源码将是恶心他妈给恶心开门,恶心到家了。

当想增加一个参数存储时,如果不很熟悉代码,根本不知道哪个扇区是空闲的。

优化版本如下,将这这些宏定义统一定义在flashmap.h中。

#define PARA_STARADDR (0x08000+(100*1024))  //前100K用于存储固件,参数存储开始地址。#define FLASH_SECTOR_SIZE (2*1024)  //Flash每个扇区的大小
#define PARA_BATTERY_ADDR PARA_STARADDR //存储电池参数#define PARA_BATTERY_SIZE (1*FLASH_SECTOR_SIZE) //电池参数所占空间大小
#define PARA_ETH_ADDR (PARA_BATTERY_ADDR+PARA_BATTERY_SIZE) //存储网络参数#define PARA_ETH_SIZE (2*FLASH_SECTOR_SIZE) //网络参数所占空间大小

相信大家也看出来了,这样管理参数地址,就显得很合理,不会想增加一个参数时,不知道哪个扇区是空闲的,找到了一个扇区,还是担心受怕,害怕和别的参数存储地址冲突将其覆盖。

当然它也有弊端,如果问你PARA_ETH_ADDR存储地址,并不能立刻从代码中看出,这个问题,我一般使用printf打印出来。

还有个问题,如果加了很多参数,最后一个参数地址大于Flash空间怎么办,或者软件设计一段Flash空间作为参数区,不被允许超过这个地址。

在这个代码结构中,无法从代码中直接获取,有不行使用printf肉眼判断,那么可以使用#error 解决这个问题。

#error

#error 是一种预编译器指示字,用于生成一个编译错误消息 。

用法:#error [message] //message为用户自定义的错误提示信息,可缺省。

#error 可用于提示编译条件是否满足。编译过程中的任何错误意味着无法生成最终的可执行程序。

上面的程序优化为

#define PARA_STARADDR (0x08000+(100*1024))  //前100K用于存储固件,参数存储开始地址。#define FLASH_SECTOR_SIZE (2*1024)  //Flash每个扇区的大小
#define PARA_BATTERY_ADDR PARA_STARADDR //存储电池参数#define PARA_BATTERY_SIZE (1*FLASH_SECTOR_SIZE) //电池参数所占空间大小
#define PARA_ETH_ADDR (PARA_BATTERY_ADDR+PARA_BATTERY_SIZE) //存储网络参数#define PARA_ETH_SIZE (2*FLASH_SECTOR_SIZE) //网络参数所占空间大小
#define PARA_END_ADDR (PARA_ETH_ADDR+PARA_ETH_SIZE)// 参数的结束地址#if #error#endif

这样当你的参数最后地址大于0x0801E000,编译器机会报错,根本编译不过,如下图

图片

类似的,#warning 用于生成编译警告消息。warning可用来提示一些非致命错误。

其他用法

限定宏定义的数值范围,下面SIZE被限制在0到100内。

#define#if SIZE < 0 || SIZE > 100#error#endifuint8_t buffer[SIZE];

指定使用VS编译器

#ifndef#error#endif

判断是否定义了某个宏,比如FreeRTOS源码中

#ifndef configMINIMAL_STACK_SIZE    #error Missing definition:  configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h.  configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task.  Refer to the demo project provided for your port for a suitable value.#endif

责任编辑:武晓燕 来源: 知晓编程
相关推荐

2024-08-19 10:24:14

2022-03-05 23:29:18

LibuvwatchdogNode.js

2024-03-05 10:09:16

restfulHTTPAPI

2022-12-26 07:48:04

敏捷项目

2024-06-12 08:36:25

2023-01-29 08:08:34

并发库conc通用库

2023-07-10 08:36:21

工具pptword

2024-02-02 11:03:11

React数据Ref

2024-04-29 06:55:34

RustMIDI应用程序

2024-03-04 07:41:18

SpringAOPOOP​

2022-12-27 08:45:00

绘制菜单符号

2022-12-08 10:49:43

2022-09-26 08:49:11

Java架构CPU

2022-04-13 09:01:45

SASSCSS处理器

2022-07-11 09:00:37

依赖配置文件Mybati

2023-06-05 08:36:04

SQL函数RANK()

2023-03-07 07:50:15

Transactio事务代码

2024-11-08 08:56:01

2023-12-05 17:57:13

nginx参数

2022-10-11 08:48:08

HTTP状态码浏览器
点赞
收藏

51CTO技术栈公众号