查看: 584|回复: 0

智能小车37:异常在ARM、JAVA、硬件里的实现

[复制链接]
  • TA的每日心情
    奋斗
    2017-8-9 10:25
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2017-10-12 21:38 | 显示全部楼层 |阅读模式

    几乎所有编程语言都有异常,可以说有程序就有异常。今天学习Arm的中断(异常)处理,联想到Java的异常,硬件中如何实现等问题,下面给大家分享一下。

    一、Arm的中断。
    1.触发异常
    2.保存现场
    3.cpu进入异常工作模式,程序指针(pc)跳入异常入口(处理异常的代码地址)
    a.分辨中断源
    b.进行逻辑处理
    c.清理工作
    4.恢复现场
    流程图(来源于《2440数据手册》)如下:

    这里的工作模式,其实就是不同情况下,cpu有一组不同的寄存器。正是有了不同的寄存器,程序在可以在不同的状态下来回切换。如下图:

    中断例子的汇编代码如下:

    b   Reset

    @******************一堆设置代码已省略*************************************************      Reset:                  
        ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈
        bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启
         msr cpsr_c, #0xd2       @ 进入中断模式,d的前两位是11,意思是关闭所有的中断
        ldr sp, =3072           @ 设置中断模式栈指针
        msr cpsr_c, #0xd3       @ 进入管理模式
        ldr sp, =4096           @ 设置管理模式栈指针,
                                @ 其实复位之后,CPU就处于管理模式,
                                @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略
        bl  init_led            @ 初始化LED的GPIO管脚
        bl  init_irq            @ 调用中断初始化函数,在init.c中
        msr cpsr_c, #0x53       @ 设置I-bit=0,开IRQ中断
          ldr lr, =halt_loop      @ 设置返回地址
        ldr pc, =main           @ 调用main函数
    halt_loop:
        b   halt_loop
    @中断函数
    HandleIRQ:
        sub lr, lr, #4                  @ 计算返回地址,arm架构规定的
        stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器,保存现场
                                        @ 注意,此时的sp是中断模式的sp
                                        @ 初始值是上面设置的3072
           ldr lr, =int_return             @ 设置调用ISR即EINT_Handle函数后的返回地址  
        ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中
    int_return:
        ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr

    EINT_Handle 函数的实现就是判断是那个按钮然后点相应的灯,我这里就不复制代码了。
    msr cpsr_c指令值的来源如下图(来源于《嵌入式Linux应用开发完全手册》):


    二、java中的异常,很简单。
    try{
    }catch(Exception e){
    }finally{
    }
    不用关心什么工作模式,catch中代码命中就执行,finally里的代码一定会执行。根据自己的逻辑来写就行了。

    java中的中断,Thread有个interrupt方法,但调用这个方法并不知道线程会在什么状态下中断,我没有用过这种方式。需要中断的话,我一般自己写个状态变量,在while里判断中断状态做下处理。

    三、硬件实现中断。
    用继电器就可以实现开关,如下图:

    给线圈一点电压就能切换这个开关,也就能触发工作模式的切换了。

    高级模式  
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    Arduino Uno 电机无法正常工作问题
    Arduino Uno 电机无法正常
    如图,请问代码有什么不对的地方吗 #include #include #include double angle_r
    顔色傳感器
    顔色傳感器
    有會使用顔色傳感器的朋友嗎?請問怎樣識別紅色和藍色,當然能來段代碼就更好了
    Blink——Arduino的Hello World!
    Blink——Arduino的Hello
    本教程节选自《Arduino程序设计基础》 Arduino编程基础(零)——Blink,Arduino的He
    创客集结号项目:太阳能陀螺仪机器人
    创客集结号项目:太阳能陀
    这是一只最简单的全自动机器人,它不像居家电器一样需要电源开关,也不需要人来维护,
    关于蓝牙4.0的问题
    关于蓝牙4.0的问题
    蓝牙4.0始终进不来AT,用的是JDY08 代码 #include SoftwareSerial BT(10, 11); // 接
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表