打印
[ZLG-ARM]

(分享)周立功移植 μc/os - Ⅱ 到 ARM7中断宏定义

[复制链接]
2108|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
maoyanketi|  楼主 | 2010-9-26 22:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
经网上(ATMEL单片机学习网 —— **:关于ARM中断宏定义,作者:佚名)查询,终于搞懂了周立功移植 μc/os - 到 ARM7中断的那个宏定义的整个替换过程,花了整整三天时间哟,笨啊!现写出,供那些需要透彻理解移植 μc/os - 到 ARM7的人看,使学习的过程少一点障碍、轻松一些。
一)原文:
周立功的《ARM微控制器基础与实战(第2版)》P392,第7章7.3.6关于中断及时钟节拍中断,
程序清单7.10  IRQ异常处理代码的汇编语言部分

       MACRO
$ IRQ_Label   HANDLER   $ IRQ_Exception_Function
       EXPORT   $ IRQ_Label                                       ;输出的标号                  (1)
       IMPORT   $ IRQ_Exception_Function                 ;引用的外部标号               (2)
$ IRQ_Label
        SUB     LR, LR, #4                                          ; 计算返回地址              (3)
        STMFD   SP!, {R0-R3, R12, LR}                      ; 保存任务环境              (4)
        MRS     R3, SPSR                                        ; 保存状态                       (5)
        STMFD   SP, {R3, SP, LR}^       ; 保存用户状态的R3,SP,LR,注意不能回写   (6)
        LDR     R2,  = OSIntNesting                ; OSIntNesting++                    (7)
        LDRB    R1, [R2]                                                                           (8)
        ADD     R1, R1, #1                                                                    (9)
        STRB    R1, [R2]                                                                        (10)
        SUB     SP, SP, #4*3                                                                   (11)
        MSR     CPSR_c, #(NoInt | SYS32Mode)          ; 切换到系统模式           (12)
        CMP     R1, #1                                                                             (13)
        LDREQ   SP, =StackUsr                                                               (14)
        BL      $ IRQ_Exception_Function      ;调用c语言的中断处理程序15
        MSR     CPSR_c, # (NoInt | SYS32Mode)         ;切换到系统模式           (16)
        LDR     R2, = OsEnterSum     ; OsEnterSum,使OSIntExit退出时中断关闭  (17)
        MOV     R1, #1                                                                               (18)
        STR     R1, [R2]                                                                              (19)
        BL      OSIntExit                                                                               (20)
        LDR     R2, = OsEnterSum  ; 因为中断服务程序要退出,所以OsEnterSum=0(21)
        MOV     R1, # 0                                                                        (22)
        STR     R1, [R2]                                                                        (23)
        MSR     CPSR_c, # (NoInt | IRQ32Mode)    ; 切换回irq模式            (24)
        LDMFD   SP, {R3, SP, LR}^      ;恢复用户状态的R3,SP,LR,注意不能回写(25)
        LDR     R0,  = OSTCBHighRdy     (26)
        LDR     R0, [R0]                         (27)
        LDR     R1, = OSTCBCur             (28)
        LDR     R1, [R1]                          (29)
        CMP     R0, R1                            (30)
        ADD     SP, SP, # 4*3                                                (31)
        MSR     SPSR_cxsf, R3                                                (32)
        LDMEQFD SP!, {R0-R3, R12, PC}^   ; 不进行任务切换     (33)
        LDR     PC, =OSIntCtxSw             ; 进行任务换              (34)
    MEND

相关帖子

沙发
maoyanketi|  楼主 | 2010-9-26 22:30 | 只看该作者
二)解释

1)、为便于对替换过程的理解,根据原文建一简化模型



MACRO

$ IRQ_Label  HANDLER   $ IRQ_Exception_Function

       EXPORT   $ IRQ_Label                                          ;输出的标号            

       IMPORT  $ IRQ_Exception_Function                             ;引用的外部标号     

$ IRQ_Label

      A语句

      B语句

      … …

      C语句

      BL      $ IRQ_Exception_Function                ;调用c语言的中断处理程序    (15)

      L语句

      M语句

      … …

      N语句

      MEND



首先看,$ IRQ_Label 、$ IRQ_Exception_Function 是宏定义的两个参数,且$ IRQ_Label 在本宏中是一个标号,一段程序的入口地址;$ IRQ_Exception_Function 是一个函数,也是一个入口地址、该函数的入口地址。

           请先不要在此纠缠,后面看了才好理解。

           实际要配套以下约定,这个宏才起作用,可惜这点在书中没明确提出,且给出的“中断服务程序C语言部分示意代码”如下,对初学者来说,反转极易造成误导。

           Void           ISR(Void         )

           {

                    … … …;

                    … … …;

                    … … …;

           }



        正确地使用这个宏的约定是如下三点。



第一点:假如系统开放了以下三种中断,Timer0、 Eint0、Eint1。以LPC2106/2105/2104为例,则:

     初始化向量中断控制器(IRQ的优先级是我假定的):

              VICVectAddr 0 = (uint32)Timer0_Handler  ;

              VICVectCntl 0 = (ox20  I  4);

              VICIntEnable   =  1 〈 〈 4;



              VICVectAddr 1 = (uint32)Eint0_Handler  ;

              VICVectCntl 1 = (ox20  I  14);

              VICIntEnable  I=  1 〈 〈  14;



              VICVectAddr 2 = (uint32)Eint1_Handler  ;

               VICVectCntl 2 = (ox20  I  15);

               VICIntEnable  I=  1 〈 〈  15;



       第二点:增加汇编语言接口的支持,方法是在文件IRQ.S 中适当位置添加如下代码。

                 Timer0_Handler   HANDLER   Timer0_Exception

                 Eint0_Handler   HANDLER   Eint0_Exception

                 Eint1_Handler   HANDLER   Eint1_Exception



         第三点:各个中断源的中断服务程序C语言部分示意代码,要像如下形式方才行。

           Void           Timer0_Exception(Void  )      //C处理程序

           {

                    … … …;

                    … … …;

                    … … …;

                   }

                  



           Void           Eint0_Exception(Void     )      //C处理程序

           {

                    … … …;

                    … … …;

                    … … …;

                   }



           Void           Eint1_Exception(Void     )      //C处理程序

           {

                    … … …;

                    … … …;

                    … … …;

                   }



         到此,这里来解释宏的替换过程就顺理成章了。



  假设Timer0 中断响应了,

   VICVectAddr  = VICVectAddr 0 = (uint32) Timer0_Handler  ,

   PC = (uint32)Timer0_Handler ,

由句柄 Timer0_Handler   HANDLER  Timer0_Exception ,和这个宏的定义,见前面宏的模型,PC 实际是跳至如下处开始执行。并且 BL 后调换成了Timer0_Exception。当然Timer0_Handler程序段,是根据定义的宏、定义的句柄、由编译器在编译程序时自动生成。



         Timer0_Handler

            A语句

            B语句

            … …

            C语句

            BL      Timer0_Exception     ;调用c语言的Timer0中断处理程序    (15)

            L语句

            M语句

            … …

            N语句



同样,假设Eint0 中断响应了,

         VICVectAddr  = VICVectAddr 1 = (uint32) Eint0_Handler  ,

         PC = (uint32)Eint0_Handler ,

由句柄 Eint0_Handler   HANDLER   Eint0_Exception ,和这个宏的定义,见前面宏的模型,PC 实际是跳至如下处开始执行。并且 BL 后调换成了Eint0_Exception。当然Eint0_Handler程序段,是根据定义的宏、定义的句柄、由编译器在编译程序时自动生成。



         Eint0_Handler

              A语句

              B语句

              … …

              C语句

              BL      Eint0_Exception    ;调用c语言的Eint0中断处理程序    (15)

              L语句

              M语句

              … …

              N语句





Eint1 情况类似,因我们是初学者,不妨采用笨办法。



         假设Eint1 中断响应了,

         VICVectAddr  = VICVectAddr 2 = (uint32)Eint1_Handler  ,

         PC = (uint32)Eint1_Handler ,

由句柄 Eint1_Handler   HANDLER   Eint1_Exception ,和这个宏的定义,见前面宏的模型,PC 实际是跳至如下处开始执行。并且 BL 后调换成了Eint1_Exception。当然Eint1_Handler程序段,是根据定义的宏、定义的句柄、由编译器在编译程序时自动生成。



         Eint1_Handler

           A语句

           B语句

           … …

           C语句

           BL      Eint1_Exception                ;调用c语言的Eint1中断处理程序    (15)

           L语句

           M语句

           … …

           N语句

使用特权

评论回复
板凳
maoyanketi|  楼主 | 2010-9-26 22:30 | 只看该作者
三)结论

         实际上这个宏是方便了编写程序,在开发环境编译时,将宏展开,为各个中断服务程序,添加了公共部分,而用户只写各个中断源的中断服务程序C语言部分,如      Void                   Timer0_Exception(Void  )      //C处理程序,

Void           Eint0_Exception(Void     )      //C处理程序,Void               Eint1_Exception(Void     )      //C处理程序,减少重复性、简单过程。



         这是一个ARM新手的认识,若有错,敬请指出,在此先谢了!

使用特权

评论回复
地板
思考| | 2010-9-27 19:45 | 只看该作者
自己按照UCOS书上的步骤重新写一个移植代码,不要用周立功的。乱七八糟。

使用特权

评论回复
5
bit6019| | 2010-9-27 21:58 | 只看该作者
谢楼主分享

使用特权

评论回复
6
yoyowodeai| | 2010-9-29 22:50 | 只看该作者
谢分享

使用特权

评论回复
7
huzixian| | 2010-10-7 15:17 | 只看该作者
mark

使用特权

评论回复
8
vivisa| | 2010-11-30 17:53 | 只看该作者
谢谢,

使用特权

评论回复
9
爱在2012| | 2010-12-29 16:10 | 只看该作者
mark

使用特权

评论回复
10
caijie| | 2011-1-22 16:51 | 只看该作者
呵呵 就是 支持4楼。

使用特权

评论回复
11
ladygaga| | 2011-1-24 12:46 | 只看该作者
看完了。报个道

使用特权

评论回复
12
6019赵文| | 2011-1-25 12:18 | 只看该作者
看了还是不知道在说啥呢,还是谢谢楼主

使用特权

评论回复
13
七叶一枝花| | 2011-1-26 21:13 | 只看该作者
楼主辛苦了。

使用特权

评论回复
14
diny| | 2011-1-27 15:38 | 只看该作者
看到四分之一的时候,明白不少,看到二分之一的时候,只明白一点了。看完后,再回过头来想,一点也不记得了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

143

主题

1079

帖子

0

粉丝