在PC上编写过C语言的人都知道,printf可以向控制台输出,scanf可以从控制台获取输入,这里的printf/scanf都是标准库函数,利用这些函数,我们可以很方便的调试程序。
printf的方式有很多种,一般情况下,我们可以使用串口或其它接口重定向printf。参见之前的文章《串口printf和USB虚拟串口printf》。也可以使用Jlink等调试工具printf《Jlink使用技巧之RTT和J-Scope》。今天来介绍另外一种printf的方式:基于ITM机制的printf。
1.ITM简介
ITM,(英文:Instrumentation Trace Macrocell,指令跟踪宏单元),是一种针对MCU进行跟踪调试的新方法,与打断点(Breakpoint)不同,ITM方法不需要暂停程序运行,可以在程序全速运行的过程中实时输出变量的数值以便观察,即Trace功能。
2.硬件
ITM是一个硬件存在,Cortex-M3,M4,M7内核的单片机都支持(M0,M0+内核是不支持的),在代码调试过程中,它与Jlink或者ST-LINK等结合,可以实时跟踪MCU的运行状态,查看数据等。ITM只支持SWD接口,不支持JTAG接口,而且相比于一般的SWD调试接口需要SWDIO和SWCLK两根线,ITM则额外需要一个SWO端口。
3.软件
使用时,在工程设置中选择SW接口:
在Trace菜单下使能Trace功能,并设置MCU的内核频率,这里使用的是STM32F407,设置为168MHz,其它默认即可:
ITM机制有专门的几个函数用于收发字符串:
ITM_SendChar(ch)
ITM_CheckChar()
ITM_ReceiveChar()
将其重定向,然后就可以使用printf和scanf函数了。代码如下(别忘了包含stdio.h头文件):
struct __FILE { int handle; /* Add whatever needed */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
return(ITM_SendChar(ch));
}
volatile int32_t ITM_RxBuffer;
int fgetc(FILE *f)
{
while (ITM_CheckChar() != 1) __NOP();
return (ITM_ReceiveChar());
}
编写测试程序,测试printf和scanf函数:
while(1)
{
printf("ITM test AD = %d\r\n",AD++);//打印数据
scanf("%c",&c);//等待输入一个字符
printf("you input a character \'%c\'\r\n",c);//打印输入的字符
}
进入调试模式后,打开Debug(printf)Viewer窗口:
然后运行程序,在窗口中会打印出调试信息,同时等待输入字符。在窗口中输入字符,程序会继续运行。运行结果如下:
相比于其它方式的printf,ITM还可以支持scanf功能,调试程序时非常方便。ITM功能还有许多实用的功能,比如显示波形等,有兴趣的可以自己探索。
推荐阅读:
欢迎关注公众号"嵌入式技术开发",大家可以后台给我留言沟通交流。如果觉得该公众号对你有所帮助,也欢迎推荐分享给其他人。