• arm swi 软中断 一例


    原文在CU,挪过来了。

    1. 目标

        本文单纯验证swi指令相关功能

    2. 环境

        vmware + redhat 9 + arm-elf-gcc 2.95 + skyeye-1.2.6_rc1(模拟s3c44b0x)

    3. 功能详述

         1). 调用swi前,关IRQ,FIQ,INTMSK,改变CPU模式为用户模式0x10000

         2). 指令的功能号由swi指令码的低24位传输,通过
               ldr r4,[lr,#-4]
               bic r4,r4,#0xff000000
              得到它的功能号,这样就可以根据功能号来进行相关功能的调用,
              本例只使用了两个功能号:
             

               swi #1   1 表示两个数的加法
               swi #2   2 表示两个数的减法
               加法和减法的函数在.c文件中定义

         3). 在swi的处理程序中,对于c函数int add(int a,int b)的参数传递是通过
               r0,r1进行的, add(),sub()的结果通过r0返回给swi的处理程序
                               
         4). swi的处理流程:  swi #x --> 0x00000008 --> HandlerSWI --> C函数, 仅此而已

    4. 运行:

                #  skyeye 
        调试

               # skyeye -d

         不用再加文件名,文件写在skyeye.conf里了, 当然还得用arm-elf-gdb.

    5. 文件清单(5个文件)

    swi.s

    .equ INTCON,   0x01e00000
    .equ INTMSK,   0x01e0000c
    .equ LOCKTIME, 0x01d8000c
    .equ PLLCON,   0x01d80000
    .equ CLKCON,   0x01d80004
    .equ WTCON,    0x01d30000
    .equ I_ISPR,   0x01e00020
    .equ I_ISPC,   0x01e00024
    .equ TCFG0,    0x01d50000
    .equ TCFG1,    0x01d50004
    .equ TCON,     0x01d50008
    .equ TCNTB5,   0X01d50048
    .equ UTXH0,    0x01d00020
    .equ UFCON0,   0x01d00008
    .equ ULCON0,   0x01d00000
    .equ UCON0,    0x01d00004
    .equ UBRDIV0,  0x01d00028
    
    
    .globl _start
    _start:
        b reset
        b .
        b HandlerSWI
        b .
        b .
        b .
        b .
        b .
    
    
    reset:
        mov r0,#0x80 | 0x40 | 0x13  @ svc, disable irq,fiq
        msr cpsr_c,r0
    
        ldr sp, =0x0c700000
    
        ldr r0,=WTCON        @ disable watch dog
        ldr r1, =0x0
        str r1, [r0]
    
        ldr r0, =INTCON      @ non-vector mode, disable irq, disable fiq
        ldr r1, =0x7
        str r1, [r0]
    
        ldr r0, =LOCKTIME
        ldrb r1, =800
        strb r1, [r0]
    
        ldr r0, =PLLCON
        ldr r1, =0x34031
        str r1,[r0]
        
        ldr r0, =CLKCON
        ldr r1, =0x7ff8
        str r1, [r0]
    
        @ UART 0
        ldr r0,=UFCON0
        mov r1,#0x0
        str r1,[r0]
    
        ldr r0,=ULCON0
        mov r1,#0x03
        str r1,[r0]
        
        ldr r0,=UCON0
        mov r1,#0x05
        str r1,[r0]
    
        ldr r0,=UBRDIV0
        mov r1,#32
        str r1,[r0]
    
        ldr r0,=UTXH0        @ print 'C'
        mov r1,#'C'
        str r1,[r0]
        
        @ sp_svc
        ldr sp,=0x0c700000
        
        ldr r0, =INTMSK
        ldr r1, =0x03ffffff  @ disable all irq.
        str r1, [r0]
        
        @ move to user mode
    
        mov r0, #0x80 | 0x40 | 0x10  @ svc, disable irq,fiq
        msr cpsr_c,r0
    
        mov r0, #'A'
        mov r1, #0x1
        swi #1              @ add('A',1), print 'B'
    
        ldr r1,=UTXH0       @ print 'A'
        str r0,[r1]
    
        mov r0, #'H'        @ subtract
        mov r1, #0x1        @
        swi #2              @ sub('H',1), print 'G'
    
        ldr r1,=UTXH0       @ print 'H'
        str r0,[r1]
        
        ldr r1,=UTXH0       @ print 'S' -- STOP
        mov r0,#'S'
        str r0,[r1]
    
    stop:    b stop              @ while(1);
    
    
    HandlerSWI:       
        stmfd sp!,{r0-r12,lr}   
    
        ldr r4,[lr,#-4]         @ lr is "swi #x" address, get swi instruction code
        bic r4,r4,#0xff000000   @ get #x
    
        cmp r4,#1               @ 1 -- add(a,b)
        bne next
    
        bl add                  @ c function use r0,r1 as parameter, and return result with r0
        ldr r1,=UTXH0           @ print 'B'
        str r0,[r1]
    
    next:
        cmp r4,#2               @ 2 -- sub(a,b)
        bne swi_return
    
        bl sub
        ldr r1,=UTXH0           @ print 'G'
        str r0,[r1]
    
    swi_return:
        ldmfd sp!, {r0-r12,pc}^

    c_fun.c

    int add(int a,int b){
        return a + b;
    }
    
    int sub(int a,int b){
        return a - b;
    }

    swi.lds

    OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(_start)
    SECTIONS
    {
        . = 0x00000000;
    
        .text :
        {
                swi.o (.text)
        }
        
        . = ALIGN(4);
        .data :
        {
           *(.data)
        }
    
    }

    Makefile

    all: swi
    
    swi: swi.o c_fun.o
        arm-elf-ld -T swi.lds -o swi swi.o c_fun.o
        arm-elf-objcopy -O binary -S swi swi.bin
    
    swi.o: swi.s
        arm-elf-as --gstabs -o swi.o swi.s
    
    c_fun.o: c_fun.c
        arm-elf-gcc -gstabs -c c_fun.c
    
    .PHONY: clean
    clean:    
        rm -f swi.o c_fun.o swi swi.bin

    skyeye.conf

    #skyeye config file for S3C44B0X
    cpu: arm7tdmi
    mach: s3c44b0x
    
    # physical memory
    mem_bank: map=M, type=RW, addr=0x00000000, size=0x00200000, file=swi.bin
    mem_bank: map=M, type=RW, addr=0x0c000000, size=0x00800000
    
    # peripherals I/O mapping area
    mem_bank: map=I, type=RW, addr=0x01c00000, size=0x00400000
    
    # uart 0
    uart: mod=stdio
  • 相关阅读:
    Android ListView的使用(三)
    Android GridView的使用页面按钮
    Android ListView的使用(二)
    Android ListView的使用(一)
    Linux 下MongoDb的安装
    Linux使用redis
    JavaWeb之JDBC
    JavaWeb之多语言国际化
    JavaWeb之JSTL标签
    JavaWeb之JSP技术总结
  • 原文地址:https://www.cnblogs.com/bear129/p/8196394.html
Copyright © 2020-2023  润新知