UCOS-II在LPC2210上的移植--os_cpu_a.s

 

CPU Philips ARM7 LPC2210

OS uC/OSII 2.52

IDE ADS 1.2

移植一个操作系统到一个CPU体系的结构上,移植者必须的要求:

1、对目标体系结构要有很深的了解 -- ARM Architecture Reference Manual

2、对OS原理要有较深入的了解 -- 嵌入式实时操作系统uC/OSII

3、对所使用的编译器要有较深入的了解 -- ADS自带的编译器和连接器的手册

4、对需要移植的操作系统要有相当的了解 -- 嵌入式实时操作系统uC/OSII

5、对具体使用的芯片也要有一定的了解 -- 芯片的数据手册

编写OS_CPU_A.s

;****************************************************************************************/

;定义系统模式堆栈的大小

SVC_STACK_LEGTH     EQU   32

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           ;软中断入口

 

;/*****************************************************************************************

;** 函数名称: SoftwareInterrupt

;** 功能描述: 软件中断,用于提供一些系统服务,功能参考os_cpu_c.c文件

;** 输 入:   依功能而定

;** 输 出 :  依功能而定

;** 全局变量:

;** 调用模块: SWI_Exception

;**

;******************************************************************************************/

;软件中断

SoftwareInterrupt

        LDR     SP, StackSvc            ; 重新设置堆栈指针

        STMFD   SP!, {R0-R3, R12, LR}   ; 参数, IP( R12 ), LR入栈. ( 这几个为当前处理器模式的堆栈结构 )

        MOV     R1, SP                  ; R1存储参数存储位置的堆栈指针, 实质为当前的堆栈指针

        MRS     R3, SPSR

        TST     R3, #T_bit              ; 中断前是否是Thumb状态, 测试位T

        LDRNEH  R0, [LR,#-2]            ; : 取得Thumb状态SWI, H为半字加载

        BICNE   R0, R0, #0xff00         ; swi号在32位里面为24,Thumb状态下为8

        LDREQ   R0, [LR,#-4]            ; : 取得arm状态SWI

        BICEQ   R0, R0, #0xFF000000     ; swi24位立即数

                                        ; r0 = SWI号,R1指向参数存储位置

        CMP     R0, #1                  ; 1作比较

        LDRLO   PC, =OSIntCtxSw        ; 小于1,那就零了,那么就是切换到任务切换函数OSIntCtxSw

        LDREQ   PC, =__OSStartHighRdy   ; SWI 0x01为第一次任务切换

        BL      SWI_Exception           ; 跳转到软中断服务程序

        LDMFD   SP!, {R0-R3, R12, PC}^  ; 参数, IP( R12 ), LR出栈

StackSvc           DCD     (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

 

;/******************************************************************************************

;** 函数名称: OSIntCtxSw

;** 功能描述: 中断退出时的入口

;** 输 入:   R3    :当前任务的状态寄存器CPSR(即SPSR的值)

;**           R4-R12:当前任务的R4-R11

;**           当前处理器模式的堆栈结构(出栈次序):R0-R3R12PC(当前任务的)

;** 输 出 : 

;** 全局变量: OSPrioCur,OSPrioHighRdy,OSPrioCur,OSPrioHighRdy

;** 调用模块:

;**

;************************************************************************************/

 

;  |____________________|<--- 栈底                              

;  |                    |

;  | 任务入栈的其它数据 |

;  |____________________|

;  |         PC         |

;  |____________________|<--- 任务环境开始

;  |         LR         |

;  |____________________|

;  |        R12         |

;  |____________________|

;  |        R11         |

;  |____________________|

;  |        R10         |

;  |____________________|

;  |         R9         |                          

;  |____________________|                         

;  |         R8         |                         

;  |____________________|                         

;  |         R7         |                         

;  |____________________|                          

;  |         R6         |                        

;  |____________________|                

;  |         R5         |                

;  |____________________|                

;  |         R4         |                

;  |____________________|                

;  |         R3         |                

;  |____________________|                

;  |         R2         |                

;  |____________________|                

;  |         R1         |                

;  |____________________|                

;  |         R0         |                

;  |____________________|                

;  |        CPSR        |                

;  |____________________|                

;  |     OSEnterSum     |<---- SP        

;  |____________________|       

;  |                    |       

;  |     空闲空间        |       

;  |____________________|       

;  |                    |                                                 

;                                                                            

;    A  任务堆栈结构                                                 

                                                   

;  |____________________|<--- 栈底             

;  |                    |                      

;  | 任务入栈的其它数据 |                       

;  |____________________|                      

;  |         LR         |                      

;  |____________________| <--- 任务环境开始    

;  |         R12        |                      

;  |____________________|                       

;  |         R3         |                      

;  |____________________|                      

;  |         R2         |                      

;  |____________________|                      

;  |         R1         |                      

;  |____________________|                      

;  |         R0         |<---- SP              

;  |____________________|                      

;  |                    |                      

;  |     空闲空间        |                      

;  |____________________|                      

;  |                    |                      

    B  调用OSIntCtxSw时的堆栈结构   

OSIntCtxSw

                                                    ; 下面为保存任务环境, 见图B

        LDR     R2, [SP, #20]                       ; 获取PC, LR

        LDR     R12, [SP, #16]                      ; 获取R12

        MRS     R0, CPSR

        MSR     CPSR_c, #(NoInt | SYS32Mode)        ; 关中断,并且设置为系统模式

        MOV     R1, LR

        STMFD   SP!, {R1-R2}                        ; 保存LR,PC

        STMFD   SP!, {R4-R12}                       ; 保存R4-R12

        MSR     CPSR_c, R0

        LDMFD   SP!, {R4-R7}                        ; 获取R0-R3

        ADD     SP, SP, #8                          ; 出栈R12,PC

        MSR     CPSR_c, #(NoInt | SYS32Mode)

        STMFD   SP!, {R4-R7}                        ; 保存R0-R3

        LDR     R1, =OsEnterSum                     ; 获取OsEnterSum

        LDR     R2, [R1]

        STMFD   SP!, {R2, R3}                       ; 保存CPSR,OsEnterSum.

                                                    ; 到这里为至任务环境保存完成

 

                                                    ; 保存当前任务堆栈指针到当前任务的TCB

        LDR     R1, =OSTCBCur

        LDR     R1, [R1]

        STR     SP, [R1]

        BL      OSTaskSwHook                        ; 调用钩子函数

                                                    ; OSPrioCur <= OSPrioHighRdy

                                                    ; 当前任务设为最高优先级的任务

        LDR     R4, =OSPrioCur

        LDR     R5, =OSPrioHighRdy

        LDRB    R6, [R5]

        STRB    R6, [R4]

                                                    ; OSTCBCur <= OSTCBHighRdy

                                                    ; 任务控制块设为最高优先级任务的TCB

        LDR     R6, =OSTCBHighRdy

        LDR     R6, [R6]

        LDR     R4, =OSTCBCur

        STR     R6, [R4]

OSIntCtxSw_1

                                                    ; 获取新任务堆栈指针

        LDR     R4, [R6]

        ADD     SP, R4, #68                         ; 17寄存器CPSR,OsEnterSum,R0-R12,LR,SP

        LDR     LR, [SP, #-8]

        MSR     CPSR_c, #(NoInt | SVC32Mode)        ; 进入管理模式

        MOV     SP, R4                              ; 设置堆栈指针

        LDMFD   SP!, {R4, R5}                       ; CPSR,OsEnterSum

                                                    ; 恢复新任务的OsEnterSum

        LDR     R3, =OsEnterSum

        STR     R4, [R3]

   

        MSR     SPSR_cxsf, R5                       ; 恢复CPSR

        LDMFD   SP!, {R0-R12, LR, PC }^             ; 运行新任务

 

;/******************************************************************************************

;** 函数名称: __OSStartHighRdy

;** 功能描述: uC/OS-II启动时使用OSStartHighRdy运行第一个任务,

;**           OSStartHighRdy会调用__OSStartHighRdy

;** 输 入:  

;** 输 出 : 

;** 全局变量: OSRunning,OSTCBCur,OSTCBHighRdy,OsEnterSum

;** 调用模块: OSTaskSwHook

;**

;***************************************************************************************/

 

__OSStartHighRdy

        MSR     CPSR_c, #(NoInt | SYS32Mode)

                                                ;告诉uC/OS-II自身已经运行

        LDR     R4, =OSRunning

        MOV     R5, #1

        STRB    R5, [R4]

        BL      OSTaskSwHook                    ;调用钩子函数

        LDR     R6, =OSTCBHighRdy

        LDR     R6, [R6]

        B       OSIntCtxSw_1

        AREA    SWIStacks, DATA, NOINIT

;,ALIGN=2

SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间

 

    END

;/*********************************************************************************************************

;**                            End Of File

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值