首页> 中国专利> 统一处理多个子程序执行回应的固件架构方法及相关装置

统一处理多个子程序执行回应的固件架构方法及相关装置

摘要

提供一种装置控制的固件程序架构方法及相关装置。该固件程序是由一处理器来执行,以控制一硬件电路的运作。其中该固件程序中设有多个子程序以分别定义该硬件电路的不同运作,而该多个子程序被区分为数个不同的阶层,阶层较低的子程序用来定义该硬件电路较简单的运作,而阶层较高的子程序则呼叫多个较低阶层的子程序以定义出该硬件电路较复杂的运作;而各个低阶子程序会将该硬件电路对应运作的结果记录于一错误记录码。其中当该硬件电路进行某运作而未达到该运作的预期结果时,该硬件电路应进行一对应的回复运作。为了控制该硬件电路进行必要的回复运作,该固件程序中设有一错误处理子程序,进行对应该高阶子程序中各低阶子程序的回复运作。

著录项

  • 公开/公告号CN1536480A

    专利类型发明专利

  • 公开/公告日2004-10-13

    原文格式PDF

  • 申请/专利权人 联发科技股份有限公司;

    申请/专利号CN03110369.3

  • 发明设计人 许汉文;蔡明宪;

    申请日2003-04-10

  • 分类号G06F9/40;

  • 代理机构北京市柳沈律师事务所;

  • 代理人蒲迈文

  • 地址 台湾省新竹市新竹科学工业园

  • 入库时间 2023-12-17 15:39:00

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2023-04-28

    专利权有效期届满 IPC(主分类):G06F 9/40 专利号:ZL031103693 申请日:20030410 授权公告日:20061025

    专利权的终止

  • 2006-10-25

    授权

    授权

  • 2004-12-29

    实质审查的生效

    实质审查的生效

  • 2004-10-13

    公开

    公开

说明书

技术领域

本发明涉及一种固件架构方法及相关装置,特别是涉及一种以分层管理、错误回复集中处理来减少固件程序复杂度的方法与相关装置。

背景技术

在现代化的信息社会中,信息、影像、数据资料都是以电子形式的讯号来传输、储存及处理的,而各种各样用来存取电子讯号的电子系统、装置,小至手机、大至计算机,也就成为现代信息社会不可或缺的用品。一般来说,在电子装置中,多半设有一处理器(或称微处理器)统合操控电子装置的各种运作;而在功能繁复、多样的电子装置中,由于操控的程序比较复杂,就要用特定的程序码来记录各种操控程序进行的相关步骤及过程;处理器执行程序码,就能实现电子装置的不同功能。这样的程序码,即被称之为固件程序码;而固件程序码多半被储存于电子装置中的非易失性存储器(像是闪速存储器)中,方便处理器读取、执行。另外,像在计算机系统这种功能更为复杂多样的电子系统中,计算机的各种周边装置本身就具有自己的处理器及对应的固件程序码;计算机的主机本身仅需发出高阶的控制指令至周边装置的处理器,该周边装置的处理器就会执行该周边装置本身的固件程序码,控制其周边装置的实际运作。举例来说,计算机系统中的光盘机本身就具有其处理器及对应的闪速存储器,以储存光盘机本身的固件程序码。当计算机的主机要读取一光盘片上的数据时,仅需向光盘机指定该笔数据在光盘片上的地址,光盘机的处理器就会执行本身的固件程序码,协调光盘机中诸如主轴马达(spindle)、激光读取头(pick-up head)等等机电元件的运作(像是主轴马达要达到特定的转速,读取头要移动、锁定至特定的位置,接收光盘片上反射的激光等等),实际完成主机的要求。

请参考图1。图1为一典型周边装置12配合一主机10运作时的功能方块图。周边装置12为一典型的电子装置,其中即设有一处理器16,用来主控周边装置12的运作。除此之外,周边装置12中还设有一易失性的缓中存储器22(像是随机存取存储器)、一非易失性的储存存储器24(像是闪速存储器)以及一用来实现周边装置12功能的硬件电路18。周边装置12通常电连于主机10,以接收主机10的操控指令而运作。主机10可以为一计算机主机,其中设有一中央处理器14A、一北桥电路14B、一南桥电路14C、一显示卡14E、一显示器14F、一易失性的存储器14D(像是随机存取存储器)。中央处理器14A用来主控主机10的运作,存储器14D用来暂存中央处理器14A运作时必需的数据、程序,显示卡14E用来处理影像讯号,以将主机10运作的情形于显示器14F显示为影像画面。北桥电路1 43用来控制显示卡14E、存储器14D与中央处理器14A之间的数据传输;南桥电路14C则通过北桥电路14B电连于中央处理器14A,与主机10配合运作的周边装置12即通过与南桥电路14C间的电连接(像是通过一IDE总线的电连接)而得以和主机10交换指令、数据。

在周边装置12中,除了主控周边装置12运作的处理器16外,缓冲存储器22用来暂存周边装置12运作期间必需的数据;而硬件电路18中设有一编解码器20A、一讯号处理器20B及一伺服模块20C。由于主机10、周边装置12间往来传输的指令、数据需要符合一定的格式、协定(protocol),故编解码器20A会将主机10传至周边装置12的指令、数据解码,再由处理器16依据解码后的指令、讯号来操控周边装置12;同理,由周边装置12回传至主机10的数据也会由编解码器20A加以适当地编码,以符合主机10、周边装置12间数据交换的格式及协定。伺服模块20C则受控于处理器16,以实际执行周边装置12的主要功能;其所存取得的数据、讯号会由讯号处理器20B加以讯号处理。举例来说,若周边装置12为一用来存取光盘片数据的光盘机,则伺服模块20C中会设有一主轴马达28A、一读取头28B等等机电元件。主轴马达28A用来带动光盘片28C转动;读取头28B则可沿一滑轨28D滑动,以存取光盘片上不同轨道(track)上的数据。伺服模块20C由光盘片28C读到的数据,会经过讯号处理器20B的讯号处理,再经由处理器16的安排储存入缓冲存储器22中,让主机10可通过编解码器20A取得缓冲存储器22中的这些数据;这样主机10就能通过光盘机的周边装置12读取到光盘片28C上的数据。同理,若主机10要将数据写入至光盘片28C上,则会将数据通过编解码器20A传输至缓冲存储器22,再由处理器16的控制,利用伺服模块20C将这些暂存于缓中存储器22的数据写入至光盘片28C。

如前所述,周边装置12的处理器16会依据记录于程序中的操控程序控制周边装置12的运作,而储存于非易失性储存存储器24中的固件程序码26,就是用来记录这些操控程序。处理器16执行固件程序码26,就可操控周边装置12进行各种不同的运作。

请参考图2A(并一并参考图1)。图2A为已知技术中,固件程序码26典型程序结构的示意图。固件程序码26的程序可分为两大类,一为接口程序组IF0、一为伺服程序组SR0。伺服程序SR0中包括有多个子程序(subroutine,图2中示出了子程序R1、R2A-R2B、R3A-R3B、R4A-R4B、R5A-R5C、R6A-R6B及R7A-R7B做为代表),各个子程序用来控制硬件电路18中的各电路进行某种特定的运作。举例来说,某个子程序可控制伺服模块20C中的读取头28B由滑轨28D上的某个位置移到另一位置,另一个子程序则可控制读取头28B调整其激光功率的大小,等等。接口程序组IF0中也可包含多个子程序,接口程序组IF0的主要功能则是用来根据主机10的指令,呼叫伺服程序组SR0的对应子程序,以操控硬件电路18实现主机10指定的功能。伺服程序组SR0执行后的结果,也会再由接口程序组IF0的执行而回报至主机10。举例来说,若主机10要求周边装置12读取光盘片上的某段数据,接口程序组IF0就会呼叫伺服程序组SR0中定义有数据读取操控程序的子程序;处理器16执行此子程序,就能操控硬件电路18,完成数据读取的工作。若子程序顺利完成,可发出工作完成的讯息(像是将讯息存在一变数中),再由接口程序组IF0依此讯息控制周边装置12对主机10回传相关的讯号,知会主机10其工作的结果。

一般来说,由于现代电子装置的功能日趋多元,装置内部的操控程序、固件程序码也越来越复杂。为了缩短固件程序码的研发时程,信息业者多半是由多个固件工程师协同运作,各个固件工程师负责撰写一部分的子程序,再统合至固件程序码中。如本领域的技术人员所知,子程序可将特定的操控程序模块化,方便重复利用。举例来说,在光盘机中,不论是开机后的初始化动作、要读取光盘片上特定部分的数据,或是要将数据写入至光盘片上的某一部分时,可能都要控制读取头28B由滑轨28D上的某一位置移动到另一位置,而此控制读取头28B移动的程序码就可模块化于一子程序中。而在操控光盘机进行开机初始化动作、读取数据、写入数据的不同子程序中,就能呼叫(call)这个控制读取头移动的子程序,以操控读取头28B移动。这样一来,开发各个子程序的固体工程师就不必在开机初始化动作、读取数据、写入数据的各个子程序中重复编写控制读取头移动的程序码。

虽然子程序的运用能在不同的操控程序中共用相同的子程序,便利固件程序码的开发,但在已知技术中,却缺乏对子程序呼叫的控制管理。尤其是当各子程序是由不同的固件工程师开发时,开发某一子程序A的固件工程师可能会呼叫其他固件工程师所开发的子程序B,但子程序A的固件工程师并不一定清楚子程序B中的运作细节,可能子程序B中又要呼叫另一子程序C;子程序C中又另外呼叫了子程序D,等等。这样一来,各子程序间互相呼叫的运作流程就会越来越复杂而难以掌控。关于此情形,请再参考图2A。图2A中的各箭号就用来表示图2A中各个子程序互相呼叫的流程。举例来说,根据接口程序组IF0的呼叫,处理器16要执行伺服程序组SR0中的子程序R1(箭头A1代表子程序R1开始被执行)。在子程序R1中先后呼叫了子程序R2A及R2B,故箭头A2代表子程序R2A开始被执行,子程序R2A执行完后,接下来的箭头A3代表子程序R2B被执行。子程序R2B本身又呼叫了子程序R3A、R3B,故在子程序R2B完成前,要先如箭头A4所指示,先执行子程序R3A,再依箭头A5,执行子程序R3B。子程序R3B中又先后呼叫了子程序R4A、R4B,故程序又如箭头A6、A7所指示,在执行子程序R4A后,开始执行子程序R4B。子程序R4B中又呼叫了子程序R5A、R5B及R5C,故在子程序R4B完成前,又要如箭头A8、A9及A10,依序完成子程序R5A及R5B。在执行子程序R5C时,因为子程序R5C本身又先后呼叫了子程序R6A、R6B,故要如箭头A11指示的顺序先执行子程序R6A。而子程序R6A中又先后呼叫了子程序R7A、R7B,故程序执行的顺序就如箭头A12、A13所示,先后执行了子程序R7A、R7B后,才能如箭头A14所示般继续执行子程序R6A,完成子程序R6A后再继续如箭头A15所示执行子程序R6B。在执行完子程序R5C中呼叫的两个子程序R6A、R6B后,才能再如箭头A16的指示般继续子程序R5C。子程序R5C结束后依箭头A17的顺序回到子程序R4B,继续执行子程序R4B在呼叫子程序R5A至R5C后剩下的操控程序。子程序R4B完成后,如箭头A18的指示回到子程序R3B的执行。子程序R3B完成后,呼叫子程序R3A、R3B的子程序R2B才能继续执行(如箭头A19)。等子程序R2B执行完后,执行的流程才会如箭头A20所指引,继续回到子程序R1的执行。等子程序R1完成后,就能如箭头A21的指示,将子程序R1执行的结果回传至接口程序组IF0。

由上所述可知,子程序的呼叫若无适当的管理,很有可能会使执行流程变得复杂,难以追踪。举例来说,开发子程序R1的固件工程师可能只因子程序R2B的功能符合其操控程序中的某一步骤,故在子程序R1中呼叫了子程序R2B,却忽略了子程序R2B中还会连串地呼叫子程序R3A、R3B,而子程序R3B又要呼叫其他的子程序。这样一来,开发子程序R1的固件工程师就不能掌控子程序R1执行时的真正流程。若开发子程序R1的固件工程师还要自行追踪子程序R2A的执行流程,又失去了子程序将程序码模块化而方便运用的意义。

另外,复杂、冗长的执行流程也会大量耗用周边装置12本身的处理器资源。举例来说,如本领域技术人员所知,当子程序R1在执行期间要执行其所呼叫的子程序R2A时(如箭头A2),子程序R1中各变数的值要暂存入缓冲存储器22中配置的堆栈(stack),不能释放。接下来在子程序R2B执行时,因其呼叫了子程序R3A、R3B,故又要先将子程序R2B中的各变数值暂存入堆栈中,不能释放。在继续执行子程序R3A、R3B时,又要在呼叫子程序R4A、R4B之前,先将子程序R3B执行期间的相关变数值暂存入堆栈中,不能释放。换句话说,在后续的执行流程中,当某一子程序A呼叫的子程序B未完成前,子程序A的变数都必需要暂存于堆栈中,不能释放。可想而知,若是执行流程中有连串的子程序呼叫(也就是在某一子程序未执行完成就要执行另一子程序),暂存在堆栈中的变数值就越来越多,大量耗费缓冲存储器22中的存储空间。

除此之外,冗长、繁复的子程序连串呼叫也会使整体程序的除错(debug)更为困难。一旦程序错误(bug)发生,固件工程师势将检查执行流程中的各个子程序,才能找出程序错误的症结所在。另外,在针对某一子程序除错时,由于固件工程师无法获悉执行流程中前后子程序执行的情形,也增加了除错时的困难。举例来说,当固件工程师在检查子程序R4B时,因为无从得知子程序R3A、R3B以及子程序R5A至R5C的执行情形,将难以判断子程序R4B是否运作正常。因为子程序R4B若有程序错误,可能是子程序R3A本身出错而影响子程序R4B的执行,或是因子程序R5A至R5C的程序错误而造成子程序R4B的整体错误。

除了上述缺点之外,连串的子程序呼叫也可能造成周边装置12运作错误(error)难以正确回复。由于周边装置12中的固件程序码26是用来整合周边装置12中各机电元件运作情形的,若固件程序码26执行期间有某机电元件失常(或使用者突然改变对周边装置的控制),就会打断固件程序码26正常的执行流程,造成周边装置12的运作错误;此时就要进行对应的错误回复(error recovery)运作,以恢复周边装置12的正常运作。举例来说,若光盘机在存取光盘片数据期间遭到突然的撞击震动而使得读取头28B的位置改变,光盘机可能就要进行重新锁轨(或另行寻轨)的回复运作,以使光盘机回复正常的数据存取状态。而固件程序码26中,当然也要包含错误回复的操控流程,以控制周边装置12在运行错误发生时,进行回复运作。关于此情形,请参考图2B。图2B与图2A相同,都用来显示已知技术中固件程序码26程序结构的示意图。不过,图2B中更进一步地绘出已知技术错误回复机制的实施方法。如图2B所示,在处理器16执行子程序R3B而控制周边装置12运作时,若周边装置12发生运作的错误,就会在步骤R3S的逻辑控制中进行至子程序R8A、R8B,以操控周边装置12进行回复运作;等子程序R8A、R8B执行无误后,子程序R1的执行流程才会继续如箭头A19的指示回到子程序R2B的执行。

不过,在已知技术中,由于缺乏对错误回复的管理,也容易在子程序连串呼叫的复杂执行流程中,造成不正确的错误回复。举例来说,如图2B所示,子程序码R5A本身也包括了错误回复的机制;若周边装置12执行子程序码R5A时发生运作错误,就会由步骤R5S的逻辑控制进行至子程序R9,以进行错误回复。然而,开发子程序R3B的固件工程师在子程序R3B中呼叫了子程序R4A、R4B后,可能就忽略了子程序R4B呼叫的子程序R5A中,已包含了对子程序R5A错误回复的机制,使得在负责子程序R3B错误回复的子程序R8A、R8B中又再度重复与子程序R5A错误回复相关的操控流程。重复进行的错误回复可能会导致执行流程的迟滞,甚至导致周边装置12额外的运作错误。同样地,由于开发子程序R3B的固件工程师未察觉子程序R4B最终会呼叫到子程序R6A,也会使得错误回复的子程序R8A、R8B中未包含对应子程序R6A运作错误的回复运作。如此一来,一旦子程序R6A执行期间周边装置12发生运作错误,周边装置12也无法进行正确的错误回复。换句话说,在已知技术下,因为在子程序连串呼叫的执行流程中缺乏对错误回复的管理,有可能会使运作错误得不到适当的错误回复,或进行过多、冗余的错误回复,或是没有进行任何错误回复。

总的来说,因为在已知技术在固件程序码中缺乏对子程序呼叫及错误回复的有效管理,使得已知技术中的固件程序码架构复杂,难以追踪、除错,可读性较低,而且执行时会大量消耗周边装置中的处理器数据,还容易因错误回复缺乏管理而影响周边装置的正常运作。

发明内容

因此,本发明的主要目的在于提供一种对固件程序码新的架构方法及相关装置,能有效管理固件程序码中各子程序相互呼叫的秩序,并统一对各种运作错误进行错误回复,以增加对错误回复的管理,克服已知技术的缺点。

在已知技术中,由于对固件程序码中的各个子程序相互呼叫并没有一定的管理规范,导致已知技术下的固件程序码会形成复杂的连串呼叫,不仅程序的可读性甚低,难以追纵、除错,且在执行时会消耗大量的处理器资源。同样地,已知技术也缺乏对各子程序错误回复机制的管理,会导致周边装置无法对运作错误采取有效的错误回复、或是重复错误回复运作,甚至是无法采取有效的错误回复。

在本发明中,则提出两基础原则以管理一周边装置的固件程序码中各子程序相互呼叫、进行错误回复的架构。首先是依照各子程序对应运作的复杂程度将各子程序分类为不同阶层的子程序。阶层较低、较后的子程序用来定义周边装置较单纯的运作。阶层较高、较前的子程序则可呼叫多个低阶子程序以定义出对周边装置较复杂的操控程序。由于各高阶子程序是以呼叫不同低阶子程序的方式来组合出各种操控程序,故可有效管理各子程序间互相呼叫的秩序,并易于控制固件程序码执行流程中各子程序连串呼叫的情形。

其次,本发明还设有一错误处理子程序,用来统合各子程序对应的错误回复。当周边装置在执行各子程序时,会依照子程序中的程序将周边装置本身进行实际运作的结果记录于一错误记录码;等到高阶子程序完成后,周边装置才会执行错误处理子程序,依照错误记录码中记录的内容来操控周边装置进行对应的错误回复运作。换句话说,各子程序本身并不会进行错误回复运作,而是另行于错误处理子程序中统一定义对应各子程序的错误回复运作。这样一来,就可避免在子程序连串呼叫的过程中启动不正确的错误回复。

附图说明

图1为一典型周边装置与主机配置的功能方块图。

图2A、2B为图1固件程序码已知结构的示意图。

图3为本发明中周边装置与主机配置的功能方块图。

图4为图3中固件程序码结构的示意图。

图5A至图5D示出了图4中相关子程序程序码的示意图。

图5E示出了图4中错误处理子程序程序码的示意图。

图5F为图4中固件程序码执行流程的示意图。

图6为本发明另一实施例中固件程序码结构的示意图。

图7A示出了了图6中一主要子程序程序码的示意例。

图7B为图7A中子程序执行流程的流程图。

图8示出了了图6中一第一阶子程序程序码的示意例。

图9A、9B示出了图6中错误处理子程序程序码的示意例。

图9C为图9A、9B中错误处理子程序进行流程的流程图。

附图标号说明

10、30主机                    12、32周边装置

14A、34A中央处理器            14B、34B北桥电路

14C、34C南桥电路              14D、34D存储器

14E、34E显示卡                14F、34F显示器

16、36处理器                  18、38硬件电路

20A、40A编解码器              20B、40B讯号处理器

20C、40C伺服模块              22、42缓冲存储器

24、45储存存储器              26、46固件程序码

28A、48A主轴马达              28B、48B读取头

28C、48C光盘片                28D、48D滑轨

A1-A21、F1-F17箭头

EH错误处理子程序

IF0、IF接口程序组

SR0、SR伺服程序组

50A-50J、52A-52B程序区段

R3s、R5s、72A-72D、74A-74F步骤

R1、R2A-R2B、R3A-R3B、R4A-R4B、R5A-R5C、R6A-R6B、R7A-R7B、

R8A-R8B、R9、A01_1-A02_1、B01_2-B07_2、C01_3-C03_3、D01_4-D02_4、

E01_5-E03_5子程序

具体实施方式

请参考图3。图3为本发明中一周边装置32配合一主机30运作的功能方块示意图。主机30可以是一计算机系统的主机,其可设有一中央处理器34A、一北桥电路34B、一南桥电路34C、一存储器34D、一显示卡34E及一显示器34F。周边装置32则可以是计算机系统中用来扩充主机功能的周边装置,像是光盘机、硬盘机等等;周边装置32中设有一用来主控周边装置32运作的处理器36、一用来在周边装置32运作期间暂存数据的易失性缓冲存储器42(像是一随机存取存储器)、一非易失性的储存存储器45以及一用来实现周边装置32功能的硬件电路38。在主机30中,中央处理器34A用来主控主机30的运作,易失性的存储器34D(像是随机存取存储器)则用来暂存主机30运作期间所必需的资料、数据;显示卡34E用来处理影像数据,以将主机30运作的情形在显示器34F上显示为影像画面。北桥电路34B用来控制显示卡34E、存储器34D及中央处理器34A之间的数据往来传输。通过电连于北桥电路34B的南桥电路34C,主机30和周边装置32就能交换数据、指令。在周边装置32中,硬件电路40C中设有一编解码器40A、一讯号处理器40B、一伺服模块40C。由主机30传至周边装置32的指令数据由编解码器40A加以解码,再由处理器36接收、处理。伺服模块40C存取的数据、讯号则可由讯号处理模块40B进行讯号处理。而伺服模块40C中设有用来实现周边装置32功能的机电元件;举例来说,若周边装置32为一光盘机,则伺服模块40C中可包括有一用来带动光盘片48C转动的主轴马达48A、一可沿滑轨48D移动的读取头48D,等等。储存存储器45可以为一闪速存储器,处理器36即是执行储存存储器45中储存的固件程序码46,以在接受主机30的控制指令后,操控硬件电路38进行周边装置32的预设功能。

本发明的主要目的在于提出一种新的固件程序码架构模式。本发明提出两种固件程序码架构的原则。首先,依本发明的原则,固件程序码不同的子程序可区分为不同的阶层。阶层较低、较后阶的子程序用来定义周边装置32较基本、较简单、功能较为单一的运作。阶层较高,较前阶的子程序用来呼叫较低阶的子程序,以组合出较复杂、功能较为完整的操控程序,或是较复杂的逻辑。此处所谓的较复杂的逻辑,是指当某逻辑条件为真时,要进行一连串较复杂的操控程序;当该逻辑条件为伪时,又要进行另一连串较复杂的操控程序。在本发明中,这样的复杂逻辑,就可用较高阶的子程序来整合。本发明披露的另一原则是,统一以一错误处理子程序来管理、执行其他各个子程序所需的错误回复。换句话说,当周边装置32在执行一高阶子程序所呼叫的各个低阶子程序时,即使发生运作上的错误,也不会立即进行对应的错误回复运作,而是将运作错误发生的情形记录于一错误记录码。等高阶子程序结束后,周边装置32才会执行错误处理子程序,根据错误记录码中记录的错误发生情形而呼叫对应的子程序,以进行错误回复运作。而用来定义错误回复运作的子程序,也可称之为回复子程序。以错误处理子程序来统一管理各子程序对应的回复运作,就能让固件程序码46正常运作的执行流程与错误回复进行的流程两者独立,使正常运作执行流程的运作以及错误回复机制都变得更单纯,对固件工程师来说,程序的控管、追踪、除错和程序的可读性都可大大的提高。

为进一步说明本发明实施的情况,请参考图4。图4为本发明中固件程序码46架构的示意图。如前所述,固件程序码46中的子程序可分为两大类,一为接口程序组IF,另一组为伺服程序组SR。伺服程序组SR中的各个子程序用来定义周边装置32各种不同的操控程序,接口程序组IF中的子程序则根据主机30的控制指令呼叫伺服程序组中对应的程序,使周边装置32进行主机30控制指令所要求的运作。同理,周边装置32也可执行接口程序组IF中的子程序,将周边装置32执行伺服程序组SR中各子程序的结果编成适当格式的数据,回报至主机30。为了说明上的方便,在不妨碍本发明技术披露的情形下,以下将假设本发明是实施于伺服程序组SR中的各个子程序。

如前所述,本发明是将各子程序归类为不同的阶层。在图4中的实施例,即将伺服程序组SR中的各个子程序分组为五个不同的阶层,最高阶(最前阶)的子程序有子程序A01_1、A02_1等等(图4中绘出两个作为代表),其次的第二阶子程序中则有子程序B01_2、B02_2、B03_2、B04_2到B07_2等等,第三阶的子程序包括有子程序C01_3、C02_3、C03_3等等,第四阶子程序则有子程序D01_4、D02_4等等,最低阶(最后阶)的子程序则包括有子程序E01_5到E03_5等等;另外,子程序EH则是错误处理子程序。最低阶的子程序E01_5、E02_5等等子程序用来定义周边装置32较基本、较单纯(没有复杂逻辑)的运作,甚至只是用来设定周边装置32运作期间必要的参数。较高阶的子程序则用来呼叫不同的低阶子程序,以组合出较为复杂的操控程序及较为复杂的逻辑。像是第四阶的子程序D01_4、D02_4就可以呼叫各个不同的第五阶子程序,来组合出不同的操控程序。同理,第三阶的子程序C01_3、C02_3及C03_3可以呼叫第四阶、第五阶的子程序,组合出比第四阶子程序更复杂的操控程序。第二阶的子程序B01_2等等则能进一步地呼叫第三阶、第四阶、第五阶的各个子程序,组合出更复杂、功能更完整的操控程序。最后,到最高阶的第一阶子程序,则能呼叫第二阶至第五阶的各种子程序,共同组合出功能最完整、也最复杂的操控程序或最复杂的逻辑。

在本发明的较佳实施例中,除了最低阶的子程序可以互相呼叫外,其他阶的子程序中,属于同一阶层的子程序均不互相呼叫。举例来说,图4中最低阶的子程序E01_5可以呼叫子程序E02_5及E03_5;也就是说,子程序E01_5在执行期间可以先执行子程序E02_5及E03_5,等子程序E03_5完成后,再执行子程序E01_5中剩下的操控程序。不过,较高阶的各个子程序中,属于同一阶层的各个子程序皆不互相呼叫。举例来说,在第三阶的子程序C01_3、C02_3及C03_3不会互相呼叫,也就是在(举例而言)子程序C02_3执行期间,执行流程不会去执行其他的第三阶子程序,直到子程序C02_3执行完毕,执行流程才有可能去执行其他的第三阶子程序。此外,在本发明中,较低阶的子程序也不呼叫较高阶的子程序。举例来说,若周边装置32有某一操控程序需要依序执行子程序E01_5、E02_5以及D01_4,此时应以定义一第三阶子程序来整合呼叫这三个较低阶的子程序,而不是另行定义第四阶、第五阶的子程序来呼叫这三个本属第四阶、第五阶的子程序E01_5、E02_5及D01_4。

藉由本发明上述呼叫秩序的安排,固件程序码46就能避免复杂的子程序连串呼叫。在最低阶的子程序(也就是图4中的第五阶子程序)中,由于最低阶的子程序仅用来定义周边装置32最基本、最单纯、功能也较为单一的动作,故最低阶子程序间的相互呼叫,并不会形成复杂、难以追踪的连串呼叫,也不会大量消耗处理器36的处理器资源。较高阶的子程序因为有较为复杂的功能及逻辑,故本发明由高阶子程序来呼叫低阶子程序,并限制同一阶层子程序的互相呼叫,就能有效避免子程序间复杂无秩序的连串呼叫。换句话说,依本发明的原则来管理子程序间的呼叫后,就能有效控制子程序间相互连串呼叫的执行流程。举例来说,在图4中的五阶实施例中,第一阶的子程序可呼叫第二阶的子程序、第二阶的子程序会呼叫第三阶的子程序、第三阶的子程序会呼叫第四阶的子程序、第四阶的子程序会呼叫第五阶的子程序,但子程序连串呼叫的次数大致上就会限制于四次,不会再增加子程序连串呼叫的复杂度(如前所述,第五阶子程序的相互呼叫几乎不会增加子程序连串呼叫的复杂度);这就是因为实施了本发明所披露的高阶至低阶的呼叫秩序,以及同一阶层子程序不互相呼叫的原则。试以一反例来思考,若第一阶子程序呼叫了一第二阶子程序B01_2、而子程序B01_2又呼叫了同一阶子程序B02_2,则子程序连串呼叫的次数就会至少增加一次。若某一子程序E02_5又呼叫了一高阶的子程序,像是子程序B02_2,那么子程序连串呼叫的次数及复杂度又会大幅增加,因为子程序E02_5呼叫了子程序B02_2后,子程序B02_2又会呼叫第三阶、第四阶到第五阶的子程序。无限制、无秩序地让各个子程序互相呼叫,正是已知技术中无法控制子程序连串呼叫复杂度的原因。相较之下,利用本发明所披露的原则来管理子程序相互间的呼叫后,就能有效控制子程序连串呼叫的次数及复杂度,也不影响利用子程序来整合各种操控程序、减少重复程序码的目的。

除了阶层化的呼叫秩序外,本发明还以一错误处理子程序EH(见图4)来整合不同操控程序运作错误所对应的错误回复。配合错误处理子程序EH的运作,各子程序会将运作错误的情形记录于一作为错误记录码的全域变数(global variable),让各个子程序皆可以存取此一错误记录码的值。为进一步说明此情形,请参考图5A至图5D(并一并参考图4)。图5A至图5D示出的是子程序A01_1、B01_2及C01_3、D01_4的程序码的示意例。图5A中也定义了后续说明所使用的一些巨集(像是巨集ChkStatus等等)。在此处(及后续)所示出的程序码,皆是以C程序语言的格式来示意各子程序的内容,但在实际实施时,本发明中的各子程序当然可以使用其他的程序语言来形成。另外,在不妨碍本发明技术披露的情形下,详细的程序码(像是常数、变数、部分函式的宣告、定义等等)皆已省略;本领域的技术人员应已可获得足够的技术披露以实施本发明。如图5A所示,在伺服程序组SR执行期间,是以一全域变数_bLevel来代表现行子程序的阶层;就如图4所显示的,在第一阶子程序执行期间,变数bLevel的值应为1;同理,在执行第二阶到第五阶子程序时,变数_bLevel的值分别为2到5。当子程序A01_1被执行前,变数_bLevel的值应被设为0。此外,阵列全域变数_bErrorCode即为错误记录码。

如图5A所示,当第一阶子程序A01_1被执行时,会将变数_bLevel加1,代表固件程序码46的执行流程正在进行一第一阶子程序。接下来子程序A01_1会执行图5A中的程序区域50A,依据一状态变数_fgSelectB01_2的值进行逻辑判断;若变数_fgSelectB01_2为真,则继续呼叫第二阶子程序B01_2;否则呼叫子程序B02_2。子程序B01_2、B02_2皆会回传一字节的值,分别代表周边装置32在执行子程序B01_2、B02_2后进行对应运作的结果。若子程序B01_2、B02_2回传一常数READY的值,代表周边装置32在进行子程序B01_2或B02_2时进行顺利,并没有发生运作错误。相反地,若周边装置32在执行子程序B01_2发生运作错误,子程序B01_2就不会回传常数READY的值。如图5A所示,若子程序B01_2回传的值不是常数READY,子程序A01_1就会在错误记录码_bErrorCode的一个元素中(也就是_bErrorCode[1]),记录下代表子程序B01_2运作错误的代号(即常数B01_Err的值),再将变数_bLevel重设为0,并中止子程序A01_1的执行,回传常数值(!READY),代表子程序A01_1执行期间发生运作错误;此时错误记录码_bErrorCode[1]中即以常数B01_Err记录了此运作错误是在执行子程序B01_1时发生的。同理,若周边装置32在执行子程序B02_2的过程发生运作错误,子程序A01_1也会中止执行,回传常数值(!READY)代表其发生了运作错误,并在错误记录码_bErrorCode[1]中记录常数B02_Err的值,代表运作错误是在子程序B02_2执行期间发生的。

同理,接下来子程序A01_1会依序执行至程序区段50B、50C;以程序区段50B为例,子程序A01_1会在此程序区段中呼叫子程序B03_2,控制周边装置32进行子程序B03_2对应的运作。若周边装置32在依据子程序B03_2进行对应运作却发生运作错误时,子程序B03_2也就不会回传常数READY的值;此时子程序A01_1就会依据子程序B03_2回传的值判断周边装置32已发生执行错误,并在错误记录码_bErrorCode[1]中记录常数B03_Err的值,代表子程序B03_3执行期间发生了运作错误。接下来子程序A01_1就结束执行,回传常数值(!READY),代表子程序A01_1在执行期间因周边装置32的运作错误而中断执行。换句话说,子程序A01_1在呼叫其他较低阶(低子程序A01_1本身所在的第一阶)子程序后,可根据这些子程序回传的值,判断周边装置32是否发生运作错误,并在错误记录码_bErrorCode中记录运作错误发生的情形(像是在执行哪一个低阶子程序时发生运作错误),就像在程序区段50A、50B、50C中一样。相对地,若周边装置32在执行子程序A01_1所呼叫的各个低阶子程序时均没有产生错误,子程序A01_1就会一直被顺利执行至程序区段50D,而在错误记录码_bErrorCode[1]中记录常数READY的值,代表子程序A01_1所呼叫的所有低阶子程序均顺利完成,而子程序A01_1本身也会回传常数READY的值,代表子程序A01_1本身也已经顺利完成,并结束子程序A01_1的执行。请注意在子程序A01_1中,在记录错误记录码_bErrorCode时所用的程序指令“_bErrorCode[_bLevel--]=…”不仅在错误记录码_bErrorCode[1]中记录了对应常数值,也将变数_bLevel的值减1,使其回复到子程序A01_1被执行前的值。如图5A所示,在以程序指令“_bErrorCode[_bLevel--]=…”设定错误记录码的值后,接下来就会结束子程序A01_1的执行,以程序指令“Return(…)”回传对应常数值,故将变数_bLevel的值减小,就可将此变数的值回复到子程序A01_1本身被呼叫前的值,与子程序A01_1一开始时的程序指令“++_bLevel”对应。

如图5B所示,在属于第二阶的子程序B01_2中,也呼叫了较低阶(第三阶至第五阶)的其他子程序,像是子程序C01_3。不过,在子程序B01_2开始时,会先将全域变数_bLevel加1,使变数_bLevel成为2(因为子程序B01_2是被子程序A01_1所呼叫,而变数_bLevel在子程序A01_1执行期间已被设为1),代表固件程序码46执行至一第二阶子程序。就如图5B中的程序区段50E所示,若是周边装置32在执行子程序B01_2所呼叫的子程序C01_3时发生运作错误,子程序C01_3就不会传回常数READY的值,而子程序B01_2也就会在错误记录码_bErrorCode[2]中记录常数C01_Err的值,代表周边装置32在进行子程序C01_3对应的运作时发生运作错误。接下来子程序B01_2本身也就结束执行,回传常数值(!READY),代表子程序B01_2在执行期间发生运作错误。相对地,若子程序B01_2顺利完成,一直进行至程序区段50F,就会在错误记录码_bErrorCode[2]中记录常数READY的值,并在恢复变数_bLevel的值后,结束子程序B01_2。请注意,因为子程序C01_3为一更低阶的子程序,其运作的结果会被记录于阵列变数的错误记录码_bErrorCode的次一元素(也就是_bErrorCode[2])。换句话说,本发明可利用错误记录码_bErrorCode的不同元素(或可视为一表列数据型态下的不同栏位)来记录在不同阶子程序所发生的运作错误。像是在图5A、5B中,当周边装置32在执行子程序A01_1所呼叫子程序B01_2时,若在进行子程序B01_2呼叫的子程序C01_3时发生运作错误,不但子程序B01_2会设定错误记录码_bErrorCode[2]为常数C01_Err,子程序A01_1也会设定错误记录码_bErrorCode[1]为常数B01_Err。依此类推,错误记录码就能以阵列变数的不同元素,清楚记录各阶子程序运作错误发生的情形。

如图5C所示,子程序C01_3中呼叫了较低阶的子程序D01_4。图5D中的子程序D01_4则呼叫了最低阶的子程序E01_5、E02_5。当然,在这些子程序中,也可以有相对应的程序区段来设定变数_bLevel的值,并将各子程序运作的情形记录于错误记录码_bErrorCode。本领域技术人员应已能由图5A、5B的讨论得知相关细节实施的方式;在不妨碍本发明技术披露的情形下,不再赘述。除了像图5A至5D所示,可在错误记录码_bErrorCode[1]、_bErrorCode[2]等元素中分别记录不同阶层子程序运作错误发生的情形之外,本发明也可利用错误记录码_bErrorCode[0]来记录最高阶(也就是第一阶)子程序运作错误发生的情形。对照图5A所示,在子程序A01_1执行结束后,就可将一代表子程序A01_1的代码记录于错误记录码_bErrorCode[0]。举例来说,若周边装置32在执行子程序A01_1期间,在执行到子程序B01_2中的子程序C01_3时发生运作错误,子程序B01_2、子程序A01_1就会依序中止执行,而错误记录码_bErrorCode[0]、_bErrorCode[1]、_bErrorCode[2]记录的就分别为一常数值A01(代表是在进行子程序A01_1进行期间发生错误)、常数B01_Err的值、常数C01_Err的值。当然,某些简单、低阶的子程序也可能不必回传运作的结果,或是不必将是否发生运作错误记录于错误记录码。

如前所述,本发明的特点之一,就是使用错误处理子程序EH来统一处理周边装置32在各子程序进行期间所发生的运作错误,以进行对应的错误回复。请参考图5E。图5E示出的程序码即为图4中错误处理子程序EH(其子程序的名称为ErrorHandler)的示意例。在最高阶的子程序(举例来说,第一阶子程序A01_1)执行完毕后,本发明就会继续执行错误处理子程序EH,对子程序A01_1执行期间所发生的运作错误进行对应的错误回复。参照图5A可知,在子程序A01_1结束后,变数_bLevel的值应该已回复为0。而如图5E所示,当子程序A01_1结束、错误处理子程序EH开始执行之初,错误处理子程序EH会先检查错误记录码_bErrorCode[0]的值,判断是否有运作错误需要进行错误回复。若有运作错误,则进行至程序区段50G,根据之前进行的第一阶子程序为何,判断应进行的错误回复。其中变数_bFunctionCode即用来代表之前进行的第一阶子程序,而此变数的值即记录于错误记录码_bErrorCode[0]。举例来说,若变数_bFunctionCode的值为常数A01,代表之前进行的为子程序A01_1,应进行至程序区段50H,以进行对应子程序A01_1的错误回复;若为另一常数A02,代表之前进行的是子程序A02_1,应进行至程序区段50I,进行对应子程序A02_1的错误回复,以此类推。如图5E中的示意例,在确定之前进行的子程序为A01_1后,在程序区段50H,还会进一步检查错误记录码_bErrorCode[1]中记录的值;举例来说,若错误记录码_bErrorCode[1]中记录的是常数B01_Err的值,就可于程序区段50J中进一步确认错误记录码_bErrorCode[2]中记录的错误情况。就像图5E中程序区段50J所定义的,若错误记录码_bErrorCode[2]中记录的是常数C01_Err,错误处理子程序EH就会呼叫另一子程序B07_2,操控周边装置32进行对应的错误回复。换句话说,当周边装置32在执行子程序A01_1中的子程序B01_2而于进行子程序C01_3时发生运作错误后,应该要进行子程序B07_2来进行对应的错误回复(子程序B07_2也就是一回复子程序)。而错误处理子程序EH就会在子程序A01_1中止后,依据错误记录码_bErrorCode中记录的错误发生情况来呼叫子程序B07_2,完成必要的错误回复。

归纳上述描述可知,本发明中是以错误处理子程序EH统一管理各种运作错误的对应回复动作。错误处理子程序EH会根据错误记录码_bErrorCode中记录的运作错误发生情形(像是在哪一阶层的哪一个子程序发生运作错误),呼叫对应该种情形的回复子程序来进行错误回复。换句话说,所有运作错误对应的错误回复运作都已经依照运作错误发生的情形分门别类地记录于错误处理子程序中,便于错误回复的集中管理。这样一来,就不必像已知技术一般,在子程序中各自处理错误回复,导政错误回复的执行复杂、重复,或无法有效完成。请参考图5F。图5F与图4相同,显示的是固件程序码46中各子程序的架构。总结图5A至5E的各个子程序,其执行的流程就如图5F所示。首先,由接口程序组IF中的程序依主机30(见图3)的控制指令而要进行伺服程序组SR中的子程序A01_1,以操控周边装置32进行对应的运作。如箭头F1所示,子程序A01_1开始被执行,再依箭头F2的指示,执行至子程序B01_2或B02_2(如图5A所示);以下假设是执行子程序B01_2。而子程序B01_2呼叫了较低阶的子程序C01_3、子程序C01_3呼叫了较低阶的子程序D01_4、子程序D01_4又呼叫了最低阶的子程序E01_5、E02_5,其执行流程就如箭头F3至F11所示。子程序B01_2执行完成后,就可继续执行子程序A01_1所呼叫的子程序B03_2、B04_2,如箭头F12至F13所示。在执行完子程序A01_1后,执行流程就会如箭头F14所指示进行至错误处理子程序EH,由错误处理子程序EH来针对子程序A01_1执行期间所发生的运作错误进行对应的错误处理。在错误处理子程序EH完成后,执行流程就能如箭头F17的指示回到接口程序组IF。在错误处理子程序EH动作期间,错误处理子程序EH也会依照错误回复运作的情形重设错误记录码_bErrorCode。举例来说,若错误回复运作顺利,错误处理子程序EH就可将原本记录有错误发生情形的错误记录码_bErrorCode,改记为没有错误发生的情形。或者,有某些错误无法由伺服程序组SR中的子程序来完成错误回复(像是在周边装置32运作期间,使用者突然中断周边装置32的正常运作,周边装置32也只能等待使用者的下一个控制指令,才能继续运作),接口程序组IF也可根据此种情况下的错误记录码_bErrorCode,将运作错误的情形进一步回传至主机30。

为更进一步说明本发明实际实施的情形,以下将描述本发明的精神实际实施于一可烧录式光盘机(光盘烧录器)的情况。换句话说,本发明于图3中的周边装置32为一光盘机,光盘机中的处理器36则执行固件程序码46以控制此光盘机的运作。首先请参考图6。图6为固件程序码46中各子程序架构的示意图。固件程序码46中仍包括了接口程序组IF及伺服程序组SR;以下就以本发明实施于伺服程序组SR的情况作为实施例。如图6所示,在本实施例中,伺服程序组SR中的各个子程序被区分为五个阶层,在最高阶的第一阶子程序中包括了子程序SRVStartUp_1、SRVCDQSeek_1等等;次阶的第二阶子程序中有子程序bReadLeadIn_2等等;第三阶子程序则有子程序PowerOnCalibrate_3等等,第四阶中则有子程序bReadQPosition_4、bReadATIPPosition_4等等;在最低阶的第五阶子程序中,则包括有子程序MediaOKInitSetting_5、MoveSled_5及ServoOff_5等等。请注意在各个子程序名称中最后的数字即用来标示该子程序所属的阶层,像是子程序ServoOff_5名称中最后的数字“5”,就用来表示其为第五阶的子程序。在实际运用时,于子程序名称中加入该子程序所属的阶层,将有助于固件工程师清楚辨识各子程序的阶层,使固件工程师更容易遵循本发明中子程序依阶层序向相互呼叫的原则,也更容易追踪固件程序码执行的流程,或是进行程序除错。

除了分属各阶层的子程序外,接口程序组IF可经由一子程序SRVFunction_0来统一呼叫各第一阶子程序,而子程序ErrorHandler_0就是本发明中的错误处理子程序。接下来请继续参考图7A、7B(并一并参考图6)。图7A示出的即为子程序SRVFunction_0程序码的示意例;图7B则为子程序SRVFunction_0执行时的流程图。图7A中也定义了一些常数(像是ENTRY_LEVEL的值为0)及巨集(像是巨集RET)。全域阵列变数_bErrorCode用来记录伺服程序组SR中各阶层子程序运作错误发生的情形。另外,全域变数_bPlayerStatus也可视为另一个错误记录码,用来整合记录各子程序运作错误发生的情形。全域变数_bServoLevel用来记录固件程序码46执行流程进行至哪一阶层的子程序。全域变数_bErrCnt则用来控制错误回复重复进行的次数(将于稍后做进一步说明)。

当固件程序码46的执行流程开始时,接口程序组IF会根据主机30的控制指令,设定变数bFuncName的值,并以此变数的值呼叫子程序SRVFunction_0;而子程序SRVFunction_0就会根据变数bFuncNName的值来呼叫对应的第一阶子程序。就如图7A、7B中所示,若变数bFuncName为一常数START_UP的值,可代表周边装置32要进行初始化的运作(像是光盘机刚开机时),而子程序SRVFunction_0就会对应地呼叫第一阶子程序SRVStartUp_1,以操控周边装置32进行初始化的运作,并在错误记录码_bErrorCode[0]中记录常数START_UP的值。类似地,若变数bFuncName为一常数CD_Q_SEEK的值,可代表作为光盘机的周边装置32要进行快速寻轨;而子程序SRVFunction_0就会对应地呼叫第一阶子程序SRVCDQSeek_1来操控周边装置32进行寻轨,并在错误记录码_bErrorCode[0]中记录常数CD_Q_SEEK的值,以此类推。在第一阶子程序执行完后,子程序SRVFunction随即呼叫错误处理子程序ErrorHandler_0,以对第一阶子程序进行期间发生的运作错误进行错误回复。比较特别的是,在子程序SRVFunction_0中,会以程序指令“do…while”的流程控制,来依据子程序ErrorHandler_0进行错误处理的情形,控制第一阶子程序的重试(retry)。在第一阶子程序进行完毕而进行至子程序ErrorHandler_0时,子程序ErrorHandler_0会依据错误回复的情况重设错误记录码_bErrorCode的值,反应错误回复进行的情况。子程序ErrorHandler_0执行完毕后,子程序SRVFunction_0就会于程序指令“while”中,根据错误记录码的值(此实施例是依据错误记录码_bErrorCode[1]的值是否等于一常数EXIT_SRVFUNCTION的值)判断是否要以程序指令“do…while”重新进行先前呼叫的第一阶子程序,进行重试。

上述的重试控制流程也显示于图7B的流程中;如图7B所示,假设接口程序组是以变数bFuncName为常数START_UP的值来呼叫子程序SRVFunction_0,子程序SRVFunction_0就会由图7中的步骤72A进行至步骤72B、72C;在步骤72C执行子程序ErrorHandler_0时,错误记录码_bErrorCode也可能会改变(子程序ErrorHandler_0的运作情形将在稍后做进一步说明)。结束步骤72C后,子程序SRVFunction_0就会于程序指令“while”(也就是图7B中的步骤72D)中依据错误记录码_bErrorCode[0]的值而决定接下来的流程。若错误记录码_bErrorCode[0]等于常数EXIT_SRVFUNCTION的值,就能进行至步骤72E而结束子程序SRVFunction_0。相对地,若错误记录码_bErrorCode[0]不等于常数EXIT_SRVFUNCTION的值,子程序SRVFunction_0就会重新执行步骤72B、72C,也就是重试;在执行步骤72C时,子程序ErrorHandler_0还是会依据重试后运作错误发生的情形重设错误记录码_bErrorCode的值,再重新进行至步骤72D,判断是否还需进行另一次重试,以此类推。

请参考图8。图8示出的即为第一阶子程序SRVStartUp_1程序码的示意例。当子程序SRVStartUP_1被子程序SRVFunction_0呼叫而开始执行时,会先将变数_bServoLevel加1,代表执行流程已进行至一第一阶子程序。接下来子程序SRVStartUp_1会检查变数_fgKEjtPressed的状态(巨集ChkStatus的定义请参考图7A),此变数是用来代表使用者是否按了周边装置32的光盘片“弹出”钮。若使用者按了此“弹出”钮,子程序SRVStartUp_1就会执行巨集RET,设定错误记录码_bErrorCode[1]的值为常数TRAY_EJECT的值,重设变数_bServoLevel的值为0,并结束子程序SRVStartUp_1。既然使用者按下了“弹出”钮,子程序SRVStartUp_1也就可中止执行。相对地,若使用者未按“弹出”钮,子程序SRVStartUp_1接下来就会根据变数_fgPowerOnInit的值判断周边装置32开机后是否已进行初始化的设定。若否,则进一步呼叫第三阶子程序PowerOnCalibrate_3来操控周边装置32进行开机后初始化的相关校正,并呼叫第五阶子程序MoveSled_5来进行将读取头48B(见图3)移动至某一初始位置。然后子程序SRVStartUp_1又会呼叫第五阶子程序CheckMotorStop_5来检查主轴马达48A(图3)是否已经开始转动,等等。

如图8中的程序区段52A所示,子程序SRVStartUp_1也会依据一变数_fgATIP的值来判断光盘片48C的种类(子程序SRVStartUp_1可在之前先呼叫另一较低阶的子程序以设定此变数的值);若周边装置32在光盘片48C上读不出可烧录式光盘片上独具的预建轨迹的讯号(也就是ATIP,AdsoluteTime In Pre-Groove),代表此光盘片为只读光盘片(也就是一般的CD,Compact Disk)。此时子程序SRVStartUp_1就可以呼叫第四阶子程序bReadQPosition_4来读取只读光盘片上的Q讯号。一般来说,在光盘片用来记录数据的轨道上,会区分出不同的数据帧(frame),用来记录一定量的数据。而每个数据帧都有其地址;而光盘机即是利用由只读光盘片上读出的Q讯号来定址每个数据帧,以依据各数据帧的地址找出某个特定的数据帧。若周边装置32在进行子程序bReadQPosition_4对应的运作时发生运作错误(即无法由Q讯号中解析出数据帧定址的信息,像是光盘片本身有刮损),就会反映在子程序bReadQPosition_4回传的值,而子程序SRVStartUp_1就会执行至巨集RET,在错误记录码_bErrorCode[1]中记录常数bReadQPosition_Err的值,反应子程序bReadQPosition运作的错误,并中止子程序SRVStartUp_1。另一方面,若由变数_fgATIP可知光盘片48C为可烧录式光盘片(像是CD-R、CD-RW光盘片),子程序SRVStartUp_1就会呼叫第四阶子程序bReadATIPPosition_4,以操控周边装置32读取ATIP讯号。相对于只读光盘片中的Q讯号,在可烧录式光盘片中,光盘机则是由可烧录式光盘片上读出的ATIP讯号来为可烧录式光盘片中的数据帧定址。若在子程序bReadATIPPosition_4回传的值反应周边装置32发生了运作错误(无法由ATIP讯号中解析出数据帧定址的信息),子程序SRVStartUp_1也会执行巨集RET,在错误记录码_bErrorCode[1]中记录常数bReadATIPPosition_Err,并结束子程序SRVStartUp_1本身的执行。若子程序bReadATIPPosition_4顺利完成,子程序SRVStartUp_1会继续呼叫第二阶子程序bReadLeadin_2,操控周边装置32读取光盘片48C上的引入区(Lead-In Area)。若周边装置32在进行子程序bReadLeadin_2时发生运作错误(也就是光盘机找不到光盘片上的引入区),子程序SRVStartUp_1就会根据子程序bReadLeadin_2回传的值,判断要进行巨集RET,以设定错误记录码_bErrorCode[1]的值为常数bReadLeadin_Err的值。

换句话说,当周边装置32在执行子程序SRVStartUp_1呼叫的低阶(也就是低于第一阶)子程序时发生运作错误,子程序SRVStartUp_1就可依据这些低阶子程序回传的值设定错误记录码_bErrorCode的值以反应对应的运作错误,并中止子程序SRVStartUp_1本身的执行。相对地,如图8所示,若周边装置32顺利完成子程序SRVStartUp_1呼叫的各个低阶子程序,在执行第五阶子程序MediaOKInitSetting_5以设定周边装置32后续操控所用的参数后,子程序SRVStartUp_1就会进行至程序区段52B,在错误记录码_bErrorCode[1]中记录常数READY的值,代表子程序SRVStartUp_1顺利完成备便,而变数_bLevel的值也被重设为0,最后结束子程序SRVStartUp_1的执行。

请参考图9A至9C。图9A、9B合起来示出的即为错误处理子程序ErrorHandler_0程序码的示意例,图9C则是子程序ErrorHandler_0进行时的流程图。如图9A、9B所示,子程序ErrorHandler_0会先依据错误记录码_bErrorCode[0]的值判断是要对哪一个第一阶子程序进行错误回复的相关操控。由先前于图7A的子程序SRVFunction_0可知,子程序SRVFunction_0已在呼叫第一阶子程序时,于错误记录码_bErrorCode[0]中记录了其所呼叫的第一阶子程序(也就是变数FuncName的值)。等到进行子程序ErrorHandler_0时,就能依据错误记录码_bErrorCode[0]来对各第一阶子程序所可能产生的运作错误作初步分类。

针对不同的第一阶子程序,子程序ErrorHandler_0会进一步根据错误记录码_bErrorCode[1]的值定义对应的错误回复。像是在图9A、9B所示的示意例中所显示的,在子程序SRVStartUp_1执行完毕后(对应错误记录码_bErrorCode[0]为常数START_UP的值),错误记录码_bErrorCode[1]的值可能为常数READY、TRAY_EJECT、bReadQPositin_Err、bReadQTIPPosition_ERr、bReadLeadin_Err等等的值。对照图8中的子程序SRVStartUp_1可知,当周边装置在执行子程序SRVStartUp_1的低阶子程序时发生运作错误,就会在错误记录码_bErrorCode[1]中记录相对应的常数值。以记录于错误记录码_bErrorCode[1]的值做为索引,子程序ErrorHandler_0就能找出这些运作错误个别所对应的错误回复运作。举例来说,如图9A、9B所示,若错误记录码Error_Code[1]中为常数READY的值,代表周边装置32在执行子程序SRVStartUp_1期间没有发生运作错误,子程序ErrorHandler_0就会在错误记录码_bErrorCode[0]中记录常数EXIT_SRVFUNCTION的值,并在另一个作为错误记录码的变数_bPlayerStatus中记录常数READY的值,代表周边装置32已顺利完成子程序SRVStartUp_1的执行;而后子程序ErrorHandler_0就会结束。相对地,若错误记录码_bErrorCode[1]为常数TRAY_EJECT,代表使用者按下了“弹出”钮(请对照图8及相关说明),子程序ErrorHandler除了设定错误记录码_bErrorCode的值外,也会在变数_bPlayerStatus中记录常数TRAY_EJECT的值,代表周边装置32现在状况为光盘片匣弹出的状况;接下来子程序ErrorHandler_0就能结束。

另外,子程序SRVStartUp_1中呼叫的低阶子程序可能会呼叫其他更低阶的子程序,并在错误记录码中记录了更多有关低阶子程序运作错误的信息。举例来说,如图9B中的程序码所示,当错误记录码_bErrorCode[1]中为常数bReadLeadin_Err的值时,子程序ErrorHandler_0还会进一步根据错误记录码_bErrorCode[2]是常数bSeekATIP_Err或是ReadLeadinInfo_Err等等的值来定义不同的回复运作。像是当错误记录码_bErrorCode[2]为常数bSeekATIP_Err的值时,子程序ErrorHandler_0还会再进一步地根据错误记录码_bErrorCode[3]为常数FOCUS_ERROR或是READATIP_ERROR等等的值来判断周边装置32应进行的回复运作。换句话说,若光盘机读不到光盘片上的引入区(对应于常数bReadLeadin_Err),其可能的原因可能是光盘机无法根据ATIP讯号寻轨(对应于常数bSeekATIP_Err)或是无法正确解析出引入区的信息(对应于常数ReadLeadinInfo_Err)。若是光盘机无法根据ATIP讯号寻轨,其可能的原因还包括了光盘机无法正确将读取头激光聚焦于光盘片上(对应于常数FOCUS_ERROR),或是无法读到ATIP讯号(对应于常数READATIP_ERROR)等等。整体来说,针对各种错误运作可能发生的情形,其对应的错误回复运作都已经详细定义于本发明中的子程序ErrorHandler_0,以集中管理错误回复的实施。

除了上述在子程序ErrorHandler_0中依据错误记录码的内容找出对应的错误回复运作外,如前面于图7A、8B讨论时所提到的,在子程序SRVFunction_0执行期间,也可配合错误记录码_bErrorCode[0]的值来控制第一阶子程序重试的进行。如图9A、图9B的程序码所示,子程序ErrorHandler_0会针对不进行重试的情形,在将错误记录码_bErrorCode[0]记录为常数EXIT_SRVFUNCTION的值后,结束子程序ErrorHandler_0。举例来说,当错误记录码_bErrorCode[1]为常数READY或是TRAY_EJECT时,前者代表子程序SRVStartUp_1进行顺利,当然不需重试;而后者代表使用者按下“弹出”钮,周边装置32也应该暂停运作。如图7A及图7B的流程所示,针对这些不需重试的情形,子程序SRVFuncdon_0在执行完子程序ErrorHandler_0后,就会因为错误记录码Error_Code[0]为常数EXIT_SRVFUNCTION的值,而结束子程序SRVFunction_0的执行。而接口程序组IF(请见图6)就可依据错误记录码_bErrorCode或是变数_bPlayerStatus的值,将周边装置32运作的情形回报至主机30。

另一方面,针对要进行重试的错误回复运作,子程序ErrorHandler_0则不会将错误记录码ErrorCode[0]记录为常数EXIT_SRVFUNCTION的值。举例来说,如图9A所示,当周边装置32在子程序SRVFunction_0的操控下结束第一阶子程序SRVStartUp_1的执行而进行至子程序ErrorHandler_0时,或错误记录码ErrorCode[1]为常数bReadQTIPPosition_Err的值,子程序ErrorHandler_0就会先操控周边装置32进行第五阶子程序ServoOff_5,让伺服模块40C(见图3)先停止运作,并重设变数_bPlayerStatus,再于一变数_bErrCnt中加1(参照图7A可知,变数_bErrCnt的初始值应为0)。而如图7A、7B所示,在执行完子程序ErrorHandler_0后,子程序SRVFundtion_0就会在程序指令“while”中因为错误记录码_bErrorCode[0]并不等于常数EXIT_SRVFUNCTION而操控周边装置32再度进行子程序SRVStartUP_1(也就是重试),并在子程序SRVStartUp_1执行结束后第二度进行至子程序ErrorHandler_0。若在重新进行子程序SRVStartUp_1时,并没有发生运作上的错误(或发生的运作错误不需进行重试,像是使用者按下“弹出”钮),在第二度进行至子程序ErrorHandler时,子程序ErrorHandler自然就会于错误记录码_bErrorCode[0]中记录常数EXIT_SRVFUNCTION的值,接下来子程序SRVFunction就会跳出程序指令“do-while”,结束子程序SRVFunction。

相对地,若周边装置32在重试期间而第二度进行子程序SRVStartUp_1时,又发生需要重试的运作错误(像是再度发生对应于常数bReadATIPPosition_Err的运作错误),而在后续再度进行子程序ErrorHandler_0时,子程序ErrorHandler_0就不会将错误记录码_bErrorCode[0]的值设为常数EXIT_SRVFUNCTION的值;在进行对应的错误回复时,也会在变数_bErrCnt中再度累加1。而此变数_bErrCnt就是用来控制第一阶子程序重试进行的次数的。请注意,在图9A、9B的程序码中,针对不需重试的错误处理,子程序ErrorHandler_0在将错误记录码_bErrorHandler_0设定为常数EXIT_SRVFUNCTION后,就会进行至程序指令“return”,结束子程序ErrorHandler_0本身的执行。相对的,针对需要进行重试的错误处理(像是当错误记录码_bErrorCode[1]为常数bReadATIPPosition_Err时),子程序ErrorHandler在累加变数ErrCnt的值后,还会进行至图9B中的程序区段54,检查变数_bErrorCnt的值是否已经累加超过一常数MAX_ERR_CNT;若是,就代表重试进行的次数已经太多,而子程序ErrorHandler_0就会在错误记录码_bErrorCode[0]中记录常数EXIT_SRVFUNCTION的值,以便在固件程序码执行流程回到子程序SRVFunction_0时,强制结束SRVFunction,并由接口程序组IF根据错误记录码等变数,将周边装置32重试多次但都不能正常运作的情形回报至主机30。图9C中总结了子程序ErrorHandler_0的运作情形,其先根据错误记录码_bErrorCode[0]来索引对应的错误运作(像是步骤74A);若错误记录码_bErrorCode的值对应的是不需重试的运作错误(也就是某些第一预设值,像是当错误记录码_bErrorCode[1]为常数READY或是TRAY_EJECT的值时),就可由步骤74B进行至步骤74C,进行对应的错误回复,并在设定错误记录码_bErrorCode[0]为常数EXIT_SRVFUNCTION后,结束子程序ErrorHandler_0。若错误记录码_bErrorCode的值对应的是需要重试的运作错误(也就是第二预设值,像是当错误记录码_bErrorCode[1]符合常数bReadQPosition_Err或是bReadATIPPosition_Err的值时),就可由步骤74D进行至步骤74E,在根据错误记录码_bErrorCode进行对应错误回复后,累加变数_bErrCnt的值,并在步骤74F(对应于图9B中的程序区段54)中检查变数_bErrCnt值是否大于预设的常数MAX_ERR_CNT,以进行重试次数的控管。

总结本发明披露的原则,是将固件程序码中不同的子程序区分为不同的阶层,由低阶的子程序来定义较简单、功能较为单一的运作,高阶的子程序则呼叫低阶的子程序,以定义出较复杂、功能也较完整的运作。而在各子程序间,则以序向的呼叫原则来维持各子程序间相互呼叫的秩序,也就是不由低阶子程序呼叫高阶子程序,同阶层子程序也不互相呼叫(除了最低阶的子程序)。另外,本发明还披露了集中处理错误回复运作的原则,利用错误记录码记录周边装置在执行各阶子程序时运作错误发生的情形,并统一由一错误处理子程序根据错误记录码来操控周边装置进行对应的错误回复运作。在已知技术中,因为缺乏对固件程序码中各子程序相互呼叫的管理,会在各子程序间形成复杂的连串呼叫(也就是在某一子程序尚未结束前,又要先执行另一子程序),不仅不利于执行流程的追踪、除错,程序码的可读性较低,实际执行时又会耗费大量的处理器资源。而在针对运作错误进行错误回复时,已知技术也会因为执行流程的复杂、缺乏管理,而造成错误回复不必要的重复、不正确的错误回复以及不完整的错误回复。相较之下,在实施本发明披露的原则后,各子程序间的阶层序向呼叫能维持执行流程的单纯,使连串呼叫的次数受到有效的控制,不仅能使固件程序码具有较高的可读性,易于管理、追踪、除错,在周边装置实际执行固件程序码时,也能减少其所需的处理器资源。另外,本发明利用错误处理子程序以根据各阶子程序所记录的错误记录来整合不同运作错误所对应的错误回复运作,能将所有的错误回复运作集中管理,避免错误回复不必要的重复,也能确保错误回复的正确性。因为错误记录码中已记录有各阶子程序运作的情形,配合上本发明阶层序向呼叫的原则,就相当于将固件程序码执行的流程及运作情形记录于其中,不论是在固件程序码开发阶段的除错过程里,或是在实际对周边装置进行故障排除时,固件工程师都能经由错误记录码中获知执行流程的相关讯息,方便除错排障的进行。在上述所讨论的实施例中,虽假设固件程序码是用于与主机搭配的周边装置中,但本发明也可适用于单独运作的电子装置中,像是手机、数字相机等等,以有效管理这些装置中固件程序码的结构。在固件程序码中,本发明的原则可分别实施于接口程序组及伺服程序组的各个子程序间;换句话说,接口程序组中的各个子程序也可区分为不同的阶层,并设立属于接口程序组的错误处理子程序。

以上所述仅为本发明的较佳实施例,凡依本发明权利要求书所做的均等变化与修饰,皆应属本发明专利的涵盖范围。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号