当前位置:首页 > 嵌入式 > 嵌入式硬件
[导读]摘要:提出在目标系统脱离开发系统运行时,如何通过串口在Windows的超级终端软件中显示调试信息的一个具体方法。该方法有助于改进调试质量、缩短调试周期。关键词:脱机调试

摘要:提出在目标系统脱离开发系统运行时,如何通过串口在Windows的超级终端软件中显示调试信息的一个具体方法。该方法有助于改进调试质量、缩短调试周期。

关键词:脱机调试 超级终端 可变参数函数 输出函数

1 ROM版本目标系统的调试问题

一般的目标系统在开发工具环境下的调试并不困难,但最终系统必须脱离开发工具独立运行,即使在开发工具环境下完全正常的系统,ROM版本也往往会出现各种问题。原因有两人:一是开发工具硬件环境和最终的目标硬件环境不完全相同;二是外部因素不同,实验室中无法模拟现场的很多外部条件。因此,在脱离开发工具后的现场运行中,也能进行调试,这在产品开发的初期是十分重要的。对于硬件的调试,可以使用示波器等仪器;对于软件的调试,一般方法则是显示软件运行中的各种信息(如变量)。

 

我们知道,C语言中的“printf()”函数是学习C语言的人最了解和熟悉的一个函数。很多C语言教材一开始就以显示“hello word”字符串来描述C语言的基本特片,其中唯一的语句就是调用“printf ()”函数。虽然该函数可以在屏幕上输出信息,但一般的用户软件中只在调试时用它来显示某些中间变量的结果,一旦程序调试完成,就将其删除了,真正的应用信息(如菜单字符等)显示往往其他的输出函数,如puts(),cputs()等。实际上,在C语言编写的第一个软件-UNIX操作系统中,该函数也是用于输出调试信息或系统错误提示信息的。对于使用和学习C语言的程序员来说,printf()由于可以同时输出不同类型的数据,因此,它的使用是软件调试的重要手段之一。

在TURBO C2.0编译器中,printf()函数的实现依赖于操作系统。在嵌入式系统中,往往没有操作系统或者操作系统不提供这个功能,也可能没有显示输出部件,或显示设备的空间有限,只能用于显示应用信息。因此,必须用其他的方法来解决调试信息的输出问题。最常用的方法是通过目标系统的一个串口将信息发送给PC 机来显示,PC机上可以使用Windows的“超级终端”软件接受和显示信息,如图1所示。

这种系统的硬件很简单,我们只说明软件的实现方法。为此,我们必须设计专用的、可以显示各种数据类型的printf()函数,以达到从串口或其他途径输出信息的目的。在一些C开发工具(如C51)中,系统提供了printf()库函数,但没有提供源代码[1],LINUX和UNIX的源代码中虽然也包含printf()的函数源代码,但过于复杂[2,3]。和一般的C函数不同,printf()函数的参数数量和类型是可变的,这是编写该函数的难点。要解决这个难是,必须先了解C函数参数传递的原理。

2 C函数的参数传递原理

在大部分情况下,C语言是通过堆栈存储器来传递参数(也有例外,C51的小模式则通过寄存器传递参数)。对于非指针类型,传递的不是原来类型的数据,而是对参数进行了类型转换,如字符类型(char)变成整型(int)拷贝到堆栈中、浮点类型(float)变成双精度类型(double),如表1所列。表1中未列出的,则没有转换[4]。

表1

对于像字符数组之类的指针参数,是将指针拷贝到堆栈中,而不是将数组中的所有内容传送到堆栈中。比如,对函数fun(char *str,int i,float &a)的调用:

char str[10]=“welcome”;

int i=100; float a=1.14;

……

fun(str,i,&a);

各个参烽str,i在堆栈中按先右后左的次序存放,表2所列为调用函数fun( )开始时堆栈中的参数存放情况。此时函数fun()的代码上尚未执行,函数中的局部变量也是在堆栈中,所以在函数执行结束后,局部变量将消失。

表2 函数调用时的参数在堆栈中的存储情况(X86环境)

表2说明了两个问题:第一个问题是,每个参数在堆栈中的存储长度和参数的类型有关。对于指针类型参数,参数长度和编译模式有关:大模式下,地址包括段地址和偏移地址,共4字节;而小模式下,地址只有段内偏移,占2字节。第二个问题是,如果知道其中的一个参数地址和参数的类型,则可以得到任意参数的数值,并不需要知道参数的名称。比如在函数fun()中,可用以下代码显示各个参数的内容:

void fun(char *str,int i,float *a)

{

void *p

p=&str;

printf("str=%s",str); p=(char **)p+1;

printf("i=%d" ((int*)p));p=(int *)p+1;

printf("i=%d" *((float *)p));

}

上面语句定义了一个无法型指针p来指向堆栈地址,这样,就可以得到堆栈中的各个参数。p被初始化为指向第一个参数str。因为str也是一个指针,所以需要将p转换为一个二重指针后再加1,以使指针移向下一个参数i。这样,没有使用参数i和a,也可以显示这两个变量的数值。

3 PC机上的printf()函数的设计实现

现在,可以编写自己的printf()函数了。以下给出TC20编译环境下的具体实现代码,在其他环境下,可以根据该原理进行移植。该函数除了可以显示十进制、字符串、十六进制等格式数值外,也可以按位显示二进制数。对于其他类型,读者可以根据需要增删。

在实际应用中,可以修改其中的putchar()函数,将字符发到串口,就可以达到上述目的了。这里我们编写的函数还增加了数字的二进制显示,这对于很多位域应用是很有用处的。

/*printf()函数的实现代码,为和库函数区别,特在各函数前增加前缀“my”*/

void myprintf(char *fmt,…)

{

void *p;

char ch;

p=&fmt;p=(char**)p+1;/*指向堆栈中的下一个参数*/

while(1){

while((ch=*fmt++)!=‘%‘{/*读入格式字符串*/

if(ch= =‘0‘)return;

putchar(ch);

};

ch=*fmt++;[!--empirenews.page--]

switch(ch){ /*格式字符分析*/

/*因为字符参数传递时也转换成整形参数传递,故同样处理*/

case ‘c‘:

case‘d‘:

case‘x‘:

case‘0‘:

case‘b‘:

if(ch= =‘c‘)myputchar(*(int *)p));

if(ch= =‘d‘)myprintn(*((int *)p),10);

if(ch= =‘x‘)myprintn(*((int *)p),16);

if(ch= =‘o‘)myprintn(*((int *)p),8);

if(ch= =‘b‘)myprintn(*((int *)p),2);

p=(int)p+1; /*指针移动*/

break;

case‘s‘:

myputs(*((char **)p));

p=(char **)p+1; /*指针移动*/

break;

default;

};

}

}

void myputs(char str) /*显示一个字符*/

{

while((*str)!=‘0‘)myputchar(‘str++);

}

/*显示任意进制的数值,b为二、八、十、十六等进制数*/

void myprintn(int,n,int b)

{

if(b= =16){ myprintx(n); return; }

if(n<0){ myputchar(‘-‘); n=-n; };

if(n/b)

myprintn(n/b,b);

myputchar(n%b+‘0‘);

}

void myprintx(int n) /*以十六进制显示1个数字*/

{

signed char i;

for(i=3;i>=0;i--)

if(((n>>i*4)&0x0f)>=10)

/*当10,11…时,显示‘a‘,‘b‘,…‘f‘,*/

myputchar(((n>>i*4)&0x0f)-10+‘a‘);

else myputchar(((n>>i*4)&0x0f)+‘0‘);

}

/*

*在很多嵌入式系统中,并不存在PC一样的标准显示设备,

*通过修改该函数,可以将字符“ch”发送到串口,或者目

*标系统中的LED、LCD等显示器件。这样,就可以在脱

*离开发系统情况下显示调试信息,从而调试目标系统的软

*件或硬件。

*/

void myputchar(int ch)

{

……;/*此函数可供修改,将字符“ch”送到SBUF或其他显示器件就可以了*/

}

4 超级终端软件的使用

打开Windows的“超级终端”软件,再打开“hypertrm”,新建一个终端会话。在该会话的“属性u35774设置u32456终端仿真”菜单下,将终端仿真类型设置为VT100[5];在“属性u35774设置 u32456终端设置u23383字符集”菜单下设置字符集为“ASCII”;在“属性u36830连接到u37197配置u24120常规 u26368最快速度”下设置通信波特率和目录系统一致,并将该对话框下“仅以该速度连接打开”设置选中;在“属性u36830连接到u37197 配置u36830连接u36830连接首选项”下设置传送数据位数、校验方式。完成后,连接好RS-232串口线,就可以在超级终端窗口显示目标系统的调试信息了。

在用超级终端显示时,唯一要求发送的数据必须以ASCII码形式发送(上述printf()函数就是如此)。如果要求交互式双向数据传送,请参考VT100文档[5]。对于字符和控制的说明,这里不再描述。

当然,在不方便使用PC机的情况下(如某些工业现场),可以自制一个简单带串口的LED或LCD的ASCII显示终端来专门显示的调试信息。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭