首页 > 其他分享 >预编译#error的使用

预编译#error的使用

时间:2022-12-17 12:12:00浏览次数:57  
标签:ADDR PARA error 编译 参数 使用 define SIZE

1、引言

说到预编译,大家立刻就能想到#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 解决这个问题。

2、#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 (PARA_END_ADDR > 0x0801E000)
    #error Flash Map Error
#endif

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

 

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

3、其他用法

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

#define SIZE 10
#if SIZE < 0 || SIZE > 100
#error SIZE must be between 1 and 100.
#endif
uint8_t buffer[SIZE];

指定使用VS编译器.

#ifndef _MSC_VER
#error require visual studio compiler
#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

 

点击查看:C语言进阶专辑

标签:ADDR,PARA,error,编译,参数,使用,define,SIZE
From: https://www.cnblogs.com/Fireflycjd/p/16988695.html

相关文章

  • 爱加密iOS混淆工具 ijiami-clang-tools 使用
    获取联系爱加密支持人员,他们会发给你最新的爱加密工具包ijiami-clang-tools。安装首先获取要安装机器的UUID和en0的MAC地址,将这两个信息发送给爱加密人员,爱加密会根据机......
  • 使用PyTorch进行知识蒸馏的代码示例
    随着机器学习模型的复杂性和能力不断增加。提高大型复杂模型在小数据集性能的一种有效技术是知识蒸馏,它包括训练一个更小、更有效的模型来模仿一个更大的“教师”模型的行......
  • 08 回文质数 -Linux环境下的编译执行
    打开终端(terminal)输入cdm//打开m文件输入touchmain.cpp//新建main.cpp文件输入vimmain.cpp//使用vim来编写代码编写完毕后输入:wq//保存并退出输入g++main......
  • Matlab遗传算法工具箱的使用及实例(线性规划)
    ✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。......
  • VSCode编辑器极简使用入门
    VSCode(VisualStudioCode)是一款开源、跨平台、轻量级的代码编辑器,具有非常丰富的插件生态。他本身就是JavaScript+Electron(/ɪˈlektrɒn/电子)代码开发的。官方下载......
  • 如何使用 IdGen 生成 UID
    在分布式系统中,雪花ID是一种常用的唯一ID生成算法。它通过结合时间戳、机器码和自增序列来生成64位整数ID,可以保证ID的唯一性和顺序性。在.Net项目中,我们可以使......
  • 第十二章《文件与I/O流》第3节:字节流的使用
    字节流每次输入或输出一个字节的数据,下面的表12-4展示了java.io包下定义的字节流。表12-4字节流类流类用途InputStream字节输入流的父类OutputStream字节输出流的父类Buffer......
  • 基于Mybatis-Plus实现Geometry字段在PostGis空间数据库中的使用
    背景在OGC标准中,通常空间字段是由Geometry类型来表示。而一般编程语言中是没有这种数据类型的。以java为例,怎么操作这些数据,满足业务需求呢?跟着本文一起来学习吧。今天介绍......
  • C++编译错误:ISO C++ forbids initialization of member `x'
     在C-Free中编译简单的C++代码,发现报以上错误:ISOC++forbidsinitializationofmember`x'(ISOC++禁止初始化成员变量‘x’),经查阅资料:c++类基于C语言的结构体(struc......
  • Git命令的使用
    Git命令 设置用户签名gitconfig--globaluser.name用户名gitconfig--globaluser.email邮箱初始化本地库在目录内打开GitBashHeregitinit查看本地库状......