代码质量

在独立模式下进行C-RUN动态代码分析

<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >在独立模式下进行C-RUN动态代码分析</span>

C-RUN是一款动态代码分析工具,是IAR Embedded Workbench for Arm的一个插件。C-RUN能够在运行时检测对应的错误,如溢出、边界错误和内存使用错误。 

错误消息会显示在调试窗口中。其实C-RUN的消息可以重定向到任何通信通道,可以在现场测试中捕获,然后在测试后进行分析检查。 

C-RUN消息重定向到终端I/O

C-RUN消息通过半主机(semi-hosting)方式传输到PC,这是一个隐藏的过程。C-RUN消息的源代码位于<EWARM>\arm\src\lib\crun。在让C-RUN独立运行之前,我们先在终端I/O中查看消息。 

ReportCheckFailedStdout.c添加到您的工作区 

ReportCheckFailedStdout.c\crun复制到您的工作区。 

ReportCheckFailedStdout.c file

该文件默认是只读属性。从Windows属性中删除该属性。此外,将该文件添加到IAR Embedded Workbench for Arm的工作区。 

Add the source file to IAR Embedded Workbench

重定向C-RUN消息标准输出 

更改链接器配置以重定向C-RUN错误消息。默认情况下,会调用__iar_ReportCheckFailed。指定重定向到ReportCheckFailedStdout.c中定义的__iar_ReportCheckFailedStdout 

__interwork void __iar_ReportCheckFailedStdout(void * d)
{

char buf[200] = {0};
char *b = buf;

uint32_t const *data = (uint32_t const *)d;
int nr = data[0] >> 24;

b = putstring(b, "CRUN_ERROR:");
for (int i = 0; i < nr; ++i)
{
*b++ = ' ';
b = puthex(b, data[i]);
}
*b++ = '\n';
__write(_LLIO_STDOUT, (unsigned char const *)buf, (size_t)(b - buf));
if (__iar_ReportCheckFailedStdoutAbort)
abort();
}
 

打开[Project Option]Linker > Extra Options--redirect __iar_ReportCheckFailed=__iar_ReportCheckFailedStdout> 

Redirect settings for Runtine Analysis

使用C-RUN进行调试

在开始调试之前,请确保您已启用了您想要检测的C-RUN选项。选择Rebuild All,然后点击Download and Debug。接着,打开View > Terminal I/O windows并点击Go 

如果C-RUN检测到错误消息,它们将会发送到终端I/O窗口。

Output Terminal IO

现在我们可以在终端I/O窗口中看到C-RUN的消息,每条消息单独一行。这些消息是原始数据,cspybat.exe可以解析出这些消息。 

使用cspybat.exe解析C-RUN的原始数据 

cspybat.exe是一个用于批量调试测试的工具,它也可以用作C-RUN原始数据的解析器。 

修改bat文件

每次构建项目时,***.cspy.bat文件会在项目的settings文件夹下创建。用文本编辑器打开该文件。在--rtc_enable后添加--rtc_filter并保存文件。

command prompt中运行bat文件 

打开command prompt,进入settings文件夹。键入或使用TAB键选择bat文件。 

cspybat command line

接下来,添加out文件路径。

CSPYBAT syntax

在这个示例中,已经将c.out文件复制到了settings文件夹中,以简化路径,你也可以指定绝对路径。然后回车。 

CSPYBAT output in command line

现在cspybat正在等待C-RUN原始数据消息。 

解析原始数据消息 

粘贴我们在终端I/O中获得的消息。注意单行发送信息 

CSPYBAT error on command line

回车,解析后的消息将如下所示。 

CSPYBAT parsing in the command line

现在我们可以看到,在main.c的第16行出现了Inter conversion failure的信息。我们可以看到与C-RUN消息窗口中的类似信息。 

注意:在C-RUN原始数据中不包括函数调用栈信息 

C-RUN消息重定向到UART 

C-RUN消息也可以重定向到其他通信通道。我们可以简单地编辑_iar_ReportCheckFailedStdout()函数。 

编辑_iar_ReportCheckFailedStdout() 

IAR Embedded Workbench for Arm中打开ReportCheckFailedStdout.c文件。 

__interwork void __iar_ReportCheckFailedStdout(void * d)
{
char buf[200] = {0};
char *b = buf;

uint32_t const *data = (uint32_t const *)d;
int nr = data[0] >> 24;

b = putstring(b, "CRUN_ERROR:");
for (int i = 0; i < nr; ++i)
{
*b++ = ' ';
b = puthex(b, data[i]);
}
*b++ = '\n';
__write(_LLIO_STDOUT, (unsigned char const *)buf, (size_t)(b - buf));


if (__iar_ReportCheckFailedStdoutAbort)
abort();
}
 

buf包含C-RUN信息。它由__write函数发送。现在,让我们注释掉__write并调用串行发送函数。 

Serial send function

ser_printf()在其他地方定义。在C-RUN发送消息之前,必须设置UART 

您还可以修改C-RUN消息重定向到SPII2C,或存储在RAM或闪存中。 

运行项目并与终端应用程序通信 

打开终端应用程序,例如Tera Term,然后进行下载和调试。 

Tera Term output

C-RUN错误消息将显示在Tera Term中。第一个字母'A'是由正常的应用程序代码发送的。 

在独立模式下运行 

拔掉电源并从开发板上取下ICE,然后打开开发板电源。现在您应该能在终端应用程序中看到C-RUN消息。 

Tera Term output 2

现在我们可以在没有ICE的情况下进行现场测试并收集C-RUN检测消息。当然,之前的过程中检测到的消息可以通过cspybat.exe进行解析。

CSPYBAT parsed results full

注意:在创建.bat文件时,需要取消勾选Debugger > Download > Use flash loader(s)。只需取消勾选并关闭工作区,.bat文件将会更新。 

总结

C-RUN是一个非常便捷和有用的运行时分析插件。本文详细介绍了如何将C-RUN应用于现场测试中