断言不是错误!

51a47bde78c614a5120f1e01c3f92e34.png

断言机制估计很多道友都用过,在 ST 的标准库中,经常可以看到它的身影:

d4c829b69ed163a0d1f28d5311781122.png

它的实现方式也是非常简单的,就是通过 USE_FULL_ASSERT 宏进行控制:

946efd150692ef2e55f00257804d8bbc.png

如果断言失败,就会执行 assert_failed 函数,一般实现函数如下:

void assert_failed (uint8_t* file, uint32_t line)
{
static char buff[128];  


sprintf (buff,"%s,%d", file, line);
  __breakpoint(0);
}

当然这里的 sprintf 函数也常常使用 printf 代替,这样就可以直接通过串口打印出来了,而鱼鹰这个在没有串口的情况下,可以通过内存 buff 显示出来,比较方便在线调试

而 __breakpoint(0) 一般由死循环 while(1) 代替,而鱼鹰觉得 while(1) 不够好,因为断言失败后,可能很久你才能发现而进入该死循环,而使用  __breakpoint 可以让你在 在线调试 模式下,立刻停止程序运行,从而可以快速定位问题。

不管哪种实现方式,断言失败的结果一般只有暂停程序了,类似 linux 内核的 panic 。

而这是设计者希望看到的,但有些开发者认为不应该这样,因为程序一旦死循环,如果开启了看门狗,会导致整个程序复位,对于产品而言,复位是很严重的 BUG 。

“我不希望我的产品复位,所以请修改你的代码,不让他产生断言失败,可以吗?”

不可以。

断言本身不是错误,它只是发现你程序的 BUG ,进而提醒你。

断言失败,往往是很严重的问题,严重到这段代码或功能无法正常执行,所以你修改的地方应该是调用者,而不是产生断言的代码,请不要颠倒主次,否则没有从根本上解决问题。

就比如最上面的 GPIO 外设指针检查断言部分,如果调用者传入一个非 GPIO 的指针进入函数,从而产生断言失败,那么你会选择关闭断言机制还是说检查你的代码是否存在问题呢?

当然是后者。

所以,如果产生了断言失败的情况,请不要慌,不要认为这是一种错误,而应该根据断言失败的位置,定位断言失败的根本原因,而不是试图通过关闭断言的方式让程序继续运行下去,这只会让你的程序运行得更糟糕,同时也更难定位问题。

7904cadf15f31fc3faba62d2df978ada.png

1.RISC-V嵌入式开发课程节选版上线!文末还有图书优惠哦!赶快抢!

2.RISC-V能成为八位MCU的选择吗?

3.对嵌入式工程师硬件转软件的几条建议!

4.浅谈智能嵌入式系统的优化设计

5.单片机AD采样常用的十大滤波算法~

6.物联网时代,嵌入式软件测试工具越来越重要~

b6f49b30f62e08105d35fb9efe507dc9.gif

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值