在单片机的软件开发中,经常会遇到各种各样的问题,很多时候为了定位到出现bug的地方,我们可能会借助很多的手段或者工具。比如串口打印、MDK在线仿真、上位机调试工具等等的。但是,有时候想要用串口打印输出某些结果,而硬件设计又没有预留串口,这种时候就感觉很不方便。我个人使用串口调试的频率还是蛮多的,主要是简单易操作,可以在想要观察运行结果的代码位置随便加调试输出,很方便定位问题。在硬件上没有多余的串口预留的话,如果有外接仿真引脚出来的话,在MDK环境下就可以使用ST-LINK、J-LINK等的各种LINK进行调试,实现printf输出的功能,简直是不要太棒了!在MDK的开发IDE环境下,支持仿真调试的组件有好几个,我这里使用的是Event Recorder。这个组件功能是在MDK5.22的版本是哪个开始增加的,所以想要使用这个组件功能,需要将自己的MDK开发工具升级到5.22以上,建议是当前最新的版本!
1、添加 Event Recorder 组件
1)打开你需要添加调试组件的项目工程,点击如下图所示的图标:
2)选择 “Compiler”,并按照如下勾选,勾选之后点击“ok”即可。如下图:
勾选之后可以看到工程目录上出现一个“Compiler”的选项,说明组件添加成功了,如下图:
3)检查组件的工程配置,如下:
说明如下:
Number of Records:表示 Event Recorder 缓冲可以记录的消息条数。Time Stamp Source:表示时间戳的来源其中,Time Stamp Source 有如下四种可以选择,一般使用 DWT 时钟周期计数器。如下图:
至此,Event Record组件就已经添加完成了。
2、printf 重定向
在Event Recorder 实现printf输出需要使用MDK的 Debug 功能,输出的效果就跟串口调试工具上的显示效果是一样的。Event Recorder 中的重定向代码如下:
int fputc (int c, FILE * stream) {
#if (!defined(RTE_Compiler_IO_STDOUT) && !defined(RTE_Compiler_IO_STDERR))
(void)c;
(void)stream;
#endif
#ifdef RTE_Compiler_IO_STDOUT
if (stream == &__stdout) {
#if (STDOUT_CR_LF != 0)
if (c == 'n') stdout_putchar('r');
#endif
return (stdout_putchar(c));
}
#endif
#ifdef RTE_Compiler_IO_STDERR
if (stream == &__stderr) {
#if (STDERR_CR_LF != 0)
if (c == 'n') stderr_putchar('r');
#endif
return (stderr_putchar(c));
}
#endif
return (-1);
}
注意:使用 Event Recorder 实现printf重定向时,一定要取消掉自己的项目中原本的重定向!
1)进入仿真调试模式,如下:
2)选中 Debug(printf)Viewer 调试组件,如下图:
3)选择仿真时周期更新,如下图:
4)添加初始化代码,如下:
/* 初始化 EventRecorder 并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
5)全速运行即可以看到结果。
示例:
测试代码如下:
仿真结果如下:
鼠标右键还可以对 Debug(printf)Viewer 进行设置,如下图:
3、简单方便的时间测量功能
Event Recorder 也可以测量代码运行的时间,时间测量功能简单易用,仅需一个起始函数,一个停止函数即可。
3.1、时间测量起始函数
EventStartG (slot)
或者
EventStopGv (slot, val1, val2)
函数说明:
1)函数中的字母 G 是表示分组 A,B,C,D,即实际调用函数为 EventStartA,EventStartB,EventStartC 和 EventStartD。2)函数的第一个形参 slot 的范围是 0-15,也就是最大可以测量 16 路。3)函数后面的两个形象 val1 和 val2 是 32 Bit变量,用户可以用这两个形参来传递变量数值给 Event Statistics 调试组件里面,用于图形化展示。
3.2、时间测量结束函数
EventStopG (slot)
或者
EventStopGv (slot, val1, val2)
函数说明:
1)函数中的字母G是表示分组A,B,C,D,即实际调用函数为EventStopA,EventStopB,EventStopC 和 EventStopD。2)函数的第一个形参 slot 的范围是 0-15,也就是最大可以测量 16 路。3)函数后面的两个形象 val1 和 val2 是 32 位变量,用户可以用这两个形参来传递变量数值给 Event Statistics 调试组件里面,用于图形化展示。
3.3、使用示例
1)添加初始化代码
/* 初始化 EventRecorder 并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
2)在代码前后加上起始和结束时间的测量API函数,如下所示:
3)选择 Event Statistics 调试组件,如下:
4)全速运行,查看结果,如下:
从图中可以看出,开始测量的位置是在 149 行处,结束测量的位置是在152 行处,下方的红色方框处标出了测量的最大时间和最小时间。
-
单片机
+关注
关注
6032文章
44514浏览量
632981 -
软件开发
+关注
关注
0文章
607浏览量
27330 -
上位机
+关注
关注
27文章
930浏览量
54732
发布评论请先 登录
相关推荐
评论