arm从零开始4

 移植UCOS  修改的别人的 把某些部分简化了下 先上工程文件 细节在慢慢讨论
点击此处下载 ourdev_421563.rar(文件大小:279K) (原文件名:UCOS.rar) 

前面的启动文件Startup.s只是进行了简单的C运行环境的建立,对中断向量,各种模式下的堆栈都没有进行设置,为了应用中断等,需要对启动文件进行改造^_^,从0x0000 0000开始是ARM的中断向量入口地址,这个和51系列的有点类似,通过装载或是跳转到真正的中断执行程序。

;下面是对arm处理器模式寄存器对应值的常数定义,arm处理器中有一个CPSR程序状态寄存器,它的后五位决定目前的处理器模式
;Pre-defined constants
USERMODE    EQU        0x10        ;0b10000 用户模式
FIQMODE            EQU        0x11         ;0b10001 FIQ模式
IRQMODE            EQU        0x12        ;0b10010 IRQ模式
SVCMODE            EQU        0x13        ;0b10011 管理模式 
ABORTMODE   EQU        0x17        ;0b10111 中止模式
UNDEFMODE   EQU        0x1b        ;0b11011 未定义
MODEMASK    EQU        0x1f        ;0b11111 系统模式
NOINT            EQU        0xc0

;定义堆栈的大小,根据需要改变
FIQ_STACK_LEGTH     EQU         0
IRQ_STACK_LEGTH     EQU         64
ABT_STACK_LEGTH     EQU         0
UND_STACK_LEGTH     EQU         0


    MACRO
$HandlerLabel HANDLER $HandleLabel

        EXPORT  $HandlerLabel                   ; 输出的标号
        IMPORT  $HandleLabel                 ; 引用的外部标号

$HandlerLabel
        SUB     LR, LR, #4                      ; 计算返回地址
        STMFD   SP!, {R0-R3, R12, LR}           ; 保存任务环境
        MRS     R3, SPSR                        ; 保存状态
        STMFD   SP!, {R3}

        LDR     R2,  =OSIntNesting              ; OSIntNesting++
        LDRB    R1, [R2]
        ADD     R1, R1, #1
        STRB    R1, [R2]
        
        BL      $HandleLabel                 ; 调用c语言的中断处理程序

        MSR     CPSR_c, #0x92
        BL      OSIntExit

        LDR     R0, =OSTCBHighRdy
        LDR     R0, [R0]
        LDR     R1, =OSTCBCur
        LDR     R1, [R1]
        CMP     R0, R1
        
        LDMFD   SP!, {R3}
        MSR     SPSR_cxsf, R3

        LDMEQFD SP!, {R0-R3, R12, PC}^          ; 不进行任务切换
        LDR     PC, =OSIntCtxSw                 ; 进行任务切换
    MEND
    
; 启动文件,初始化C程序的运行环境,然后进入C程序代码。
 IMPORT    |Image$$RO$$Limit|
 IMPORT    |Image$$RW$$Base|
 IMPORT    |Image$$ZI$$Base|
 IMPORT    |Image$$ZI$$Limit|
 IMPORT    main      ; 声明C程序中的Main()函数
 IMPORT  SoftwareInterrupt               ;软中断入口
 IMPORT  FIQ_Exception                   ;快速中断异常处理程序
 IMPORT  OSIntCtxSw                      ;中断中任务切换函数
 IMPORT  OSIntExit                       ;中断退出函数
 IMPORT  OSTCBCur                        ;指向当前任务TCB的指针
 IMPORT  OSTCBHighRdy                    ;指向将要运行的任务TCB的指针
  
 IMPORT  OSIntNesting                    ;中断嵌套计数器
 
    CODE32 ; 声明32位ARM指令
    AREA    init,CODE,READONLY ; 声明代码段Start
 ENTRY ; 标识程序入口

start
        LDR     PC, ResetAddr
        LDR     PC, UndefinedAddr
        LDR     PC, SWI_Addr
        LDR     PC, PrefetchAddr
        LDR     PC, DataAbortAddr
        DCD     0xb9205f80
        LDR     PC, [PC, #-0xff0]
        LDR     PC, FIQ_Addr

ResetAddr           DCD     Reset
UndefinedAddr       DCD     Undefined
SWI_Addr            DCD     SoftwareInterrupt
PrefetchAddr        DCD     PrefetchAbort
DataAbortAddr       DCD     DataAbort
nouse               DCD     0
IRQ_Addr            DCD     IRQ_Handler
FIQ_Addr            DCD     FIQ_Handler

  
;未定义指令
Undefined
        b       Undefined
;取指令中止
PrefetchAbort
        b       PrefetchAbort
;取数据中止        
DataAbort  
        b       DataAbort
;中断
IRQ_Handler HANDLER IRQ_Exception
;快速中断
FIQ_Handler
        STMFD   SP!, {R0-R3, LR}
        BL      FIQ_Exception
        LDMFD   SP!, {R0-R3, LR}
        SUBS    PC,  LR,  #4

;定时器0中断
Timer0_Handler  HANDLER Timer0

InitStack    
        MOV     R0, LR
;设置中断模式堆栈
        MSR     CPSR_c, #IRQMODE|NOINT;#0xd2
        LDR     SP, StackIrq
;设置快速中断模式堆栈
        MSR     CPSR_c, #FIQMODE|NOINT;#0xd1
        LDR     SP, StackFiq
;设置中止模式堆栈
        MSR     CPSR_c, #ABORTMODE|NOINT;#0xd7
        LDR     SP, StackAbt
;设置未定义模式堆栈
        MSR     CPSR_c, #UNDEFMODE|NOINT;#0xdb
        LDR     SP, StackUnd
;设置系统模式堆栈
        MSR     CPSR_c, #MODEMASK|NOINT;#0xdf
        LDR     SP, StackIrq
        MOV     PC, R0

StackIrq           DCD     (IrqStackSpace + IRQ_STACK_LEGTH * 4 - 4)
StackFiq           DCD     (FiqStackSpace + FIQ_STACK_LEGTH * 4 - 4)
StackAbt           DCD     (AbtStackSpace + ABT_STACK_LEGTH * 4 - 4)
StackUnd           DCD     (UndtStackSpace + UND_STACK_LEGTH * 4 - 4)

Reset

 BL InitStack
 ; 初始化C程序的运行环境
 LDR       R0,=|Image$$RO$$Limit|
 LDR       R1,=|Image$$RW$$Base|    
 LDR       R3,=|Image$$ZI$$Base|    
 CMP       R0,R1
 BEQ       LOOP1
LOOP0   
 CMP       R1,R3;如果RW区不为空,将加载域的RW数据COPY到运行域      
 LDRCC     R2,[R0],#4     
 STRCC     R2,[R1],#4 
 BCC       LOOP0
LOOP1   
 LDR       R1,=|Image$$ZI$$Limit| 
 MOV       R2,#0
LOOP2   
 CMP       R3,R1;如果ZI区不为空,将ZI区域初始化为0
 STRCC     R2,[R3],#4
 BCC       LOOP2
 B      main ;跳转到c语言入口 Jump to the entry point of C program
 
 ;/* 分配堆栈空间 */
        AREA    MyStacks, DATA, NOINIT
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间
UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈

 END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值