首页 / 一种软件调试系统及调试方法

一种软件调试系统及调试方法失效专利 发明

技术领域

本发明涉及一种软件调试系统及调试方法。 背景技术
随着硬件设计和制造技术的快速发展,嵌入式系统已经被广泛应用于工 业、通讯、家电等各个领域。同时,随着功能的不断增强,嵌入式系统的体 系结构也越来越复杂。嵌入式系统已经从最初仅由单片机和简单的程序代码 组成,发展到了包含功能强大的处理器、丰富的外部设备接口和复杂的操作 系统及应用软件。
图1是一个嵌入式系统软硬件结构的示意图。如图1所示,与PC (个人
电脑)系统类似,嵌入式系统可以分为软件系统和硬件系统两部分,分别称 为嵌入式软件和嵌入式硬件。
其中,嵌入式软件通常可以分为:应用层、驱动层、硬件读写层等部分 (软件层)。各部分通常都包含多个软件功能模块,各软件功能模块又分别 由一个或多个可以相互调用的子程序(通常称为函数)组成。
嵌入式硬件包含:处理器、MCU(微控制器)、芯片等。
为了满足用户的需求,目前大多数嵌入式系统,如手机,数码相机等都 包含丰富的功能,造成其中包含的嵌入式软件的程序量越来越大、复杂度也 越来越高,这给嵌入式软件的开发和测试带来了极大的挑战。
由于嵌入式系统不具备PC系统的开发和测试软硬件条件和能力,因此 初期的开发和测试通常需要借助在PC端运行的由芯片厂商提供的模拟开发 环境。但是,模拟开发环境与真实的嵌入式系统环境有着许多本质的区别, 在模拟开发环境中完成初期的开发和测试后,还是需要将经过编译的程序通 过PC与嵌入式系统之间的接口 ,例如USB (Universal Serial Bus,通用串行
总线)、UART (Universal Asynchronous Receiver/Transmitter,通用异步孑妾收 器/发送器)等下载到嵌入式系统中实际测试运行,并根据测试运行的结果进 行修改。在这一阶段,PC端的调试工具已经无法直接使用,PC端的主要作 用是向嵌入式系统发送调试命令,并根据嵌入式系统的输出判断嵌入式软件 的工作状态是否正常,如图2所示。
很显然,采用现有技术中的上述方法,在开发测试(以下称为调试)的 中后期,将程序下载到嵌入式系统运行后,只能对嵌入式软件进行黑盒测试 (也称作数据驱动测试),这通常需要预先设计非常复杂的测试数据,而且 无法快速准确地找到软件的缺陷(BUG);并且,采用现有技术中的上述方 法,即使只对一个函数进行了修改,也需要在重新编译后对整个软件系统进 行下载,调试的效率4艮低。

具体实施方式

近几年来,随着软件工程学的发展,软件系统通常都有非常清晰的层次 结构及调用关系,不会出现跨层的函数调用,通常也不会由低层函数调用高 层函数(下层函数对上层函数的"调用"通常采用上层函数对下层函数调用
的返回参数来实现);例如,图1中的应用层不会直接调用硬件读写层,只 会通过驱动层调用硬件读写层进行硬件读写操作;而且硬件读写层也不会直 接对驱动层等上层程序进行调用。
对于这种分层的嵌入式软件,可以考虑分层进行调试,即在PC端运行 部分软件层,同时在嵌入式系统运^f亍部分软件层,并随着测试工作的进展逐 渐增加在嵌入式系统中运行的程序(函数),直至整个软件系统都正常地在 嵌入式系统中运行。
为了便于在PC端和嵌入式系统进行分层调试,本发明定义了两个变量: 系统调试级别(System Debug Level,简称SDL),软件层调试级别(Layer Debug Level,简称LDL),并为各软件层分配一个软件层调试级别值。软件层调试 级别大于等于(或大于)当前系统调试级别的软件层在PC端运行,其余软 件层在嵌入式系统运行。
下面将结合附图和实施例对本发明进行详细描述。
图3是本发明实施例软件调试系统的结构示意图。本发明的软件调试系 统用于对可运行于PC端和嵌入式系统的待调试软件进行调试,本实施例以 对包含三个软件层的待调试软件为例对本发明进行描述。
如图3所示,软件调试系统包含:PC端和嵌入式系统端;PC端包含: 调试控制单元、与运行于PC端的所属软件层相连的调试级别判决器、PC端 调试接口;嵌入式系统端包含:与运行于嵌入式系统的各待调试软件层相连 的嵌入式调试接口。
调试控制单元用于设置PC端的当前系统调试级别,以及运行于PC端的 各软件层的软件层调试级别;
此外,调试控制单元还可以用于向最高的软件层(即最先被调用的软件
层,本实施例中的软件层A)发送调试命令以启动调试。
其中,运行于PC端的三个待调试软件层:软件层A (LDL = 3 )、软件 层B (LDL = 2)和软件层C (LDL=1),与运行于嵌入式系统中的三个待调 试软件层:软件层A,、软件层B'和软件层C,分别对应,在实际开发过程中, 运行于PC端和嵌入式系统的各对应软件层可以用相同的软件代码经过不同 的预编译处理命令和预编译宏(例如,C语言中的:#if、弁ifdef等)生成。也 就是说,PC端的各待调试软件层与嵌入式系统中相应的软件层相比,基本功 能相同,差别仅在于运行环境不同。
为PC端的每一软件层都配置一调试级别判决器(调试级别判决器A、调 试级别判决器B和调试级别判决器C),每一调试级别判决器用于截获对所 属软件层的函数调用,并判断本软件层的软件层调试级别是否大于等于当前 的系统调试级别:如果是,则对本软件层的相应函数进行调用,否则将该函 数调用转化成相应的调试命令(或者说进行相应的调试命令函数的调用), 通过PC端调试接口发送至嵌入式调试接口,并由嵌入式调试接口进行嵌入 式系统中的对应软件层相应函数的调用。
PC端调试接口用于在接收各调试级别判决器发送的调试命令时(或者说 PC端调试接口提供的调试命令函数被各调试级别判决器调用时),向嵌入式 调试接口发送对应的调试命令;并接收嵌入式调试接口反馈的调试应答(即 函数调用的返回值),并将调试应答发送给相应的调试级别判决器。
嵌入式调试接口用于接收PC端调试接口发送的调试命令,并根据调试 命令的名称(或者称为标识)和参数(如果有参数),调用嵌入式系统中运 行的对应函数,并将函数调用的返回值发送给PC端调试接口。
PC端调试接口和嵌入式接口之间可以通过USB、 UART等硬件接口 (图 中未示出)相连,进行上述调试命令和调试应答的发il/接收。
下面以两个例子来说明如何通过PC端的调试级别判决器发起对嵌入式 系统的各软件层函数的调用。
例1 (无返回值):
设软件层B中包含函数:Bl(参数l,参数2),嵌入式系统中软件层B, 的对应函数为:Bl,(参数l,参数2) ; B1和B1,都没有返回值。需要注意 的是,本文中为了描述方便,分别为PC端和嵌入式系统中的对应函数起了 不同的名称(例如上述B1和B1,) , 1t实际上PC端和嵌入式系统中的对应 函数名称通常是相同的。
当软件层A中的函数对B1进行调用时,调试级别判决器B截获到该函 数调用,并将其转换为如下调试命令(可以称为无返回值函数调用请求):
SetCommand ( 'B1,,参数l,参数2);
调试级别判决器B通过PC端调试接口将上述调试命令发送至嵌入式调 试接口。嵌入式调试接口接收到该命令后,根据SetCommand函数的第一个 参数'B1'获知需要调用软件层B'中的函数Br,因此将SetCommand函数 的第二个和第三个参数作为Bl,的输入参数进行函数调用。
例2 (有返回值):
设例1中的函数B1和B1,的返回值为一整数值;
当软件层A中的函数对B1进行调用时,调试级别判决器B截获到该函 数调用,并将其转换为如下调试命令(可以称为有返回值函数调用请求):
GetCommand ( 'B1,,参数l,参数2);
调试级别判决器B通过PC端调试接口将上述调试命令发送至嵌入式调 试接口 。嵌入式调试接口接收到该命令后,根据GetCommand函数的第 一个 参数'B1,获知需要调用软件层B,中的函数B1,,因此将GetCommand函数 的第二个和第三个参数作为Bl,的输入参数进行函数调用,得到返回值RET1;
嵌入式调试接口通过以下调试应答(可以称为函数调用应答)将返回值 发送给PC端调试接口:
RetCommand ( 'B1, , RET1);
PC端调试接口接收到上述命令后,根据第一个参数'B1,将返回值RET1 返回给调试级别判决器B。
具体实现时,可以在PC端调试接口中实现上述无返回值函数调用请求
和有返回值函数调用请求的发送功能,即在PC端调试接口实现SetCommand 函数和GetCommand函数,由各调试级别判决器调用SetCommand函数和 GetCommand函数,实现对嵌入式系统中各软件层函数的调用。当然,也可 以省去PC端调试接口,在各调试级别判决器中实现上述无返回值函数调用 请求和有返回值函数调用请求的发送功能。
此外,为了实现调试级别判决器的函数调用截获功能,可以采用以下两 种方式之一对PC端的各软件层程序和调试级别判决器进行修改:
方式一:为软件层中会被其它软件层调用的函数生成统一的调用接口 , 在该调用接口中进行软件层调试级别与当前的系统调试级别大小关系的判 断,并根据判断结果调用本软件层函数,或通过PC端调试接口向嵌入式系 统发送调试命令。采用这种方式时,需要为每一软件层设置一个调试级别判 决器,对软件层的某一函数的调用,是通过将该函数的名称(标识)作为参 数对该软件层的调试级别判决器进行调用实现的,因此调试级别判决器中需
例如,调试级别判决器B的对外输入一调用接口函数,名称为:Debug_B, 可以采用以下形式调用软件层B的函数B1 (参数l,参数2):
Debug—B ( 'B1,,参数l,参数2)。
方式二:在软件层的各函数体内部进行软件层调试级别与当前系统调试 级别大小关系的判断,并根据判断结果执行本函数的正常流程,或通过PC 端调试接口向嵌入式系统发送调试命令。采用这种方式时,调试级别判决器 包含在各软件层的各函数中,即需要为每一函数设置一调试级别判决器。但 是,经过预编译处理命令和预编译宏编译生成的嵌入式系统中运行的软件层 函数中不包含调试级别判决器功能。
图4是本发明实施例软件调试方法流程图,本流程同样以包含三个软件 层的待调试软件为例对本发明的调试方法进行描述。如图4所示,该方法包
括如下步骤:
401:分别编译生成在PC端运行的可执行程序和在嵌入式系统运行的可 执行程序,并将嵌入式系统运行的可执行程序下栽到嵌入式系统。
402: PC端的调试控制单元设置当前系统调试级别SDL、以及运行于PC 端的各软件层的软件层调试级别LDL。
SDL可以用一个全局变量实现,以便各调试级别判决器在截获到函数调 用时随时读取。
403:调试控制单元调用软件层A中的函数,启动调试过程。 在调试过程中重复进行以下操作:
404:调试级别判决器截获到对本软件层函数的调用后,判断本软件层的 软件层调试级别LDL是否小于SDL:如果小于,则执行步骤405;否则执行 步骤406。
405:调试级别判决器将接收到的函数调用转换成调试命令,通过PC端 调试接口发送至嵌入式系统,嵌入式调试接口根据接收到的调试命令中包含 的函数名称进行相应的函数调用;如果该被调用函数有返回值,则将返回值 发送给PC端调试接口 , PC端调试接口将返回值发送给调试级别判决器。
406:调试级别判决器对PC端运行的被调用函数进行调用,如果该被调 用函数有返回值,则将返回值返回给调用函数。
采用本发明的调试方法时,通常先将系统调试级别设置为较小的值,以 便充分利用PC端强大的调试能力在PC端运行较多的程序;例如在图3所示 的系统中,首先将系统调试级别设置为2 (如果设置为1就是在PC端运行所 有程序,不在本文的讨论范围内),此时只有最低的软件层(即最后运行的 软件层,软件层C)在嵌入式系统中运行,其它各软件层在PC端运行。
随着调试过程的进行,越来越多的软件层在嵌入式系统中能够可靠运行 时,逐渐将系统调试级别设置为较大的值,即在嵌入式系统运行较多的程序, 直至所有程序都在嵌入式系统中运行。
此外,如果采用本发明的系统和方法,待调试软件需要满足以下条件:
(1)被跨软件层调用的函数的返回值不能是指针值(例如:指向一个整 数的指针、指向一个数组的指针等);如果是指针值,当该函数本身运行在 嵌入式系统,而被PC端调用时,PC端无法获得该指针值所指向的实际值或 实际的对象。
(2 )尽量不要使用可以被修改且可以被多个软件层读取并使用的全局变 量,以避免PC端和嵌入式系统的不一致。
需要注意的是,本文没有提到PC端的调试工具以及调试工具与各待调 试软件层的连接关系,这是由于PC端调试工具种类繁多,与待调试软件层 的关系也复杂多变,甚至没有一个清晰的界限。最主要的是PC端调试工具 的使用以及调试工具与待调试软件层的关系属于现有技术,本发明并没有进 行修改,也没有进行特殊的限定,因此不属于本发明的讨论范畴。
根据本发明的基本原理,上述实施例还有多种变换方式,例如:
( 一 )在上述实施例中按照软件层由高到低(即被调用的顺序由先到后) 的顺序依次分配由大到小的LDL值;在本发明的其它实施例中,也可以按照 相反的顺序分配LDL值,在这种情况下,各软件层的调试级别判决器的判断 准则应当变为:
LDL值小于等于(或小于)当前SDL值的软件层在PC端运行;其余软 件层在嵌入式系统运行。
还可以再进一步对SDL进行扩展,将其作为一个集合,例如PC端运行 级别集合,或嵌入式运行级别集合(统称为系统运行级别集合)。对于图3 所示实施例,当SDL-2时,如果釆用PC端运行级别集合的概念,则该集合 中包含的元素为{2, 3},如果采用嵌入式运行级别集合的概念,则该集合中 包含的元素为{1}。
(二 )上述实施例中为每一软件层或每一^皮调用函数设置一调试级别判 决器;在本发明的其它实施例中,也可以为整个待调试软件设置一个调试级
别判决器,所有跨软件层的函数调用都需要被该调试级别判决器截获,并在 该调试级别判决器经过上述调试级别判断后4艮据判断结杲对PC端或嵌入式 系统的相应函数进4亍调用。
(三) 由于系统调试级别可以动态调整,因此调试控制单元可以提供一 个用户接口 ,使调试人员可以在调试过程中动态设置新的系统调试级别值, 以实现无需暂停调试(更无需重新编译)就可以调整在PC端和嵌入式系统 中运行的软件层的数量。
当然,调试人员还可以通过调试控制单元的用户接口动态调整各软件层 的软件层调试级别达到上述目的。
(四) 虽然本发明的上述实施例中,待调试软件具有清晰的层次关系和.
调用关系,例如,不会跨软件层进行函数调用,下层函数不会调用上层函数; 但是这并不意味着本发明的调试系统和方法不能应用于不满足上述条件软件 系统。
因此,我们可以将上述软件层称为函数集合,每一函数集合具有不同的 运行级别值,因此运行级别值可以作为函数集合标识。

当前第1页 第1页 第2页 第3页