背景介绍 客户在测试SDK_2_9_1_EVK-MIMXRT1020中的evkmimxrt1020_lwip_tcpecho_freertos工程过程中,想要禁止串口打印功能,通过在Properties->Settings->Preprocessor中设置SDK_DEBUGCONSOLE=2(如图1所示)后重新编译工程,出现了如下图所示的编译错误。
图 1
图 2 问题分析在设置SDK_DEBUGCONSOLE=2后选择如下所示的串口打印、输入函数,do-while语句特点是先执行语句后判断条件,当设置while(0)时,表示while 条件永不成立,do后面语句块中的代码只会被执行一次,宏定义代码通过do { /* ... */ } while(0)将要执行的代码块包裹后,可以使得宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行,这是Linux内核代码中常用的宏函数定义方式。 - #define PRINTF(...) \
- do \
- { \
- } while (0)
- #define SCANF(...) \
- do \
- { \
- } while (0)
- #define PUTCHAR(...) \
- do \
- { \
- } while (0)
复制代码接着,我们根据错误信息定位出产生错误的代码行在fsl_assert.c中的__assertion_failed(char *failedExpr)函数(如下图所示),
经过预编译后,__assertion_failed(char *failedExpr)函数为如下所示。 - void __assertion_failed(char *failedExpr)
- {
- (void)do { } while (0);
- for (;;)
- {
- ;
- }
- }
复制代码到这里,我们应该猜到错误的原因了,就是在do前面加了**(void)**的关键字,既然找出了原因,该如何优雅的消除错误呢? 推荐的方式是修改宏函数而不是__assertion_failed(char *failedExpr)函数,这样可以避免头疼医头,脚痛医脚,而且也不容易给驱动代码带来额外的风险,修改后的代码如下所示。 - //#define PRINTF(...) \
- // do \
- // { \
- // } while (0)
- //#define SCANF(...) \
- // do \
- // { \
- // } while (0)
- //#define PUTCHAR(...) \
- // do \
- // { \
- // } while (0)
- #define PRINTF
- #define SCANF
- #define PUTCHAR
复制代码
|