历史上的今天
返回首页

历史上的今天

今天是:2025年04月11日(星期五)

正在发生

2019年04月11日 | STM32的断言机制——函数assert_param()

2019-04-11 来源:eefocus

我们在学STM32的时候函数assert_param出现的几率非常大,上网搜索一下,网上一般解释断言机制,做为程序开发调试阶段时使用。


下面我就谈一下我对这些应用的看法,学习东西抱着知其然也要知其所以然。


我们在分析库函数的时候,几乎每一个函数的原型有这个函数assert_param();


下面以assert_param(IS_GPIO_ALL_PERIPH(GPIOx));为例说一下我的理解,


函数的参数IS_GPIO_ALL_PERIPH(GPIOx),我们可以寻找到原型

#define IS_GPIO_ALL_PERIPH(PERIPH) (((*(uint32_t*)&(PERIPH)) == GPIOA_BASE)||
((*(uint32_t*)&(PERIPH)) == GPIOB_BASE) ||
((*(uint32_t*)&(PERIPH)) == GPIOC_BASE) ||
((*(uint32_t*)&(PERIPH)) == GPIOD_BASE) ||
((*(uint32_t*)&(PERIPH)) == GPIOE_BASE) ||
((*(uint32_t*)&(PERIPH)) == GPIOF_BASE) ||
((*(uint32_t*)&(PERIPH)) == GPIOG_BASE))

这个宏定义的作用就是检查参数PERIPH,判断参数PERIPH是否为GPIOX(A...G)基址中的一个,只要有一个为真则其值为真,否则为假,


不用多说,这是C语言中基本的逻辑运算。当然这个库函数也用的很有意思,看:首先对PERIPH进行取址,也就是求地址,&PERIPH,


然后对这个地址强制转化为32位的指针,即前面加(uint32_t *),然后通过*进行访问这个地址(指针)中的内容。


下面我们再回到assert_param这个函数,这个函数是哪里的呢?在stm32f10x_conf.h寻找到原型如下:
#ifdef USE_FULL_ASSERT

#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t*)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif 


若是没有定义USE_FULL_ASSERT我们调用这个函数assert_param时,不对参数IS_GPIO_ALL_PERIPH(GPIOx)的正确性进行检查,

执行语句(void)0,这是一个相当于空语句的表达式,不对程序产生任何影响。

若是定义了USE_FULL_ASSERT它,我们调用这个函数assert_param时,及对参数IS_GPIO_ALL_PERIPH(GPIOx)的正确性进行检查,

通过一个C语言中的双目运算符来判断,若是返回1,执行语句(void)0,这是一个相当于空语句的表达式;

若是返回0,则执行后面的函数assert_failed((uint8_t *)__FILE__,__LINE__),函数的作用在库函数中有解释,用来指示出错的行数和文件。


注意:__FILE__,__LINE__是标准库函数中的宏定义!切记

void assert_failed(uint8_t* file, uint32_t line);刚开始没看明白为什么加在这里,仔细一想是在头文件的函数声明。

至于函数实体呢?我们从官方文件的模板中main.c中可以找到。如下:

void assert_failed(u8* file, u32 line) 
{ /* User can add his own implementation to report the file name and linenumber, 
ex: printf("Wrong parameters value: file %s on line %drn", file,line) */ 
/* Infinite loop */ 
while (1) { } 
} 英文注释也说明了怎么应用,通过输入参数来确定位置,最简单的方法就是串口打印了,这个函数的主要思想是在输入参数有问题的时候,

但是有编译不出来,它可以帮你检查参数的有效性,好处不必多言,自己领悟就行。


继续说明如下: assert_param是怎样包含进去的呢?我们在stm32f10x_conf.h这个头文件中定义的函数声明还是宏定义,

怎么在其它文件中都能应用呢?也很多网上朋友在刚开始学习的时候都遇到编译不过去的问题出现,最后通过在文件中添加USE_STDPERIPH_DRIVER来解决的:


我们可以在整个工程中进行搜索USE_STDPERIPH_DRIVER,通过头文件可以看出,是使用标准外设文件。在stm32f10x.h文件中我们可以搜索到如下情况:
#if !defined USE_STDPERIPH_DRIVER
/**
* @brief Comment the line below if you will not use the peripherals drivers.
In this case, these drivers will not be included and the application code will 
be based on direct access to peripherals registers 
*/
#define USE_STDPERIPH_DRIVER
#endif

#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h"
#endif
可以很容易看出来,我们不在那里添加,只要把第一个的注释去掉,就不用在配置中添加USE_STDPERIPH_DRIVER了,

在第二个文件中我们可以知道怎样包含这个控制开关文件了,呵呵。我们也明白为什么我们在写程序的时候只要包含stm32f10x.h就能很容易的包含所有的文件文件了吧,

我们只要在stm32f10x_conf.h配置一下就能包含所需要的库文件了。

通过以上可以看出,通过头文件的相互包含,来控制外设以及调试文件的调用,这样我们理清思路,理解起来就好多了。

当然在学习中可能有些C语言问题还没有理解透彻,多上网搜一下,或者多看书,很快就搞明白的。



这是一种常见的软件技术,可以在调试阶段帮助程序员快速地排除那些明显的错误。

它确实在程序的运行上牺牲了效率(但只是在调试阶段),但在项目的开发上却帮助你提高了效率。

当你的项目开发成功,使用release模式编译之后,或在stm32f10x_conf.h文件中注释掉对USE_FULL_ASSERT的宏定义,

所有的assert_param()检验都消失了,不会影响最终程序的运行效率。

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

assert_param(IS_ADC_ALL_PERIPH(ADCx));
。。。

在执行assert_param()的检验时,如果发现参数出错,它会调用函数assert_failed()向程序员报告错误,

在任何一个例程中的main.c中都有这个函数的模板,如下:

void assert_failed(uint8_t* file, uint32_t line)
{


while (1)
{}
}

你可以按照自己使用的环境需求,添加适当的语句输出错误的信息提示,或修改这个函数做出适当的错误处理。

1、STM32F10xD.LIB是DEBUG模式的库库文件。
2、STM32F10xR.LIB是Release模式的库库文件。
3、要选择DEBUG和RELEASE模式,需要修改stm32f10x_conf.h的内容。
    #define DEBUG 表示DEBUG模式,把该语句注释掉,则为RELEASE模式。
4、要选择DEBUG和RELEASE模式,也可以在Options,C/C++,Define里填入DEBUG的预定义。
    这样,就不需要修改stm32f10x_conf.h的内容。
5、如果把库加入项目,则不需要将ST的库源文件加入项目,比较方便。
    但是,库的选择要和DEBUG预定义对应。


推荐阅读

史海拾趣

宜源科技(ETERNAL)公司的发展小趣事

宜源科技公司非常重视人才培养和团队建设。公司建立了一套完善的人才培养体系,为员工提供丰富的培训和发展机会。同时,宜源科技还积极引进优秀人才,打造高素质、专业化的技术和管理团队。这些团队在公司的各个领域中发挥着重要作用,为公司的长远发展提供了有力的人才保障。

Ceramics公司的发展小趣事

“绿色陶瓷”公司以其环保理念为核心,致力于研发和生产环保型陶瓷电子材料。该公司采用可再生资源和低能耗生产工艺,成功降低了产品对环境的影响。同时,绿色陶瓷还积极推广循环经济模式,通过回收再利用废旧陶瓷材料,实现了资源的最大化利用。这一环保理念不仅赢得了消费者的青睐,也为公司在电子行业的可持续发展奠定了坚实基础。

Honeywell公司的发展小趣事

背景:近年来,随着全球对可持续发展和数字化转型的重视,霍尼韦尔积极调整战略方向。

发展:公司加大了在可持续技术和数字化转型领域的投入,推出了一系列创新的产品和解决方案。例如,在能源转型领域,霍尼韦尔与多家中国合作伙伴共同推动可持续航空燃料生产基地的建设;在智慧建筑领域,与腾讯云合作打造联合解决方案等。

关键事件:这些举措不仅体现了霍尼韦尔对可持续发展的承诺和责任担当,也展示了公司在数字化转型方面的前瞻性和创新能力。同时,这些合作也进一步巩固了霍尼韦尔在全球电子行业的领先地位。

Dongguan Jingyue Electronics Co Ltd公司的发展小趣事

Dongguan Jingyue Electronics Co Ltd始终将社会责任和可持续发展作为公司发展的重要组成部分。公司积极参与公益事业,关注环境保护和员工福利。通过捐赠教育基金、支持环保项目、改善员工待遇等方式,公司履行了社会责任,也为公司的可持续发展奠定了基础。

请注意,以上故事均为虚构内容,仅用于展示电子行业公司可能的发展故事框架。

Dae Ryung Electronic Co Ltd公司的发展小趣事

在快速发展的过程中,Dae Ryung Electronic Co Ltd公司始终注重产品质量和品牌建设。公司建立了严格的质量管理体系,从原材料采购到产品生产、检测等各个环节都进行严格把关。同时,公司还注重品牌形象的塑造和宣传,通过广告宣传、公关活动等方式提升品牌知名度和美誉度。这些努力使得公司的产品在市场上获得了良好的口碑和认可。

DBM REFLEX公司的发展小趣事

在光学器件领域,技术创新是企业发展的关键。DBM REFLEX深知这一点,因此不断投入研发资源,致力于技术创新和产品创新。公司成功研发出了一系列具有高性能、高可靠性和高稳定性的光学器件,这些产品不仅满足了市场的需求,还为公司赢得了良好的口碑。

问答坊 | AI 解惑

FPGA初学者程序

有抢答器的,表决器的,线性分组编译码器的,数码管的,分频器的程序。哈哈~…

查看全部问答>

反馈的概念及判断方法(一看就明白)

很不错的教材,看了就能理解四种反馈的判断方法。…

查看全部问答>

聊聊关于VHDL

         最近开始学EDA了,VHDL看了一遍,还没有开始编程实践过,想知道要能熟练掌握VHDL是不是就必须要先知道一些基本器件的构造,比如说RS触发器之类的,以前学过数电,不过现在都忘的差不多了,是不是有必须熟悉 ...…

查看全部问答>

Spartan-6 FPGA 嵌入式套件试用(一)

拿到这板子的时候,迫不及待的拆开看了看,有感于板子功能的强大,不知道该从何入手,对于我这样的xilinx菜鸟来说,实在是太高级了!   我想既然是试用板,总该有些例子入手吧! 我开始找光盘,看看又没例子程序。找了半天没有发现哪个光盘 ...…

查看全部问答>

今天收团购的接近感应的板子了!

这个PCB设计的有意思直接加厚后,用做USB插头…

查看全部问答>

开发板android (4.5安装 ubuntu补丁)

xsltproc ia32-libs libgl1-mesa-dri:i386 lib32ncurses5-dev lib32z1-dev uboot-mkimage这个补丁安装不上,难道是安装包坏了,用WIFI下载的,最终导致IData无法实现(安装samba 让ubuntu12.04 和windows共享) …

查看全部问答>

智能小车电源问题

楼主最近在搞智能小车,基本的原理图已经完成,现在正处于各个模块的实验阶段。为了保证小车控制系统的稳定性,楼主采用了控制系统和电机驱动系统双电源供电。控制系统的电源供电采用LM2940-5.0芯片,将双节锂电池的7.5V调压至5V供电单片机,电路部 ...…

查看全部问答>

搞懂没有?dBm,dBV, dBuv, dB, dBf等测量单位

本帖最后由 dontium 于 2015-1-23 11:24 编辑 说明一下dBm,dBV, dBuv, dB, dBf等测量单位意义 dB的意义 1. dB基本上是一个比例数值,也就是一种倍数的表示单位。也就是测试数据与参考标准的相对差异表示。 2. 计算上: dB = ...…

查看全部问答>

转让闲置。

本帖最后由 zjbwxl 于 2014-11-3 19:28 编辑 1.http://2.taobao.com/item.htm?id= ... 0925.0.0.7tB1ae&mt=2.http://2.taobao.com/item.htm?id= ... 0925.0.0.7tB1ae&mt= 3.http://2.taobao.com/item.htm?id= ... 0925.0.0.7tB1ae&mt= 4.http:/ ...…

查看全部问答>

我在学cadence软件,但是无从下手,大神们都是怎么学的呢?

同标题,学习cadence,不知道如何入手,主要是想学习第三方导入网表,用cadence进行布局布线。是不是需要从cadence 的原理图设计开始呢?这个软件看起来比较复杂,大神们有没有什么推荐的视频以及书籍呢?谢谢啦…

查看全部问答>