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

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

3天内不再提示

什么是断言函数呢?断言函数在调试中的应用

冬至子 来源:聊点嵌入式 作者:聊点嵌入式 2023-11-06 15:55 次阅读

这一次我们继续讲调试方法。调试是排查程序Bug的有效方法,同时也对嵌入式软件设计的可靠性、稳定性而言至关重要。之前讲的调试方法能够打印出变量值、系统状态,或用互动的方式去调试程序,都不能动态的在系统运行时由程序判断变量、参数是否出错。

而我们今天要讲的断言(assert)函数则能做到在运行时判断参数是否超出预设值、状态是否出错,然后打印出出错数据所在的源文件和行号。

那么,什么是断言函数呢?百度百科给的定义是:“断言(assertion)是一种在程序中的一阶逻辑(如:一个结果为真或假的逻辑判断式),目的为了表示与验证软件开发者预期的结果——当程序执行到断言的位置时,对应的断言应该为真。若断言不为真时,程序会中止执行,并给出错误信息。“

接下来,我们继续采用上一次实时跟踪调试的例子,加入断言函数对运行过程的参数进行判断,看看断言函数如何应用,有什么效果。

1. CubeMX设置

我们可以在CubeMX中打开例子工程中的.ioc文件,按下图进行设置。

图片

除此之外,可以直接在CubeIDE的工程属性里定义一个宏USE_FULL_ASSERT,也可以在工程任意头文件中定义这个宏,效果是一样的。其实采用CubeMX配置之后,就是在工程的stm2f7xx_hal_conf.h头文件中定义了这个宏。

2. 修改代码

当定义了宏USE_FULL_ASSERT之后,assert_failed函数就能参与编译了,这个函数在main.c的最下边。这个函数的代码如下:

void assert_failed(uint8_t *file, uint32_t line)
{
printf("Wrong parameters value: file %s on line %drn", file, (uint16_t)line);
}

断言失败的话则会执行这个函数,利用printf打印一条消息,这里我们用的是CubeIDE的ITM模块向外打印,打印的消息里包含断言失败语句所在的源文件及行数。

要注意的是,参数line本来是无符号长整形,printf函数用%d对应长整形的话会给警告,所以做了一个强制类型转换,变为无符号短整型。我想应该不会有一个源文件超过65535行吧,那是要挨打的。

接下来在main.h里定义一个宏IS_PARA_COUNTER_OK,当然名字可以自己任意取。

#define IS_PARA_COUNTER_OK(para) (para < 5)

这个宏的其实是个表达式,用以对para参数的值进行判断,这里假设para的值小于5是正常的。为了防止出错,表达式用小括号括起来了。

在main函数while循环开始的地方,我们加上一条语句,用来对我们设置的一个用来计数的变量counter进行参数断言。

assert_param(IS_PARA_COUNTER_OK(counter));

其中,assert_param是在stm2f7xx_hal_conf.h中定义的一个宏。

#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *) FILE , LINE ))

意思是当expr表达式的值为真的时候,不执行任何操作,为假时,断言失败,执行assert_failed函数,并向该函数传递断言失败语句所在的源文件和行。__FILE__和__LINE__都是C语言定义的宏,分别代表当前源文件和所在行。

我们在main函数中写的断言语句可以完全展开如下:

(((counter < 5)) ? (void)0U : assert_failed((uint8_t *)"D:workspaceSTM32F7example2_ITMCoreSrcmain.c", 101))

是的,这条语句位于main.c的101行。

3. 调试结果

代码修改好后,连接好开发板,构建工程,进入调试模式并开始运行,我们可以在SWV ITM Data Console窗口看到如下信息。

图片

这里要说明一下,代码里counter值是在打印之后加1的,也就是说在打印出4之后,其值已经变为5,导致参数断言出错,打印出预设消息。另外我们也可以在assert_failed函数里加入一个死循环,断言失败后程序就不会继续往下执行了。

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

    关注

    180

    文章

    7534

    浏览量

    128881
  • 状态机
    +关注

    关注

    2

    文章

    486

    浏览量

    27187
  • HAL库
    +关注

    关注

    1

    文章

    112

    浏览量

    5894
收藏 人收藏

    评论

    相关推荐

    什么是断言?C语言中断言的语法和用法

    在软件开发过程中,我们经常需要处理各种错误和异常情况。为了提高代码的健壮性和可靠性,我们需要使用一些工具和技术来检测和处理这些问题。本篇博客将深入探讨C语言中断言的使用,帮助读者更好地理解和应用断言,提高代码的质量和可维护性。
    发表于 08-03 10:34 1684次阅读

    解析C语言断言函数的使用

    对于断言,相信大家都不陌生,大多数编程语言也都有断言这一特性。简单地讲,断言就是对某种假设条件进行检查。 在 C 语言中,断言被定义为宏的形式(assert(expression)),
    发表于 08-08 09:51 237次阅读
    解析C语言<b class='flag-5'>断言</b><b class='flag-5'>函数</b>的使用

    何为断言断言的作用有哪些?断言的种类 断言层次结构

    断言主要用来检查仿真过程中存在的时序问题,如果存在异常情况,断言会报警。一般在数字电路设计中都要加入断言断言占整个设计的比例应不少于30%。
    的头像 发表于 08-28 11:16 5547次阅读
    何为<b class='flag-5'>断言</b>?<b class='flag-5'>断言</b>的作用有哪些?<b class='flag-5'>断言</b>的种类 <b class='flag-5'>断言</b>层次结构

    C语言assert(断言)简介

    assert的功能,条件为真,程序继续执行;如果断言为假(false),则程序终止。
    的头像 发表于 11-17 16:33 653次阅读
    C语言assert(<b class='flag-5'>断言</b>)简介

    如何在XC8使用断言的?

    大家好,我正在尝试使用XC8断言,但是当我使用“*”时,“断言h”空格main(空隙){BOOL X=0;断言(x= 1);而(1){}}我的程序停止,并且
    发表于 03-26 10:58

    ART-Pi调试LAN8720object初始化遇到断言报错的原因是什么?

    使用rt-thread stdio平台和ART-Pi开发LAN8720A。目前已经过了ETH的初始化,但是object.c的rt_object_init()初始化函数断言报错。请教一下论坛的朋友
    发表于 04-14 09:42

    SVA断言是基于边沿还是电平

    SVA断言是一个强时序的技术,很多时候SVA的实际时序和验证工程师的期望可能不同,这种不同很难调试定位。下面是一个SVA断言的示例,验证工程师期望断言当检测到req的上升沿后,再持续高
    发表于 08-25 15:57

    何为断言断言该怎么使用

    的每个函数的参数!调试的便利 :如果在程序测试和调试期间违反了前置条件,也就是说断言异常了,则调用包含前置条件的函数的代码
    发表于 09-21 14:59

    怎样去修复HAL_NVIC_SetPriority的断言故障

    优先级值HAL_NVIC_SetPriority 的 PreemptPriority 值 0-15 之间变化,但是当调用 HAL_RCC_ClockConfig 函数时,该值是 16。(最大 4 位
    发表于 12-12 07:17

    SystemVerilog断言及其应用

    在介绍SystemVerilog 断言的概念、使用断言的好处、断言的分类、断言的组成以及断言如何被插入到被测设计(DUT)的基础上,本文详细
    发表于 05-24 16:35 0次下载
    SystemVerilog<b class='flag-5'>断言</b>及其应用

    如何正确使用断言八个技巧

    对许多开发人员来说,断言是一个令人困惑的话题,因为它们的许多使用方式与其设计初衷背道而驰。
    的头像 发表于 05-10 10:19 1w次阅读
    如何正确使用<b class='flag-5'>断言</b>八个技巧

    STM32函数库Assert断言机制

    编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任
    发表于 02-08 15:29 2次下载
    STM32<b class='flag-5'>函数</b>库Assert<b class='flag-5'>断言</b>机制

    C语言断言函数assert()的应用,清晰明了!

    这样可以快速发现并定位软件问题,同时对系统错误进行自动报警。对于在系统中隐藏很深,用其他手段极难发现的问题也可以通过断言进行定位,从而缩短软件问题定位时间,提高系统的可测性。
    的头像 发表于 04-12 10:02 593次阅读

    防御式编程之断言assert的使用

    是为了验证预期的结果——当程序执行到断言的位置时,对应的断言应该为真;若断言不为真时,程序会终止执行,并给出错误信息。可以在任何时候启用和禁用断言验证,因此可以在程序
    的头像 发表于 04-19 11:35 378次阅读

    基于断言的验证简介 – 第 1 部分

    基于断言的验证(ABV)是一种与传统方法相比可以大大减少验证过程的技术.
    的头像 发表于 01-09 09:59 255次阅读
    基于<b class='flag-5'>断言</b>的验证简介 – 第 1 部分