"); //-->
工欲善其事必先利其器之二(MPLAB IDE中使用DBPRINTF()函数打印debug信息)
现在很多嵌入式MCU开发软件都具有直接在IDE的控制台console中实时打印调试信息和实时采集数据的功能,这对我们这些MCU程序设计和开发者来说,无疑是十分有用的。MPLAB IDE中也当仁不让的集成并支持这一功能,这主要得益于它使用了gcc编译器和gdb调试器以及Microchip公司的32位高性能MPIS核MCU——PIC32XX。
但是我最开始拿到Cerebot 32MX4™™ Board时,使用MPLAB 8.6.0使用例程中的DBPRINTF()函数打印调试信息时却未成功,经过最近两天的探索,今天下午终于把问题解决了,而且这个问题的解决居然是如此的简单~!
在main.c的最前面,即代码首行对PIC32_STARTER_KIT进行定义如下所示:
#define PIC32_STARTER_KIT 1
下面讲一下其中的原因:
我首先在google寻找答案,搜到一篇名为《Hello from PIC32》的外语文章,其链接为:http://www.johnloomis.org/microchip/pic32/hello/hello1.html
按照这边文章所说的,我下载了其提供的工程,下载到Cerebot 32MX4™™ Board上,运行,确实成功的使用DBPRINTF()函数打印出了Hello from PIC32,窃以为只要按照这种方法把下载到的db_utils.h头文件和db_utils.a库文件加到自己的工程中,并在main.c的开头加入#include "db_utils.h"就可以在自己的工程中正常的使用DBPRINTF()函数呢,结果不是。
当我把下载到的db_utils.h头文件和db_utils.a库文件拷贝到i2c工程中,并添加到该工程里面时,一编译就冒出类似如下警告来:
Executing: "C:\Study\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe" -mprocessor=32MX360F512L -x c -c "source\i2c_master.c" -o".\objects\i2c_master.o" -MMD -MF".\objects\i2c_master.d" -I"C:\Projects\Peripheral Libs\Trunk\pic32-libs\include" -I".\source" -D__DEBUG -D__MPLAB_DEBUGGER_PIC32MXSK=1 -g -DSYS_CLOCK=80000000 -Wall
In file included from source\i2c_master.c:50:
source\/db_utils.h:49:1: warning: "DBINIT" redefined
In file included from C:/Study/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/p32xxxx.h:396,from C:/Study/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/peripheral/adc10.h:44,from C:/Study/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/plib.h:41,from source\i2c_master.c:48:
提示BDXXXX相关的调试函数全部重定义了。
我以为警告没有什么问题,下载到板子上进行调试,结果发现程序可以正常运行,但是还是不能打印调试信息,最后单步调试才发现,程序根本不执行DBXX类的函数,包括DBINIT();DBPRINTF();DBPUTS()等(单步是,程序直接跳过有DBXX函数的行,继续往下执行)。
最后,功夫不负有心人,提供最终编译日志,查到了原因所在:
原因其实不不在于工程没有包含db_utils.a这个包含调试函数的库,在IDE的gcc工具设置中已经包含了相关函数定义及头文件了的。我追踪到我的MPLAB安装目录C:\Study\Microchip\MPLAB C32 Suite\pic32mx\include\sys下一个叫appio.h的头文件:
在其101行至129行有如下内容:
#if defined(PIC32_STARTER_KIT) && defined(__DEBUG)
#define DBINIT() _pic32mxsk_init()
#define DBPUTC(c) db_puts(c,1)
#define DBPUTS(s) db_puts(s, strlen(s))
#define DBPRINTF printf
#define DBSCANF ((void)0) /* scanf not supported in SK */
#define DBGETS(s,len) db_gets(s, len)
#define DBGETC(c) db_gets(c,1)
/* Debug function prototypes */
extern void _pic32mxsk_init (void);
extern void __attribute__ ((noinline,nomips16,weak)) db_puts (const unsigned char *s, int len);
extern void __attribute__ ((noinline,nomips16,weak)) db_gets (unsigned char *s, int len);
extern void __attribute__ ((weak)) _mon_write (const char * s, unsigned int count) __attribute__((alias("_p32mxsk_write")));
extern void __attribute__ ((weak)) _mon_putc (char c) __attribute__((alias("_p32mxsk_putc")));
extern void __attribute__ ((weak)) _mon_getc (int canblock) __attribute__((alias("_p32mxsk_getc")));
#else /* !(defined(PIC32_STARTER_KIT) && defined(__DEBUG)) */
#define DBINIT() ((void)0)
#define DBPUTC(ignore) ((void)0)
#define DBPUTS(ignore) ((void)0)
#define DBPRINTF(ignore,...) ((void)0)
#define DBSCANF(ignore,...) ((void)0)
#define DBGETC(ignore) ((void)0)
#define DBGETS(ignore,ignore2) ((void)0)
#define DBAPPIO_INIT(ignore) ((void)0)
#define DBGETWORD(ignore) ((void)0)
#define DBPUTWORD(ignore) ((void)0)
#endif
从以上条件编译可以看到,只有当PIC32_STARTER_KIT和__DEBUG两个预编译控制变量都为1(或者非0)时,才真正对DBXX类调试函数进行定义,否则定义为((void)0)即空函数,怪说不得,之前的程序执行到DBXX函数时就直接跳过了。呵呵,真正的原因也句找到了~!
接下来解决的办法就是让编译器在编译我们的工程时真正定义这些DBxx类函数,当我们将工程属性配置为debug而非release时(配置方法为①新建工程时选择为debug,②通过IDE的菜单栏Project->Build Configuration->Debug),IDE就会自动的为我们定义__DEBUG,而PIC32_STARTER_KIT则需要我们自己进行定义,系统不会自动定义。
另外,由于在p32xxxx.h,dc10.h以及很多头文件中有用到appio.h文件,所以必须在main.c的首行就用#define PIC32_STARTER_KIT 1 对PIC32_STARTER_KIT进行定义才能让软件在编译你的工程时真正的定义DBXX类调试函数。
胡恩伟
2011年1月16日
于重庆大学A区一舍
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
Microchip推出AVR SD系列入门级单片机(MCU),降低安全关键型应用的系统成本和复杂性
贸泽联手Micron推出全新电子书;带你探索面向AI边缘应用的创新内存解决方案与设计
求助:上海微电子应届毕业生求职
单片机的EMC测试及EMC故障排除
单片机测控系统设计中对干扰问题的处理
罗德与施瓦茨携手恩智浦展示基于Trimension™ NCJ29D6汽车解决方案的独特UWB雷达目标模拟技术
单片机初学者的常见问题
应用材料公司中国总部2025年3月乔迁新址
StrikerVR触觉VR枪Arena Infinity:先进触觉技术带来更真实的后坐力,提升VR沉浸感
makefile 教程(中文版)
新型高电压精密放大器--业界最精确的SPICE模型
是德科技在宽禁带半导体裸片上实现动态测试
SmartFactory解决方案助力客户创新集成
如何用ARM对DSP编程
照度的自动控制电路
Proximus Global与诺基亚携手推出网络API,帮助开发人员创建企业级应用
设计指南-低功耗压力传感器
帖子已删除
测量射频电路
设计指南-热功率器件设计中的几点思考
南芯科技推出内置MOS管的高集成度升降压充电芯片
自动控制发光时间电路
对数照度计电路
用于测量照射强度很小的电路
bootloader开发详解
设计指南-为什么我们需要斩波放大器
单片机编程技巧--功能强大的时钟中断
单片机串口编程问题
利用光强变化测量仪电路构成差分放大器电路
中国汽车工业协会到访英特尔,共探智能汽车发展