fugoog 发表于 2025-4-14 13:34:20

如何调试nRF5 SDK

本文将讲述Nordic nRF5 SDK的主要调试手段,以帮助大家快速定位问题,并解决问题。一般来说,你可以通过打log方式,IDE的debug模式,SDK自带的app_error_check函数,以及命令行方式等多种手段来调试你的代码。1. 通过打log方式进行调试nRF5 SDK支持UART和SWD J-Link(RTT)两种底层通信方式来打印日志,SDK14之后日志也可以通过蓝牙或者Flash进行输出和存储打印,一般来说,UART和SWD用得比较多,其中UART使用串口助手来查看日志,SWD使用J-Link RTT Viewer(仅适用Windows)或者J-Link RTT Client(Windows/Mac/Linux系统)来查看打印日志。由于UART日志打印方式会占用一个UART口,而大部分nRF5芯片都只有一个UART口,从而导致资源冲突,为此推荐大家使用RTT方式来打印日志,从而可以将UART口留给正常应用,更重要的是RTT打印方式功耗非常低(几乎可以忽略不计),大家可以在正式release的产品中也使能它,从而发现产品部署后有可能会出现的问题(UART打印方式功耗非常高,在正式release产品中必须关掉它)。如果使用SWD接口进行日志打印,那么你可以使用J-Link RTT Viewer或者RTTClient来显示日志,二者选其一即可。在Windows平台推荐使用RTT viewer,否则使用RTT Client。1.1 J-Link RTT ViewerRTT viewer配置方式如下所示:RTT viewer日志打印窗口如下所示:(使用的是SDK15.3中的ble_app_hrs例子,下同)1.2 J-Link RTTClientRTT client配置方式如下所示(直接使用jlink命令进行配置):RTT client打印窗口如下所示:1.3 UART串口助手串口助手配置方式如下所示:
[*]Baud rate: 115200
[*]8 data bits
[*]1 stop bit
[*]No parity
[*]HW flow control: None
随便选择一款你熟悉的串口助手,比如Putty或者Termite,Termite打印窗口如下所示:Putty打印窗口如下所示:1.4 日志打印模块nRF_LognRF5 SDK日志打印功能是通过nRF_Log模块实现的(上面展示的日志都是通过nRF_Log打印出来的),SDK包含的大部分例子都自带打印功能,也就是说包含了nRF_Log模块。一般来说,例子都是默认使用UART进行打印的,如果需要改为RTT进行打印,需要对nRF_Log模块进行配置。在具体讲述nRF_Log模块的配置选项之前,先大概讲述一下nRF_Log的工作原理。nRF_Log工作原理nRF_Log模块包含前端和后端两部分代码。前端是面向用户的打印接口,比如NRF_LOG_INFO,它把用户要打印的数据放在一块RAM中。后端用来具体实现打印功能,即把前端RAM中的数据通过不同的后端接口打印出去。目前nRF_Log支持的后端接口有:UART,RTT,Flash和蓝牙。不管采用哪一种后端接口,对用户来说,其调用的前端API是一样的,nRF_Log模块会根据用户的配置自动适配相应后端接口,而且用户可以同时使能多个后端接口,即把日志同时打印到多个后端端口上。nRF_Log模块可以单独使能或禁止某一个模块的打印功能,比如advertising模块,当你调试advertising模块的时候,可以把log打开,调试完毕,把log关闭以让log界面变得更清爽。nRF_Log模块还可以设置打印的级别(Level),如果不分级别的话,打印界面会包含很多打印信息,让我们每次调试都要花费很多时间去寻找自己想要的日志上。设定级别后,我们可以有选择的打印需要的日志信息,没问题时,我们只打印info级别的日志;有问题时,我们就可以把所有debug级别的日志都打印出来。nRF_Log还有一个功能:Deferred,如果不使能Deferred,那么调用NRF_LOG_INFO等API的时候,立马就Flush,即把日志打印出去;如果使能了Deferred,那么调用NRF_LOG_INFO等API的时候,只是把打印数据放在RAM中,真正的打印由main函数中的NRF_LOG_PROCESS完成,这样可以最大程度降低打印对应用本身的影响,尤其在执行一些时序很关键的操作的时候。nRF_Log还支持时间戳打印,即在每条日志之前加上时间戳信息。nRF_Log配置从SDK12以后,nRF_Log模块的配置主要放在sdk_config.h文件中,以工程nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\ble_app_hrs\pca10040\s132\arm5_no_packs为例,nRF_Log的配置选项如下所示:注意:nRF5 SDK v11.0.0及以前版本是没有sdk_config.h文件的,此时你需要到options for target->C/C++->define里面定义一个宏(Keil工程),如果定义“NRF_LOG_USES_UART=1”选择UART日志打印;如果定义”NRF_LOG_USES_RTT=1” 则选择RTT日志打印,如下:还是以nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\ble_app_hrs\pca10040\s132\arm5_no_packs为例,当nRF_Log配置为info级别,无timestamp,打印信息如下(与前面配置一样)当nRF_Log配置为debug级别,打开timestamp,打印信息如下所示:2. 使用IDE调试界面进行调试Nordic产品支持单步,断点,寄存器查看,内存查看,call stack查看等所有常规调试手段。需要注意的是,由于softdevice在底层要维持一定的时钟以及处理很多中断事件,一旦蓝牙跑起来后,只能用一个断点进行全速跑,也就是说,执行完一个断点后,程序内部逻辑和时序已经紊乱,此时不能再继续全速跑第二个断点。如果要看第二个断点的内容,只能删掉第一个断点,重新开始执行。

APPLE01 发表于 2025-4-16 10:27:51

学习学习

APPLE01 发表于 2025-4-16 10:28:15

感谢分享,学习了
页: [1]
查看完整版本: 如何调试nRF5 SDK