专利名称::一种μCOS-Ⅱ移植到ARM7的中断嵌套方法
技术领域:
:本发明涉及软件设计
技术领域:
,尤其涉及一种μCOS-II移植到ARM7的中断嵌套方法。
背景技术:
:μCOS-II操作系统是一个完整的、可移植、可固化、可裁剪、可剥夺、可确定性、占先式实时多任务内核。它总是运行最高优先级的就绪任务。μCOS-II源代码开放,中断嵌套层数可达255层,V2.80版本已可以管理255个任务,源码行数仅约5000行。考虑到一些领域对可靠性、稳定性、强实时性及资源的要求,可以将μCOS-II操作系统移植到电子设备中进行任务的管理。而且,目前很多电子设备需要实现低功耗、小型化、高性能的要求,因此可以采用将μCOS-II移植到ARM7实现。在现有实现方案中,已经出现了将μCOS-II移植到ARM7的相关技术。该技术应用于电子设备时,还需要保证嵌入式软件的强实时性和安全性的要求。但是,由于ARM的现有中断管理机制未提供中断嵌套功能,因此无法满足嵌入式软件的强实时性和安全性的要求。具体来说,ARM的中断管理机制是这样的一旦发生中断,ARM内核自动做出如下动作(1)将状态寄存器(CPSR)的值保存到状态寄存器备份(SPSR)中;(2)通过设置状态寄存器(CPSR),使得强制关中断使能并切换到中断模式(IRQ)下,使得在处理当前中断过程中不接受新中断的插入;(3)在中断模式对应的连接寄存器(LR)中保存返回地址;(4)强制将中断入口地址赋值到指令寄存器(PC),使得中断函数得以执行。在后续中断函数执行过程中,运算的中间值会保存到ARM内部寄存器(R0Rn)中。从上述过程可见,在中断处理过程中不能接受其他中断插入,即无法实现中断嵌套,那么在当前处理中断的优先级较低时,高优先级中断无法得到及时响应,从而降低了系统的实时性。为了解决上述问题,一种简单的方式为在中断处理过程中打开中断使能而实现中断嵌套。但是,打开中断使能后,新中断在插入时,ARM内核会自动做出上述动作,从而将连接寄存器(LR)、内部寄存器(R0Rn)中的值覆盖,导致原来的中断现场被破坏,从而出现执行错误。其中,内部寄存器(R0Rn)中的值被覆盖的问题,可以通过将内部寄存器(R0Rn)的值入栈和中断完成后的出栈来解决。但是,对于连接寄存器(LR)的值存在一种特殊情况,即在第一级中断处理过程中包括调用子函数——跳转指令(BL),且恰好在BL指令执行完成后发生地第二级中断,因为执行BL指令时将返回地址保存在LR中,处理器响应第二级中断时又将第二级中断后的返回地址保存在LR中,两个连续的保存操作使得BL指令的返回地址被覆盖,从而造成在第一级中断中所调用的子函数无法正确返回,使得程序运行出现错误。
发明内容有鉴于此,本发明提供了一种μCOS-II移植到ARM7的中断嵌套方法,能够在出现中断嵌套时,保证程序运行的正确性。该方法应用于μCOS-II操作系统移植到ARM7处理的情况,包括步骤1当产生中断时,ARM内核执行其中断处理;步骤2将现场信息入栈到中断堆栈,所述现场信息包括ARM内部寄存器R0-R12、中断模式下的连接寄存器LR(ikq);步骤3判断当前被中断的对象是任务还是低优先级中断,如果是任务,则执行步骤4,如果是低优先级中断,则执行步骤9;步骤4:将所述现场信息转存到任务堆栈中,调用操作系统进入中断服务函数OSIntEnter();步骤5将ARM从中断模式转换为除中断模式之外的一种选定模式,将现场信息入栈到系统模式对应的堆栈,入栈信息包括R0-R12,所述选定模式下的连接寄存器LR(。h。。sd;步骤6执行应用软件中断处理服务函数;步骤7中断退出前,切换回中断模式;将中断模式下的堆栈指针调整到该级中断发生前的位置,再调用操作系统退出中断服务函数OSIntExit();步骤8从任务堆栈中恢复中断前的任务现场,至此本流程结束;步骤9将ARM从中断模式转换为所述选定模式;步骤10将中断嵌套层数OSIntNesting加一;步骤11执行应用软件中断处理服务函数;步骤12将中断嵌套层数OSIntNesting减一;步骤13中断退出前,切换回中断模式;根据中断模式下的堆栈指针,将中断堆栈中存储的中断前现场信息出栈,至此本流程结束;所述步骤6和步骤11具体包括如下子步骤①应用软件中断处理服务函数开始处保存中断使能寄存器的当前值;②通过设置中断使能寄存器,实现禁止同级中断和低优先级中断;③打开中断使能;④执行应用软件中断处理服务程序;⑤在应用软件中断处理服务函数结束处恢复保存的中断使能寄存器的值。其中,所述选定模式为系统模式或管理模式。根据以上技术方案可见,本发明在中断处理过程中,打开了中断使能,且通过设置中断使能寄存器,禁止同级中断和低优先级中断,只允许高优先级中断打断低优先级的中断过程,从而实现了中断嵌套。而且,在新中断插入时,保存当前现场信息,从而保证内部寄存器(R0Rn)中的值得以保存。此外,进行中断模式到系统模式的切换,保证BL指令的返回地址不被覆盖,从而避免程序运行出现错误。图1为本发明实现中断嵌套的流程图。具体实施例方式下面结合附图并举实施例,对本发明进行详细描述。为实现中断嵌套,且在出现中断嵌套时,保证程序运行的正确性,程序设计要解决两个关键问题a.下一级中断使能前,必须要保护好前一级中断的现场信息,该现场信息主要包括LR、CPSR、RORn。此问题较易实现,将需要保护的信息入栈即可。b.中断处理过程中对BL进行保护,防止在中断中调用子函数时无法正确返回。基于此,本发明提供了一种μCOS-II移植到ARM7的中断嵌套方法,其基本思想是,在重新使能中断之前改变处理器模式,采用非中断模式下的LR记录BL指令所使用的返回地址,这样,当新中断发生时,就不会造成LR寄存器冲突,从而在中断中调用的子函数可以正确返回。图1示出本发明μCOS-II移植到ARM7的中断嵌套方法的实现流程,如图1所示,其流程包括以下步骤步骤1当产生中断时,ARM内核执行中断处理。该中断处理包括将CPSR的值保存到SPSR中;强制关中断使能,并切换到中断模式下;在中断模式对应的LR中保存返回地址,中断模式对应的LR这里记为LR(ikq);强制将中断入口地址赋值到指令寄存器(PC)。步骤2将现场信息入栈到中断堆栈,现场包括R0-R12,LR_);RO-Rl2为ARM内部寄存器。步骤3判断被中断的对象是任务还是低优先级中断,如果是任务,则执行步骤4,如果是低优先级中断,则执行步骤9。步骤4:将现场信息转存到任务堆栈中;调用操作系统进入中断服务函数OSIntEnter()。步骤5将ARM从中断模式转换为除中断模式之外的一种选定模式,由于在系统模式下可以对所有的寄存器进行操作,故本发明实施例采用的是在重新使能中断前将ARM切换到系统模式(SYSTEM)。将现场信息入栈到系统模式对应的堆栈,入栈信息包括R0-R12,j^iv(SYSTEM);RO-Rl2为ARM内部寄存器。由于ARM在不同的模式下使用各自的LR,因此在切换为SYSTEM模式后,执行BL指令时,会使用SYSTEM模式下的LRjPj^iv(SYSTEM)°本步骤中,切换为系统模式后的入栈操作,其作用是当三层或三层以上的中断嵌套发生时,保证LR(system)中的值不会因为被覆盖而丢失。步骤6:执行应用软件中断处理服务函数。在应用软件中断处理服务函数中尚需做如下动作应用软件中断处理服务函数开始处保存当前中断使能寄存器的值;通过设置中断使能寄存器,实现禁止同级中断和低优先级中断;打开中断使能;由于中断使能寄存器被设置为禁止同级中断和低优先级中断,从而使得更高优先级的中断得到响应;执行应用软件中断处理服务程序;在应用软件中断处理服务函数结束处恢复保存的使能寄存器的中断值。步骤7中断退出前,切换回中断模式;将中断模式下的堆栈指针调整到该级中断发生前的位置,再调用操作系统退出中断服务函数OSIntExit();步骤8从任务堆栈中恢复中断前的任务现场,至此本流程结束。步骤9将ARM从中断模式转换为系统模式。步骤10将中断嵌套层数(OSIntNesting)加一。该OSIntNesting参数用于函数OSIntExit(),在OSIntExit()函数中,当OSIntNesting为零时,说明要退出任务,继而进行任务切换,否则,继续执行后续操作。该OSIntNesting的用法为操作系统内部固定用法,这里不做详细描述。步骤11执行应用软件中断处理服务函数。该步骤的具体内容与步骤6相同。步骤12将中断嵌套层数OSIntNesting减一。步骤13中断退出前,切换回中断模式;根据中断模式下的堆栈指针,将中断堆栈中存储的中断前现场信息出栈,从而恢复中断前的现场。至此,本流程结束。下面结合上述流程,举一个中断前执行BL指令的例子。假设在执行任务过程中插入中断1,此时ARM内核执行中断处理,从而使得切换到中断模式,且将中断1的返回地址保存到LR(ikq);将任务现场(包括LR(ikq)等)入栈到中断堆栈中。由于被打断的对象为任务,因此执行步骤48;在此期间,模式切换为系统模式,在执行应用软件中断处理服务函数时,执行到BL语句,此时,BL指令的返回地址保存到LR(system)中;BL指令执行完毕后,插入高优先级中断2,此时ARM内核再次执行中断处理,包括切换到中断模式,将中断的返回地址保存到LR(_;然后,将中断现场(包括LR(_等)入栈到中断堆栈中。可见,中断2的返回地址保存到LR(_,而BL指令的返回地址保存到LR(SYSTEM),可见BL指令的返回地址没有被覆盖,保证在中断1中所调用的子函数能够正确返回,避免程序运行出现错误。从以上流程可以看出,在中断处理过程中,打开了中断使能,且通过设置中断使能寄存器,禁止同级中断和低优先级中断,只允许高优先级中断打断低优先级的中断过程,从而实现了中断嵌套。而且,在新中断插入时,保存当前现场信息,从而保证内部寄存器(R0Rn)中的值得以保存。此外,进行中断模式到系统模式的切换,保证BL指令的返回地址不被覆盖,从而避免程序运行出现错误。下面举具体实施例对本发明方案进行详细描述。本实施例以μCOS-II移植到ARM7实现某卫星管理控制单元为例,卫星管理控制单元设备驱动及操作系统软件为嵌入于某卫星管理控制单元内的底层嵌入式系统软件,主要由操作系统、板级支持包(BSP)、接口驱动软件三大部分组成。主要软硬件配置如下操作系统抢占先式实时多任务内核μCOS-II(ν2.84);CPU主频44.2368MHz的ARM7处理器LPC2294;存储器:16KX8bit内部RAM禾口248KX8bit内部FLASH;两片512X16bit外部SRAM。本发明实施例实现了将μCOS-II操作系统移植到LPC2294中,并结合ARM7体系结构的特点解决了中断可重入的问题。将μCOS-II移植到LPC2294中,只需修改编写3个与体系结构相关的文件os_cpu.h,os_cpu_c.c,os_cpu_a.asm。其中,os_cpu_a.asm中操作系统中断处理接口函数0S_CPU_ARM_ExceptHndlr()的设计是实现中断嵌套的关键。为了完整下面分别对各个文件的设计进行详细介绍。1、os_cpu.h文件的编写os_cpu.h文件主要是为了方便将μCOS-II操作系统移植到不同的处理器,主要包括定义与处理器有关的数据类型、与临界区处理有关的中断禁止、中断允许的代码实现、堆栈的增长方向的设置等内容。其中,与临界区处理有关的中断禁止、中断允许的代码实现为由于LPC2294具有程序状态寄存器CPSR,可以直接通过设置CPSR来开、关中断,且用户可以直接获得程序状态寄存器的值,这样就可把该值保存在C语言函数的局部变量中,而不必压到堆栈里。故有关临界区处理采用如下方式,即进入临界区以前,将程序状态寄存器CPSR保存到全局变量中,出临界区后,从全局变量中恢复CPSR,这样可使保存在CPSR中的CPU中断允许标志的状态在临界段前和临界段后不发生改变。其代码为#defineOS_ENTER_CRITICAL(){cpu_sr=0S_CPU_SR_Save();}#defineOS_EXIT_CRITICAL(){OS_CPU_SR_Restore(cpu_sr);}堆栈的增长方向的设置为由高到低。其代码为#define0S_STK_GR0WTH1。2、os_cpu.c文件的编写os_cpu_c.c中包含与移植有关的C函数,包括任务堆栈的初始化函数和一些钩子(hook)函数的实现。任务堆栈的初始化函数用于定义当第一次创建任务时的任务堆栈中上下文的内容(如任务指针、程序状态字等)。这样,当任务获得CPU使用权时,就能把任务堆栈中的初始数据复制到CPU的各寄存器里,从而可使任务顺利启动运行。任务堆栈结构设计为递减方式,结构如表1:<table>tableseeoriginaldocumentpage7</column></row><table><table>tableseeoriginaldocumentpage8</column></row><table>表1钩子函数是为了用户在系统函数中书写自己有特殊应用要求的代码而预置的,在移植中可以为空,但必须要有。3、os_cpu_a.asm文件的编写将μCOS-II操作系统移植到LPC2294中需要用户编写os_cpu_a.asm文件中的四个汇编语言函数启动最高优先级任务函数OSStartHighRdyO、任务切换函数OSCtxSw()、中断中的任务切换函数OSIntCtxSw0和操作系统中断处理接口函数0S_CPU_ARM_ExceptHndlr()。·OSStartHighRdyOOSStartHighRdyO函数是由操作系统启动函数OSStart()函数调用的,功能是运行优先级最高的就绪任务,用户必须先调用初始化函数OSInitOjfyCOS-II自身的运行环境进行初始化。在至少创建了一个任务后便可以调用OSStartO函数进入多任务管理阶段。在OSStartO函数中先调用第一次调度函数0S_SChedNew()获得最高优先级就绪任务的优先级。这样在OSStartHighRdyO中指针OSTCBHighRdy便可以指向优先级最高就绪任务的任务控制块(0S_TCB)。在OSStartHighRdyO中先将操作系统运行标志(OSRunning)的值置为真,表示开始任务的执行;紧接着从具有最高优先级的任务控制块中取得任务的堆栈指针来初始化堆栈指针寄存器SP;然后恢复CPSR,恢复其它的寄存器,便可以开始执行最高优先级的任务了。OSStartHighRdyO函数的处理过程示意如下将操作系统运行标志置为真(TRUE);获得最高优先级任务的TCB指针;获得最高优先级任务堆栈指针并切换到新堆栈;弹出最高优先级任务上下文,从而开始执行之。·OSCtxSw()OSCtxSw()在管理模式中被调用进行任务级的任务切换。首先将当前任务的上下文入栈,然后将栈指针保存到当前任务的TCB块中;将OSTCBCur指向优先级最高的就绪任务,将新任务的上下文装载到任务堆栈中,从而完成了任务切换。OSCtxSwO函数的处理过程示意如下当前任务的上下文入栈;OSTCBCur->OSTCBStkPtr=SP;OSPrioCur=OSPrioHighRdy;OSTCBCur=OSTCBHighRdy;装载新任务的上下文,完成任务切换;·OSIntCtxSw()当中断服务程序退出时要调用退出中断服务函数OSIntExitO。在该函数中当确认中断嵌套层数为O且有比上次被中断任务优先级更高的任务已就绪时,便调用OSIntCtxSw()完成中断级任务切换。OSIntCtxSwO函数的处理过程示意如下OSPrioCur=OSPrioHighRdy;OSTCBCur=OSTCBHighRdy;SP=OSTCBHighRdy->OSTCBStkPtr;装载新任务的上下文,完成任务切换;因为被中断任务的上下文已保存到堆栈中了,故OSIntCtxSwO中没有任务级任务切换所需要的将当前任务的上下文入栈的动作。·OS_CPU_ARM_ExceptHndlr()OS_CPU_ARM_ExceptHndlr()函数是发生中断时,ARM内核进行中断处理后所要调用的函数,其编写是实现本发明中断嵌套的重点。在该函数中编写代码以实现如前流程中步骤213的步骤,其中步骤6所述在应用软件中断处理服务函数中尚需执行的一系列动作,是增加在中断处理服务函数的内容,并非0S_CPU_ARM_Exc印tHndlr()函数中的内容。由于采用了如图1所示的流程,因此当任一中断发生时,先将现场信息保存到当前中断对应的中断堆栈;然后进行判断,若是中断了任务,则需将现场信息还要转存到任务堆栈中;接着调用操作系统进入中断服务函数OSIntEnter(),再将处理器从中断模式切换为除中断模式之外的一种选定模式,例如系统模式或管理模式,再调用应用软件中断处理服务函数,退出中断前要调用操作系统退出中断服务函数OSIntExit()。若是中断了低优先级中断,则将处理器切换为上述选定模式,中断嵌套层数(OSIntNesting)加一,然后调用应用软件中断处理函数。退出中断前要将中断嵌套层数减一并恢复被中断的低优先级中断的上下文。实现了如上所述的中断处理设计后,参见图1的步骤6,在中断服务函数中尚需做如下动作中断服务函数开始处保存中断使能寄存器的当前值,禁止当前中断和低优先级中断,清除中断逻辑并开中断以使更高优先级的中断得到响应;在中断服务函数结束处恢复保存的中断使能寄存器的值。这样便可以安全地实现中断的可重入了。权利要求一种μCOS-II移植到ARM7的中断嵌套方法,其特征在于,该方法包括步骤1当产生中断时,ARM内核执行其中断处理;步骤2将现场信息入栈到中断堆栈,所述现场信息包括ARM内部寄存器R0-R12、中断模式下的连接寄存器LR(IRQ);步骤3判断当前被中断的对象是任务还是低优先级中断,如果是任务,则执行步骤4,如果是低优先级中断,则执行步骤9;步骤4将所述现场信息转存到任务堆栈中,调用操作系统进入中断服务函数OSIntEnter();步骤5将ARM从中断模式转换为除中断模式之外的一种选定模式,将现场信息入栈到系统模式对应的堆栈,入栈信息包括R0-R12,所述选定模式下的连接寄存器LR(choose);步骤6执行应用软件中断处理服务函数;步骤7中断退出前,切换回中断模式;将中断模式下的堆栈指针调整到该级中断发生前的位置,再调用操作系统退出中断服务函数OSIntExit();步骤8从任务堆栈中恢复中断前的任务现场,至此本流程结束;步骤9将ARM从中断模式转换为所述选定模式;步骤10将中断嵌套层数OSIntNesting加一;步骤11执行应用软件中断处理服务函数;步骤12将中断嵌套层数OSIntNesting减一;步骤13中断退出前,切换回中断模式;根据中断模式下的堆栈指针,将中断堆栈中存储的中断前现场信息出栈,至此本流程结束;所述步骤6和步骤11具体包括如下子步骤①应用软件中断处理服务函数开始处保存中断使能寄存器的当前值;②通过设置中断使能寄存器,实现禁止同级中断和低优先级中断;③打开中断使能;④执行应用软件中断处理服务程序;⑤在应用软件中断处理服务函数结束处恢复保存的中断使能寄存器的值。2.如权利要求1所述的μCOS-II移植到ARM7的中断嵌套方法,其特征在于,所述选定模式为系统模式或管理模式。全文摘要本发明公开了一种μCOS-II移植到ARM7的中断嵌套方法在重新使能中断之前改变处理器模式,采用非中断模式下的LR记录BL指令所使用的返回地址,这样,当新中断发生时,就不会造成LR寄存器冲突,从而在中断中调用的子函数可以正确返回。使用本发明能够在出现中断嵌套时,保证程序运行的正确性。文档编号G06F9/48GK101819539SQ201010157129公开日2010年9月1日申请日期2010年4月28日优先权日2010年4月28日发明者刘中伟,占丰,宋光磊,宋庆国申请人:中国航天科技集团公司第五研究院第五一三研究所