程序小白
认证:优质创作者
所在专题目录 查看专题
闲话内核——一切皆为程序片服务
可抢占式内核带来的挑战——并发
裸奔、事件驱动、传统多任务到底孰优孰劣?
RTOS中的断言机制——assert
作者动态 更多
重新认识电子元器件——二极管原理
5天前
W5500详解——自带硬件协议栈的以太网芯
08-26 08:23
RTOS中的断言机制——assert
08-25 08:22
移植RT-thread到stm32开发板仿真异常解决
08-15 07:56
基于RT-Thread的STM32专属bsp定制:代码移植与修改
07-16 22:06

RTOS中的断言机制——assert

      在学习C语言的时候,相信很多小伙伴都会看过断言这一章,但是从事嵌入式软件开发的领域,我们却很少用到断言,在没有接触RTOS之前,我甚至不晓得断言原来有如此大的作用。

      关于断言的作用:确保软件的正常运行,一旦出现异常进行及时止损的一种机制,断言是在软件运行阶段的一种保护机制,并不存在于预处理和编译阶段。

      在RTOS中断言的应用其实很简单:

      RT_ASSERT(spi_dev_name); //断言spi_dev_name存不存在

      具体的实现如下在:

#define RT_ASSERT(EX)                                                         \
if (!(EX))                                                                    \
{                                                                             \
    rt_assert_handler(#EX, __FUNCTION__, __LINE__);                           \
}

ASSERT 是通过宏定义实现的,判断EX是否存在,如果不存在就执行rt_assert_handler函数;有个小知识点补充下,就是\的作用,如果没有他,那么#define的宏定义只有当前行算数,有了它那么就是下面的内容也包括在宏定义中,\可以理解为连接符。

      执行的rt_assert_handler中有两个参数比较特殊:__FUNCTION__和__LINE__这两个是编译器相关的参数:

__FUNCTION__:用于定位当前执行的函数:也就是函数名。

__LINE__:用于包含当前的行号,当前文件的行号。

rt_assert_handler函数的实现如下:

/**
 * The RT_ASSERT function.
 *
 * @param ex the assertion condition string
 * @param func the function name when assertion.
 * @param line the file line number when assertion.
 */
void rt_assert_handler(const char *ex_string, const char *func, rt_size_t line)
{
    volatile char dummy = 0;

    if (rt_assert_hook == RT_NULL)
    {
#ifdef RT_USING_MODULE
        if (dlmodule_self())
        {
            /* close assertion module */
            dlmodule_exit(-1);
        }
        else
#endif
        {
            rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex_string, func, line);
            while (dummy == 0);
        }
    }
    else
    {
        rt_assert_hook(ex_string, func, line);
    }
}

这个函数看着很复杂,其实分析起来,你会发现功能很简单,首先RT_USING_MODULE宏并没有定义,所以这块可以直接忽略,假定rt_assert_hook = RT_NULL,那么实际执行的函数就只有:

rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex_string, func, line);
            while (dummy == 0);

打印断言错误信息,包括错误内容,触发函数,所在行号等信息。

然后进入while死循环,阻塞当前函数执行。

阻塞的目的是为了将当前线程的异常影响降到最低,这并不能保证整个软件的功能正常,但是他能保证系统运行正常,方便我们定位错误以及调试异常。

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 2
收藏 1
关注 98
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧

  • <tr id='zu6gu'><strong id='mou1g'></strong><small id='4tohu'></small><button id='65rcu'></button><li id='2rkpp'><noscript id='zrq54'><big id='37cvp'></big><dt id='ek2x4'></dt></noscript></li></tr><ol id='3ee0x'><option id='dfz50'><table id='dhbn4'><blockquote id='44ees'><tbody id='783bu'></tbody></blockquote></table></option></ol><u id='ab20m'></u><kbd id='8piw0'><kbd id='2h4az'></kbd></kbd>

    <code id='la94u'><strong id='k2z8e'></strong></code>

    <fieldset id='amxvy'></fieldset>
          <span id='m83w7'></span>

              <ins id='tvp0r'></ins>
              <acronym id='iql1a'><em id='oxl0a'></em><td id='e2b2d'><div id='dyzn8'></div></td></acronym><address id='5ai7j'><big id='8y0my'><big id='6lytu'></big><legend id='37wkm'></legend></big></address>

              <i id='85877'><div id='4034i'><ins id='p81au'></ins></div></i>
              <i id='w92ik'></i>
            1. <dl id='ue8ln'></dl>
              1. <blockquote id='04ekk'><q id='s3vb7'><noscript id='jxez5'></noscript><dt id='9rr6t'></dt></q></blockquote><noframes id='klt1c'><i id='bk6ga'></i>

                新宝7