Chinaunix首页 | 论坛 | 博客
  • 博客访问: 707901
  • 博文数量: 255
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 2811
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-09 13:29
个人简介

IT业行者,行者无疆

文章分类

全部博文(255)

文章存档

2011年(121)

2010年(134)

我的朋友

分类: 嵌入式

2010-09-27 09:15:39

ARM在UC/OS II的移植日记(连载7)

OS_CPU_S.S文件

这个文件完全是用汇编代码写的,是这次移植中代码比较难于实现的文件,也是决定移植效率的文件,对ARM指令的熟悉程度和ADS的熟悉程程度,令我对zlg 的牛人非常的佩服,呵呵,要是以后有时间,自己也做一个完整的移植代码,挑战一下自己,呵呵,好了,废话不说了,北京老是下雨。。。。。。。开始吧,come on。

;定义管理模式堆栈的大小
SVC_STACK_LEGTH     EQU         32   ;实际上用的只是6+1个字,为了以后扩展用,可定义的大一点

这是定义了管理模式的堆栈,因为在任务切换的时候有在管理模式下进行了一些数据的保存动作

NoInt       EQU 0x80

USR32Mode   EQU 0x10
SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f
IRQ32Mode   EQU 0x12
FIQ32Mode   EQU 0x11

;T_bit用于检测进入异常前cpu是否处于THUMB状态
T_bit               EQU         0x20

以上是定义了一些常量

    CODE32

    AREA    |subr|, CODE, READONLY

            IMPORT  OSTCBCur                    ;指向当前任务TCB的指针
            IMPORT  OSTCBHighRdy                ;指向将要运行的任务TCB的指针
            IMPORT  OSPrioCur                   ;当前任务的优先级
            IMPORT  OSPrioHighRdy               ;将要运行的任务的优先级
            IMPORT  OSTaskSwHook                ;任务切换的钩子函数
            IMPORT  OSRunning                   ;uC/OS-II运行标志

            IMPORT  OsEnterSum                  ;关中断计数器(关中断信号量)
            IMPORT  SWI_Exception               ;软中断异常处理程序
           
            EXPORT  __OSStartHighRdy           
            EXPORT  OSIntCtxSw                  ;中断退出时的入口,参见startup.s中的IRQ_Handler
            EXPORT  SoftwareInterrupt           ;软中断入口

这个就不用解释了吧?记住IMPORT和EXPORT关键字就行了,实在不懂就看我以前的连载吧。

StackSvc           DCD     (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

        AREA    SWIStacks, DATA, NOINIT,ALIGN=2
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间

我把这两句放到一起来解释吧。AREA是说明这个一块数据,SWIStacks是这段数据的名称,DATA代表这是数据,不是代码段,NOINT代表这块数据没有进行初始化,就是没有清零吧,ALIGN是要求编译器必须按照字整齐排列这些数据,SPACE是预汇编宏指令,要求编译器预留一段连续的数据块,数据块的大小是SVC_STACK_LEGTH * 4,这个大小是字节为单位的,SvcStackSpace是给这段数据块的名字,就是他的句柄啦。DCD也是一个为指令,给一段数据命名,SvcStackSpace + SVC_STACK_LEGTH * 4 - 4就是这段数据块的首地址,所以StackSvc就是代表这段数据的首地址了。

 

;软件中断
SoftwareInterrupt

这是软件中断的唯一入口,既是当产生软件中断时,立刻程序转到这里执行,代码的开始段是管理模式
        LDR     SP, StackSvc            ; 重新设置堆栈指针,这时已经是管理模式了
        STMFD   SP!, {R0-R3, R12, LR} ; 现场保护,R0-R3在函数参数传递和返回值时使用,R12是进行运算用的,LR调用函数时使用,同时更新SP的值
        MOV     R1, SP                  ; R1指向参数存储位置,保存SP的值

        MRS     R3, SPSR
        TST     R3, #T_bit              ; 中断前是否是Thumb状态

具体的手册看ARM的说明,在Thumb和Arm状态下SWI号的传递是不一样的,
        LDRNEH  R0, [LR,#-2]            ; 是: 取得Thumb状态SWI号
        BICNE   R0, R0, #0xff00
        LDREQ   R0, [LR,#-4]            ; 否: 取得arm状态SWI号
        BICEQ   R0, R0, #0xFF000000
                                        ; r0 = SWI号,R1指向了SP的值

        CMP     R0, #1

SWI号的第一和第二分别单独的实现,分别是中断级任务切断函数和多任务启动函数,其他的中断号都在SWI_Exception中实现。
        LDRLO   PC, =OSIntCtxSw

调用中断级任务切换函数
        LDREQ   PC, =__OSStartHighRdy   ; SWI 0x01为第一次任务切换

调用多任务启动函数

        BL      SWI_Exception

调用其他的软件中断函数
        
        LDMFD   SP!, {R0-R3, R12, PC}^

加!代表同时更新SP的值,堆栈恢复后管理模式的堆栈必须恢复,否则会产生溢出的,^代表最后恢复PC的值,就是中断返回啦。

 

阅读(578) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~