我怎样才能将中断实际纳入我的嵌入式应用程序?

时间:2014-09-18 21:52:01

标签: embedded arm powerpc

我正在为ARM平台和PowerPC平台开发嵌入式应用程序。这个应用程序是一个裸机应用程序,所以没有任何操作系统。它将在进入我的主应用程序逻辑所在的无限循环之前执行硬件的所有初始化。

我的主要问题是,是否有任何方法可以使用中断来执行异步行为(思考类似功能的线程)来检查硬件的某些特性以及任何硬件子系统错误,导致重置,记录事件等.I我猜我试图实现像看门狗这样的东西,但我希望它完全异步,并且不需要主应用程序的任何干预(比如踢看门狗)。谢谢!

3 个答案:

答案 0 :(得分:1)

我建议的是一个调用前台处理程序的中央循环。

中断服务程序将值放在某处的某个字节中。

前台处理程序查看该字节

前景和背景"沟通"用那个字节(或某种结构)

这里有一些伪代码

    The_Top_Of_This_Loop:

            Call    Check_What_ISR_01_Did
            Call    Check_What_ISR_02_Did
            Call    Check_What_ISR_03_Did
            Call    Check_What_ISR_04_Did

            Call    Update_The_Rest_Of_The_System

            Jump    The_Top_Of_This_Loop

前景子程序会做这样的事情(再次,伪代码,你写一些真实的东西)

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;                                                       ;
    ; Subroutine name: Check_What_ISR_01_Did                ;
    ;                                                       ;
    ; Looks at the indicator from the background and takes  ;
    ; the appropriate action.                               ;
    ;                                                       ;
    ; On Entry:     Nothing                                 ;
    ;                                                       ;
    ; On Exit:      Reg_00 is messed up, don't believe it   ;
    ;                                                       ;
    ;                                                       ;
    ;                                                       ;
    ;                                                       ;
    ;                                                       ;
    ;                                                       ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


    Check_What_ISR_01_Did:

            Move    Reg_00.Byte, The_ISR_01_Flag    ;The ISR Set this if he did anything
            Cmp     Reg_00.Byte, Nothing_Happened   ;Did anything happen since last time ?
            Jz      We_Are_Done                     ;No, there's nothing to do

            ;                                       ;else yes, so examine what to do
            ;                                       ;and so on
            ;                                       ; blah
            ;                                       ;  blah
            ;                                       ;   blah


    We_Are_Done:

            Return                                  ;End of foreground routine

实际的ISR会做这样的事情......

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;                                                       ;
    ; Interrupt Service Routine 01                          ;
    ;                                                       ;
    ; Checks to see if a button was pushed.                 ;
    ;                                                       ;
    ; On Entry:     Nothing                                 ;
    ;                                                       ;
    ; On Exit:      The_ISR_01_Flag is updated to hold      ;
    ;               a value which the foreground will       ;
    ;               use to make a decision                  ;
    ;                                                       ;
    ;                                                       ;
    ;                                                       ;
    ;                                                       ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


    ISR_01:

            Push    {All The Registers And Flags}   ;This is the background; leave with no trace
            ;                                       ;Do whatever
            ;                                       ; your real
            ;                                       ;  code needs
            ;                                       ;   to do to look
            ;                                       ;    at a button 

            Move    Reg_00.Byte, Nothing_Happened   ;This is a defined constant value somewhere
            Move    The_ISR_01_Flag, Reg_00.Byte    ;The foreground routine will see this
            Jump    We_Are_Done                     ;There's nothing else to do now

    We_Are_Done:

            Pop     {All The Registers And Flags}   ;Don't forget the stack

            IntReturn                               ;End of ISR

同样,这是所有伪代码,使用真实语法等等。

答案 1 :(得分:1)

Round-Robin Scheduling - 您可能需要实现或只是使用已经存在的(其中一些是开放的并且可以通过网络访问)。

循环法(RR)是过程和网络调度程序在计算中使用的算法之一。当通常使用该术语时,时间片以相等的部分和循环次序分配给每个过程,处理没有优先级的所有过程(也称为循环执行)。循环调度简单,易于实现,无需饥饿。循环调度也可以应用于其他调度问题,例如计算机网络中的数据分组调度。这是一个操作系统概念。

为了公平地调度进程,循环调度程序通常采用时间共享,为每个作业提供一个时隙或量子(它允许CPU时间),如果当时没有完成,则中断作业。下次为该进程分配时隙时,将恢复作业。在没有分时的情况下,或者如果量子相对于工作的规模而言很大,那么产生大量工作的过程将比其他过程更受青睐。

Round Robin算法是一种先发制人算法,因为调度程序会在时间配额到期后强制进程退出CPU。

例如,如果时隙为100毫秒,并且job1需要250毫秒的总时间才能完成,则循环调度程序将在100毫秒后暂停作业,并在CPU上为其他作业提供时间。一旦其他作业具有相同的份额(每个100毫秒),job1将获得另一个CPU时间分配,并且循环将重复。此过程将继续,直到作业完成,并且不再需要CPU上的时间。

但是在将RR引入应用程序之前,首先需要能够启用和调整定时器中断及其处理程序。一旦你完成处理计时器IRQ,你甚至可以在其中实现简单的东西或考虑RR或简单的RTOS。

答案 2 :(得分:1)

您可以使用计时器并定期检查硬件特性。但是,如果定时器是常规的并且与时钟同步,则它是同步中断。

任何异步发生的中断(即,不与时钟同步)都可以由ISR处理。在ARM中,它们将中断称为异常。根据硬件验证所需的时间,可以在这样的异常处理程序中进行检查硬件特性的例程。

RTOS的主要目的之一是提供时间限制结果和解决实时异步事件/中断。但是,由于调度程序的存在,RTOS能够处理这样的多个异步任务/中断,而调度程序又依赖于上下文切换。因此,您可能需要在裸机上安装一层薄薄的调度程序。术语中的调度程序类型取决于您的要求。如果时间不是问题,你可以继续推进队列并在你自己的时间处理它,否则你可能需要一个合适的调度程序。