Event Recorder的使用

描述

在单片机的软件开发中,经常会遇到各种各样的问题,很多时候为了定位到出现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 行处,下方的红色方框处标出了测量的最大时间和最小时间。

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分