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

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

3天内不再提示

printf调试的技巧

lilihe92 来源:嵌入式Linux 2023-05-10 09:31 次阅读

1

前言

printf调试是嵌入式调试的基本手段,而且是非常重要的手段,我认为相比单步调试更加有用有效,特别是单片机之后跑系统,单步调试效率更加低下了,我们在工作遇到bug的时候,我们第一时间就想知道那些该死的日志有没有保存下来,这样好让我们程序员装逼一波把问题解决。

printf宏定义调试非常重要,有些日志在开发的时候才需要打开,发布的时候需要关闭,但是在代码上又需要保留下次调试,所以我们在调试的时候才打开调试宏定义,而且printf会占用空间,很多芯片的空间非常有限,更应该关闭调试宏。

下面就直接进入正题,说一下调试的技巧

2

正文

1、 编译器内置宏

先介绍几个编译器内置的宏定义,这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息

ANSI C标准中有几个标准预定义宏(也是常用的):

__LINE__:在源代码中插入当前源代码行号;

__FILE__:在源文件中插入当前源文件名;

__DATE__:在源文件中插入当前的编译日期

__TIME__:在源文件中插入当前编译时间;

__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;

__cplusplus:当编写C++程序时该标识符被定义。

编译器在进行源码编译的时候,会自动将这些宏替换为相应内容。

2、最基本的用法

打开宏的时候输出

09f9e1b8-ee7a-11ed-90ce-dac502259ad0.png

关闭宏的时候输出

0a0cc72e-ee7a-11ed-90ce-dac502259ad0.png

3、换个高级的用法

代码如下

#include

#define__DEBUG__

#ifdef__DEBUG__
#defineDEBUG(format,...)printf("Date:"__DATE__",File:"__FILE__",Line:%05d:"format"
",__LINE__,##__VA_ARGS__)
#else
#defineDEBUG(format,...)
#endif

intmain(intargc,char**argv){
charstr[]="HelloWorld";
DEBUG("%s",str);
return0;
}

输出如下

Date:Oct52018,File:/code/main.c,Line:00013:HelloWorld
sandbox>exitedwithstatus0

在线编译器网址:https://tool.lu/coderunner/

4、## __VA_ARGS__ ... 宏和可变参数

在GNU C中,宏可以接受可变数目的参数,就象函数一样

例如:

#definepr_debug(fmt,arg...)
printk(KERN_DEBUGfmt,##arg)

用可变参数宏(variadic macros)传递可变参数表
你可能很熟悉在函数中使用可变参数表,如:

voidprintf(constchar*format,...);

直到最近,可变参数表还是只能应用在真正的函数中,不能使用在宏中。

C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以

使用拥有可以变化的参数表的宏。可变参数宏就像下面这个样子:

#definedebug(...)printf(__VA_ARGS__)

缺省号代表一个可以变化的参数表。使用保留名 __VA_ARGS__ 把参数传递给宏。

当宏的调用展开时,实际的参数就传递给 printf()了

例如:

debug("Y=%d
",y);

处理器会把宏的调用替换成:

printf("Y=%d
",y);

因为debug()是一个可变参数宏,你能在每一次调用中传递不同数目的参数:

debug("test");//一个参数

用GCC和C99的可变参数宏, 更方便地打印调试信息

可变参数宏不被ANSI/ISO C++ 所正式支持。因此,你应当检查你的编译器,看它是否支持这项技术。

可变参数的宏里的'##'操作说明带有可变参数的宏(Macros with a Variable Number of Arguments)

5、举个栗子-Linux内核调试宏

下面是Android touchscreen驱动的调试宏用法,看这样的写法就是一个大神了,给大家借鉴。

//Logdefine
#defineGTP_ERROR(fmt,arg...)printk("<<-GTP-ERROR->>"fmt"
",##arg)
#ifDEBUG_SWITCH
#defineGTP_INFO(fmt,arg...)printk("<<-GTP-INFO->>"fmt"
",##arg)
#defineGTP_DEBUG(fmt,arg...)do{
if(GTP_DEBUG_ON)
printk("<<-GTP-DEBUG->>[%d]"fmt"
",__LINE__,##arg);
}while(0)
#defineGTP_DEBUG_ARRAY(array,num)do{
s32i;
u8*a=array;
if(GTP_DEBUG_ARRAY_ON)
{
printk("<<-GTP-DEBUG-ARRAY->>
");
for(i=0;i< (num); i++)
                                            {
                                                printk("%02x   ", (a)[i]);
                                                if ((i + 1 ) %10 == 0)
                                                {
                                                    printk("
");
                                                }
                                            }
                                            printk("
");
                                        }
                                       }while(0)
#define GTP_DEBUG_FUNC()               do{
                                         if(GTP_DEBUG_FUNC_ON)
                                         printk("     <<-GTP-FUNC->>Func:%s@Line:%d
",__func__,__LINE__);
}while(0)

#else
#defineGTP_INFO(fmt,arg...)
#defineGTP_DEBUG(fmt,arg...)
#defineGTP_DEBUG_ARRAY(array,num)
#defineGTP_DEBUG_FUNC()
#endif





审核编辑:刘清

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

    关注

    1

    文章

    1618

    浏览量

    49043
  • GNU
    GNU
    +关注

    关注

    0

    文章

    143

    浏览量

    17475
  • 嵌入式调试器

    关注

    1

    文章

    4

    浏览量

    8953
  • Printf
    +关注

    关注

    0

    文章

    81

    浏览量

    13623

原文标题:单步调试好用,printf宏也挺香~

文章出处:【微信号:最后一个bug,微信公众号:最后一个bug】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    keil5中想确认工程中某一个.c文件是否出错,如何利用printf调试

    现在想确认工程中某一个.c文件是否出错,如何利用printf调试
    发表于 03-21 08:03

    【NUCLEO-F412ZG试用体验】2:调试准备测量函数运行时间

    到stlink的,如下图所示:用STM32F412的串口3发送数据,就可以和电脑进行通信了。除了用串口调试,还可以用ITM功能,进行DEBUG printf调试还可以用ITM功能测量程序运行时
    发表于 12-02 22:22

    如何去解决STM32串口打印输出乱码的现象

    STM32串口打印输出乱码的解决办法前言最近在试用uFUN开发板,下载配套的Demo程序,串口数据输出正常,当使用另一个模板工程,调用串口printf调试功能时,输出的却是乱码,最后发现是外部晶振
    发表于 08-12 06:08

    使用STM32最小系统要注意哪些问题呢

    STM32最小系统使用注意事项使用HAL库CubeMX工具使用printf调试串口板子烧录程序后没反应使用HAL库CubeMX工具在System Core->SYS里选择Debug方式,否则
    发表于 11-25 09:10

    如何为stm32-f429启用类似SWD/SWO printf()的调试功能?

    我对 stm32 和 arm 开发完全陌生,最近得到了我的 stm32-f429(ZIT6) 发现工具包。我只是遵循了一些教程,但无法正确启用 SWO printf() 之类的功能,我遵循了一些
    发表于 12-27 06:46

    如何在STM32CubeIDE上为Cortex M0+进行“快速”调试

    printf 调试?或者,有没有一种快速的方法可以让我了解我的代码在跳入和跳出中断时是如何执行的?笔记:我知道这个文件:https : //www.st.com/resource/en
    发表于 02-03 08:31

    ESP-WROVER-KIT开发板不能用于开发涉及SD卡的代码?

    如果要使用调试器,就没有办法为ESP32开发吗?您有什么建议 - 将此卡发回并进行 PrintF() 调试
    发表于 03-01 07:41

    如何通过USB PC终端使用printf()调试OM13093评估板?

    帮助:通过 USB PC 终端使用 printf() 调试 OM13093 评估板我在 2018 年找到了一篇类似的帖子,但问题没有得到直接回答——如何设置 OM13093 评估板硬件
    发表于 03-23 09:01

    RT1170 EVK MCUXpresso“SWD配置”检测到0个可用的SWD设备?

    一切都调试得很好,然后我开始遇到这个问题。它是在尝试让 M4 控制 PRINTF 调试并调用 BOARD_InitDebugConsole 而不是 M7 之后启动的我尝试使用 LPCScrypt 和 program_CMSIS.
    发表于 04-11 06:27

    ESP-WROVER-KIT开发板不能用于开发涉及SD卡的代码?

    如果要使用调试器,就没有办法为ESP32开发吗?您有什么建议 - 将此卡发回并进行 PrintF() 调试
    发表于 04-12 08:37

    STM8S串口打印调试信息(不使用printf)

    STM8S串口打印调试信息(不使用printf),感兴趣可以看看。
    发表于 07-25 18:52 51次下载

    51单片机-printf调试用法

    #include <stdio.h>#include <reg52.h> void InitUART(void)//使用定时器1作为串口波特率发生器{ TH1 = 0xF3; //晶振12mhz 波特率串口上设为2400才不显示乱码代码是4800 TL1 = TH1; TMOD |= 0x20; //定时器1方式2 SCON ...
    发表于 11-11 20:06 2次下载
    51单片机-<b class='flag-5'>printf</b><b class='flag-5'>调试</b>用法

    STM32最小系统使用注意事项

    STM32最小系统使用注意事项使用HAL库CubeMX工具使用printf调试串口板子烧录程序后没反应使用HAL库CubeMX工具在System Core->SYS里选择Debug方式
    发表于 11-17 17:36 6次下载
    STM32最小系统使用注意事项

    51单片机串口通信调试printf函数重定向输出打印

    51单片机串口通信以及printf调试串行通信1.串口初始化串口工作方式波特率设置通过软件直接生成串口初始化代码2.输出到串口3.发送字符串到串口4.printf重定向到串口5.补充print
    发表于 11-20 16:36 16次下载
    51单片机串口通信<b class='flag-5'>调试</b><b class='flag-5'>printf</b>函数重定向输出打印

    STM32串口打印输出乱码的解决办法

    最近在试用uFUN开发板,下载配套的Demo程序,串口数据输出正常,当使用另一个模板工程,调用串口printf调试功能时,输出的却是乱码,最...
    发表于 01-26 18:29 2次下载
    STM32串口打印输出乱码的解决办法