zoukankan      html  css  js  c++  java
  • 中断与异常

    arm对异常(中断)处理过程

    1 初始化:
    :: a 设置中断源,让它可以产生中断
    :: b 设置中断控制器(可以屏蔽某个中断,优先级)
    :: c 设置CPU总开关,(使能中断)

    2 执行其他程序:正常程序

    3 产生中断:按下按键--->中断控制器--->CPU

    4 cpu每执行完一条指令都会检查有无中断/异常产生

    5 发现有中断/异常产生,开始处理。对于不同的异常,跳去不同的地址执行程序。这地址上,只是一条跳转指令,跳去执行某个函数(地址),这个就是异常向量。如下就是异常向量表,对于不同的异常都有一条跳转指令。  (3-5都是硬件强制做的)

    6 这些函数做什么事情?
    :: 软件做的:
    :: a 保存现场(各种寄存器)
    :: b 处理异常(中断):
    :::: 分辨中断源
    :::: 再调用不同的处理函数
    :: c 恢复现场

    --------------------------------------异常向量表-------------------------------------

    .globl _start
    _start: b   reset
        ldr pc, _undefined_instruction
        ldr pc, _software_interrupt
        ldr pc, _prefetch_abort
        ldr pc, _data_abort
        ldr pc, _not_used
        ldr pc, _irq //发生中断时,CPU跳到这个地址执行该指令 **假设地址为0x18**
        ldr pc, _fiq
    //我们先在0x18这里放 ldr pc ,__irq,于是cpu最终会跳去执行__irq代码
    //保护现场,调用处理函数,恢复现场

    思考:为什么不用b指令实现中断的跳转?

    软中断程序:

    示例一:

    .text
        
        @异常向量表
        b     reset        @0x00 reset
        nop                @0x04 udef
        b    swi_handler   @0x08 swi
        nop                @0x0c prefetch abort 指令预取终止
        nop                @0x10 data abort 数据访问终止
        nop                @0x14 reserved   保留
        nop                @0x18 irq
        nop                @0x1c fiq
                           @nop 占空地址;0x00-1c为异常向量表所用,不可被其他语句所占
    swi_handler:
        stmfd sp!,{r0,lr} @将r0,lr进栈,保护现场,sp为堆栈指针
        mov r0,#6
        ldmfd sp!,{r0,pc} @将原值出栈到r0,pc,恢复现场
    
    reset:
        mov r0,#3
        swi 2
        
        mov r1,r0
        b   reset
        

    执行压栈和出栈指令后报错

     所以在压栈之前,要令堆栈指针sp重新指向一个空间

        .text
        
        @异常向量表
        b     reset      @0x00 reset
        nop             @0x04 udef
        b    swi_handler @0x08 swi
        nop                @0x0c prefetch abort 指令预取终止
        nop                @0x10 data abort 数据访问终止
        nop                @0x14 reserved   保留
        nop                @0x18 irq
        nop                @0x1c fiq
                        @nop 占空地址;0x00-1c为异常向量表所用,不可被其他语句所占
    swi_handler:
        stmfd  sp!,{r0,lr} @将r0,lr进栈,保护现场,sp为堆栈指针
        mov    r0,#6
        ldmfd  sp!,{r0,pc} @将原值出栈到r0,pc,恢复现场
    
    reset:
        ldr    sp,=stack_base
        mov    r0,#3
        swi    2
        mov    r1,r0
        b      reset
        
        .data
    buf:
        .space    32   @定义内存空间,将空间末地址赋给sp
    stack_base:      @开始压栈,sp递减,入栈sp递增,又会回到此位置
    
        .end

    软中断主要用于系统调用,用于从用户空间到内核空间的切换。user--->svc

    @异常向量表
        b     reset           @0x00 reset 指令机器码存放的地址空间大小有限制,可以如下单独构造4字节的空间存放
        ldr  pc,_udef        @0x04 udef
        ldr     pc,_swi         @0x08 swi   不使用b而使用ldr跳转以突破32M空间限制
        ldr  pc,_prefetch     @0x0c prefetch abort 指令预取终止
        ldr  pc,_data_abort     @0x10 data abort 数据访问终止
        nop                     @0x14 reserved   保留
        ldr  pc,_irq         @0x18 irq
        ldr  pc,_fiq         @0x1c fiq
                             @nop 占空地址;0x00-1c为异常向量表所用,不可被其他语句所占
    
    _udef:
        .word    udef_handler
    _swi:                     @此标号为地址
        .word    swi_handler  @里面存放了一个数,此数存放了地址,通过ldr将函数地址赋给PC以实现跳转
    _prefetch:
        .word   prefetch_handler  @未实现
    _data_abort:
        .word   data_abort_handler
    _irq:
        .word   irq_handler
    _fiq:
        .word   fiq_handler
    swi_handler:
        stmfd  sp!,{r0,lr}   @将r0,lr进栈,保护现场,sp为堆栈指针
        sub       r0,lr,#4
        ldr    r0,[r0]
        bic    r0,#0xff000000
        bl     swi_num_handler
        ldmfd  sp!,{r0,pc}^  @将原值出栈到r0,pc,恢复现场
    
    swi_num_handler:
        @swith(num)
        @case 2:
        @  .....
        @case 3:
        @  .....
        
    
    reset:
        ldr    sp,=stack_base
        @切换到应用程序空间
        msr    cpsr,#0x10
        mov    r0,#3
        @ open  read  write  ioctl ...通过系统调用访问内核数据
        @  2     4      6      7      软中断号  
        swi    2     @跳转到异常向量表的软中断入口
                     @保存返回的地址到LR
                     @切换到SVC模式
        mov    r1,r0
        b      reset
        
        .data
    buf:
        .space    32   @定义内存空间,将空间末地址赋给sp
    stack_base:      @开始压栈,sp递减,入栈sp递增,又会回到此位置
    
    
        .end
  • 相关阅读:
    pycharm中将文件目录标记为sources root和sys.path.append()效果一样
    简单的股票信息查询系统 1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环) 2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来 3 允许按股票价格、涨跌幅、换手率这几列来筛选信息, 比如输入“价格>50”则把价格大于50的股票都打印,输入“市盈率<50“,则把市盈率小于50的股票都打印,不用判断等于。
    添加jar到本地maven库
    jquery.qrcode中文乱码的解决终极办法
    easyUI datagrid view扩展
    CANNOT READ PROPERTY ‘opera’ OF UNDEFINED解决方法
    关于 Promise 的一些简单理解
    Java 内功修炼 之 数据结构与算法(一)
    学习一下 JVM (三) -- 了解一下 垃圾回收
    学习一下 JVM (二) -- 学习一下 JVM 中对象、String 相关知识
  • 原文地址:https://www.cnblogs.com/y4247464/p/12283480.html
Copyright © 2011-2022 走看看