IAR和KEIL环境下打印调试信息的方法Word文档下载推荐.docx
《IAR和KEIL环境下打印调试信息的方法Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《IAR和KEIL环境下打印调试信息的方法Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。
目标开发板上执行的IO实际上是交给了远程主机来处理实现,正是因为如此,这种方式只适合在调试模式下,真正的嵌入式系统不可能依赖于主机实现IO处理的,嵌入式系统要想独立出来实现IO请求的处理,这就需要将输入输出库函数的底层相关硬件实现重定向。
使用ITM机制实现调试,实现printf与scanf,
ITM是ARM在推出semihosting之后推出的新一代调试机制。
二、IAR输出调试信息方法
IAREWARMPrintfviaSWOStdoutandstderroftheapplicationcanberedirectedtoITMstimulusport#0.Itmeansthatstdout/stderrmessages(e.g.stringssentbyprintf)canbetransferredfromthetargetapplicationtotheC-SPYTerminal]
Requirements:
Cortex-M3/M4board;
J-Link/J-Trace;
IAREmbeddedWorkbenchforARM,V5.50.5orlater.
1.plusreroutingstdout/stderrmessagesviaSWO(librarylow-levelinterfaceimplementation,seethefigurebelow).
2.
exceptforenablingITMstimulusport#0andusingitforroutingdatatotheC-SPYTerminalI/Owindow.
3.
OpentheTerminalI/OwindowfromtheViewmenu.
StartexecutingtheapplicationtocollectSoftwareTraceinformation.
Stdoutmessagessentbyprintf()intheapplicationwillbedisplayedhereviaSWOTrace.
在IAR选项卡内GeneralOptions/LibraryConfiguration/下Library选项Full,Stdout/stderr选项viaSWO,仿真模式下设定SWO选项卡勾选EnablePortsToTerminalI/oWindowBit0,打开View下的TerminalIO显示。
基本步骤:
a.启动J-linkSWOviewer,设置选择的MCU型号,自动检测频率;
b.设置IAR工程的Generaloption的Libraryconfigure中选中ViaSWO。
c.添加stdio.h头文件,并在程序中需要的地方添加printf函数,实现了信息的打印功能。
三、IAR虚拟的串口来实现交互和打印
这里稍微提一句,我测试的是KE驱动库的代码,但是实际上只要你看懂了我下面的解决方法(授之以渔而不是鱼),其他代码都是类似的。
1)打开KE02platinum的IAR工程,进入到platinum.c文件,找到main函数如下图1,可以看到其调用了printf打印函数,而该工程是默认调用底层串口的,我们跳转到该函数的定义如图2,再继续跳转到out_char的函数定义如图3,这下就屡清楚了,我们可以很直观的看到工程默认是调用UART底层的,下面我们就要动手改造它对printf进行重定向;
2)首先我们需要注释掉printf的实现函数,将其屏蔽掉,然后需要给printf一个重新指向的地址,下面就该我们常见的<
stdio.h>
这位老兄出场了(貌似当初自打我开始接触TurboC的时候就已经用到它了,老生常谈的“Helloworld”就是调用它内部的printf来实现的)。
我们找到Common.h文件,将<
添加到其中,如下图,这样凡是需要printf的文件只需要添加common.h头文件即可:
3)这里先说说stdio.h文件的作用,我们打开stdio.h文件可以看到其内部定义了标准输入输出函数,包括我们常见的scanf和printf等函数,而这些函数所调用的底层即为IAR提供的链接到其Terminal的驱动,所以……懂的,呵呵。
除此之外,我们肯定不满足只输出打印(给人略显低端的赶脚有木有),所以为了体现我们不是“土豪”,我觉着有必要让它交互起来,实现真正的串口功能(因为一些类似bootloader之类的还是需要输入参数的),我在main函数添加了scanf语句用来测试输入功能,如下:
4)准备工作就绪,编译链接整个工程,然后下载到KE02的板子中并进入到Debug调试环境中,点击View->
TerminalI/O调出虚拟终端,然后全步运行,就可以看到Terminal下开始打印调试信息,如下。
当然显示输出有点小case了,我们再试试输入功能,在input框中输入‘a’,然后回车,如下图,perfect:
5)还没完,我们要玩就玩高端大气上点档次的,我们再探索探索呢,结果又发现个小惊喜,我们点击上图右下角的“InputMode”,弹出设置框如下,很高端啊有木有:
四、semihost/ITM机制浅析以及在IDE环境下使用JLINK通过ITM调试stm32单片机
<
允许自由转载,必须包含作者信息>
-----------------------------------------------------------作者:
prife
感谢:
hexlog@
-----------------------------------------------------------使用ITM机制实现调试stm32单片机,实现printf与scanf。
1.ITM简介
ITM机制要求使用SWD方式接口,并需要连接SWO线。
ITM机制是一种调试机制,是新一代调试方式,在这之前,有一种比较出名的调试方式,称为半主机(semihosting)方式。
在pc上编写过C语言的人都知道,printf可以向控制台输出,scanf可以从控制台获取输入,这里的printf/scanf都是标准库函数,利用操作系统的这些函数,我们可以很方便的调试程序。
在嵌入式设备上(如stm32单片机平台上)开发工具(如MDK/IAR)也都提供了标准库函,自然也提供了printf/scanf函数,那么这些函数是否可以使用呢?
问题来了,printf向哪里输出呢?
并且大部分情况下,也没有键盘,又如何使用scanf实现输入呢?
我们都知道,嵌入式设备一般的使用仿真器,如常见Jlink/ulink,可以实现烧录,单步,下断点,查看变量,等等。
仿真器将PC机和单片机连接器来。
聪明的设计者们就在考虑是否可以借助仿真器,使得单片机可以借助PC机的屏幕以及PC机的键盘实现printf的输出和scanf的按键获取。
也就是说,如下的hello,world程序
#include<
intmain()
{
//硬件初始化
//....
printf("
hello,world"
);
for(;
;
}
这个程序烧录到单片机中后,仿真器连接接单片机与PC,开始在线调试后,那么这个程序会将"
Hello,world"
输出到PC机上,在开发工具(MDK/IAR等)的某个窗口中显示。
这就相当于,单片机借助了PC机的显示/输入设备实现了自己的输出/输入。
这种方式无疑可以方便程序开发者调试。
这种机制有多种实现方式,比较著名的就是semihosting(半主机机制)和ITM机制。
ITM是ARM在推出semihosting之后推出的新一代调试机制。
现在我们来尝试一下这种方式调试。
2.stm32使用ITM调试
MCU:
stm32f207VG
仿真器:
JlinkV8
IDE:
MDK4.50
2.1硬件连接
ITM机制要求使用SWD方式接口,并需要连接SWO线,一般的四线SWD方式(VCCSDCLK,SDIO,GND)是不行的。
标准的20针JTAG接口是可以的,只需要在MDK里设置使用SWD接口即可。
2.2添加重定向文件
将下面的文件保存成任意C文件,并添加到工程中。
这里对这个文件简单说明一下,要知道我们的程序是在单片机上运行的,为什么printf可以输出到MDK窗口里去呢?
这是因为标准库中的printf实际上调用fputc实现输出,所以我们需要自己编写一个fputc函数,这个函数会借助ITM(类似于USART)提供的寄存器,实现数据的发送,仿真器会收到这些数据,并发往PC机。
实际上,如果你的单片机和一块LCD连接,那么你只需要重新实现fputc函数,并向LCD上输出即可,那么你调用printf时就会输出到LCD上了。
这中机制,就是所谓的重定向机制。
#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))
#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))
#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))
#defineDEMCR(*((volatile