再开始ARM920t的中断体系分析前,我们先来回忆一个中断触发时8051单片机的处理流程:
(1)保护现场
(2)cpu的pc指针自动跳转到中断向量表处找出对应的中断处理入口,即中断处理函数
(3)进入中断处理函数后首先要分辨中断源,然后进行对应的中断处理
(4)中断处理完,清除中断
(5)返回现场
中断程序的设置流程:
(1)建立中断向量表
(2)初始化中断:打开开关、设置优先级、中断模式下的堆栈指针等
(3)建立中断处理函数:汇编调用C函数

开始分析ARM920t的中断处理过程,原理和51单片机类似直接开始分析我的实验代码。

进入代码时间:

File:head.S

.extern     main
.text
.global _start
_start:
@******************************************************************************
@ (1)建立中断异常向量表:每一条指令占用4个字节的空间
@******************************************************************************       b   Reset                @ 0x00:(有使用)启动复位也是一种特殊的“异常”
HandleUndef:b   HandleUndef         @ 0x04: 未定义指令中止模式的向量地址
HandleSWI:b   HandleSWI             @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
HandlePrefetchAbort:b   HandlePrefetchAbort @ 0x0c: 指令预取终止导致的异常的向量地址
HandleDataAbort:b   HandleDataAbort     @ 0x10: 数据访问终止导致的异常的向量地址
HandleNotUsed:b   HandleNotUsed     @ 0x14: 保留b   HandleIRQ            @ 0x18: (有使用)中断模式的向量地址
HandleFIQ:b   HandleFIQ         @ 0x1c: 快中断模式的向量地址Reset:                  ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启msr cpsr_c, #0xd2       @ 进入中断模式,只有在中断模式下才可以设置中断的堆栈指针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      @ 进入c函数main前设置返回地址ldr pc, =main           @ 调用main函数
halt_loop:b   halt_loopHandleIRQ:                           @ 定义中断异常处理函数sub lr, lr, #4                  @ 计算返回地址stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器@ 注意,此时的sp是中断模式的sp@ 初始值是上面设置的3072ldr lr, =int_return             @ 设置调用ISR即EINT_Handle函数后的返回地址  ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中
int_return:ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr

代码分析:慢慢体会和51单片机的一点差别

当一个异常中断发生时ARM920T的硬件自动处理的工作:保护一部分现场
(1)将前一个工作模式的“下一条即将执行的指令地址”即PC值保存到下一个异常模式下的R14即LR寄存器中(此时还未进入该异常模式)
(2)将前一个工作模式的下的CPSR保存到下一个异常模式下的SPSR中
(3)强制将下一个异常模式的CPSR工作模式位设置成对应值
(4)强制让PC值等于中断向量表中保存的跳转地址
进入到中断后软件要完成的工作有:
(1)计算中断返回地址保存到LR:上面我们讲到硬件自动帮我们把
注意这里有一点很有意思:根据2440使用手册可知平时PC指针是指向当前执行指令的下两条指令(即PC=“PC”+8),刚才硬件帮我们保存的地址并不是我们中断返回时真正想要的地址!!!
例如从IRQ返回前,我必须要矫正这个返回地址才行,即让LR=PC+4,这很简单,之前LR=PC+8,现在只要将LR=LR-4就可以了。
(2)保护剩余的现场:将所有的工作寄存器,比如R0-R12、LR等
(3)调用异常处理函数并清除中断
(4)恢复现场,将保存过得寄存器值恢复
【非常建议自己去看s3c2440英文版的使用手册,里面有讲到中断异常到来时是CPU是如何操作的】

附加文件:

(1)File:interrupt.c   真正中断处理函数

#include "s3c24xx.h"void EINT_Handle()
{unsigned long oft = INTOFFSET;//判断外部中断源unsigned long val;switch( oft ){// S4被按下case 0: {   GPBDAT |= (0x7<<5);   // 所有LED熄灭GPBDAT &= ~(1<<5);      // LED1点亮break;}// S1被按下case 1:{   GPBDAT |= (0x7<<5);   // 所有LED熄灭GPBDAT &= ~(1<<6);      // LED2点亮break;}// K3被按下case 2:{   GPBDAT |= (0x7<<5);   // 所有LED熄灭GPBDAT &= ~(1<<7);      // LED3点亮                break;}// K2被按下case 4:{   GPBDAT |= (0x7<<5);   // 所有LED熄灭GPBDAT &= ~(1<<8);      // LED3点亮                break;}default:break;}//清中断if( oft == 5 ) EINTPEND = (1<<11);   // EINT8_23合用IRQ5SRCPND = 1<<oft;INTPND = 1<<oft;
}

(2)File:init.c   一些初始化函数,比较懒所以就用c函数代替

#include "s3c24xx.h"#define    GPB5_out    (1<<(5*2))
#define GPB6_out    (1<<(6*2))
#define GPB7_out    (1<<(7*2))
#define GPB8_out    (1<<(8*2))#define GPB5_msk    (3<<(5*2))
#define GPB6_msk    (3<<(6*2))
#define GPB7_msk    (3<<(7*2))
#define GPB8_msk    (3<<(8*2))#define GPF0_eint   (0x2<<(0*2))
#define GPF1_eint   (0x2<<(1*2))
#define GPF2_eint   (0x2<<(2*2))
#define GPF4_eint   (0x2<<(4*2))#define   GPF0_msk    (3<<(0*2))
#define GPF1_msk    (3<<(1*2))
#define GPF2_msk    (3<<(2*2))
#define GPF4_msk    (3<<(4*2))void disable_watch_dog(void)
{WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可
}void init_led(void)
{// LED1,LED2,LED4对应的3根引脚设为输出GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);GPFCON |= GPF4_out | GPF5_out | GPF6_out;
}/** 初始化GPIO引脚为外部中断* GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)*/
void init_irq( )
{//配置中断引脚GPFCON &= ~(GPF0_msk | GPF1_msk | GPF2_msk |GPF4_msk);GPFCON |= GPF0_eint | GPF1_eint | GPF2_eint | GPF4_eint;/** 设定优先级:*  ARB_MODE0 = 0, ARB_SEL0 = 00b*  ARB_MODE6 = 0, ARB_SEL6 = 00b*  ARB_MODE1、ARB_SEL1无需设置:因为这一组仲裁器只用了一个中断源*  优先级最终排名:EINT0 > EINT1 > EINT2 > EINT4*/PRIORITY = (PRIORITY & ( (~0x01) | (0x0<<7) | (~(0x1<<6))| (0x0<<19) ) );// EINT0、EINT1、EINT2、EINT4 使能INTMSK   &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<4));
}

代码分析:

中断优先级的设置:
ARM920t的中断优先级主要由7个仲裁器arbiter来控制,每个仲裁器连接的中断信号如图,最终0-5仲裁器选出来的信号还要6仲裁器来进行最后一轮的排优。

PRIORITY寄存器共有有20bit,被分成两部分功能:看2440手册,记得是英文版
[0-6]ARB_MODE:设置仲裁寄存器的工作模式,主要有自动轮流优先级和关闭该功能。一个仲裁器使用1bit
[7-20]ARB_SEL:控制输入中断信号的优先级。一个仲裁器使用2bit

(3)File:main.c   等待中断触发

int main()
{while(1);return 0;
}

搞定

ARM920T中断体系结构相关推荐

  1. Microsoft Windows CE .NET 中的中断体系结构

    概述 通过 Microsoft Windows CE .NET,Microsoft 已经升级了 Windows CE 的中断体系结构.该操作系统 (OS) 所具有的处理共享中断的能力极大地扩展了 Wi ...

  2. arm920t中断系统详解

    这篇文章把2410中断处理过程分析的淋漓尽致,感谢作者... 关于更详细的资料请参考920t的datasheet!!!!! 作者:蔡于清  www.another-prj.com 在进入正题之前,我想 ...

  3. S3C2440的中断体系结构

    概述 S3C2440A中的中断控制器接受来自60个中断源的请求.提供这些中断源的可以是内部外设,如DMA控制器.UART.IIC等等.在这些中断源中,UARTn.AC97和EINTn中断对于中断控制器 ...

  4. linux 在某个core上的中断 affinity c语言函数,Linux中断处理体系结构

    各种的异常的C处理函数可以分为5类,他们分布在不同的文件中. 1.在arch/arm/kernel/trapsc.c中 未定义指令异常,总入口函数为do_undefinstr. 2.在arch/arm ...

  5. 裸机篇 -- S5PV210的中断体系

        本帖主要通过外部中断实验来学习S5PV210的中断体系. S5PV210的中断体系结构 在官方datasheet -- S5PV210_UM_REV1.1 中的sections 04_inte ...

  6. WinCE中断结构分析

    前一段时间研究了一下WinCE下的中断结构,整理了一下,希望与大家讨论. 最下面有PDF版本下载,便于保存 版权申明:本文版权归ARMCE所有,转载请保留所有原文内容及 ARMCE标识并注明出 自 A ...

  7. linux 中断 c语言程序,linux驱动之中断处理过程C程序部分

    当发生中断之后,linux系统在汇编阶段经过一系列跳转,最终跳转到asm_do_IRQ()函数,开始C程序阶段的处理.在汇编阶段,程序已经计算出发生中断的中断号irq,这个关键参数最终传递给asm_d ...

  8. 《Windows CE嵌入式开发入门——基于Xscale架构》 第7章 Windows CE体系结构

    7.1  层次式架构 1.系统分层模型 操作系统(包括应用环境.操作环境等)一般具有分层的结构特征,典型的就是UNIX系统的同心环,最里面是硬件,从里向外依次是kernel.共享函数库.应用程序3个层 ...

  9. Linux下触摸屏驱动程序分析

    [摘要: 本文以 linux 3.5--Exynos4412仄台,剖析 触摸屏 驱动焦点内容.Linux下触摸屏驱动(以ft5x06_ts为例)须要懂得以下学问: 1. I2C协定 2. Exynos ...

  10. linux中断处理汇编入口,Linux中断处理体系结构分析(一)

    中断也是一种异常,之所以把它单独的列出来,是因为中断的处理与具体的开发板密切相关,除一些必须.共用的中断(比如系统时钟中断.片内外设UART中断)外,必须由驱动开发者提供处理函数.内核提炼出中断处理的 ...

最新文章

  1. 类加载器双亲委派模式
  2. DOS调用21H存取中断向量
  3. zz Microsoft Chart Controls for Microsoft .NET Framework 3.5
  4. 创建可调试,热加载的TypeScript+Koa工程
  5. GraphQL:从头开始
  6. docker安装消息队列延时插件
  7. 用c语言输出魔方阵答案,如何用C语言输出一个1—16 组成的4*4的魔方阵
  8. iOS【终极方案】精准获取webView内容高度,自适应高度
  9. du命令和df命令的区别
  10. 例4.4 最大公约数 - 九度教程第47题(最大公约数GCD)
  11. mapgis编辑属性结构编辑不了_在win 7系统中MAPGIS的区属性结构修改不了,而且出现死机...
  12. 非线性数学模型线性化
  13. 解决拉取远程分支后出现.xcodeproj Couldn't load project的问题
  14. 微服务项目架构演变过程
  15. JAVA的stream流操作详细解析
  16. 润乾打印控制解决方案
  17. 脱胎于沃尔沃的Polestar 2浮出水面,它真能挑战Model 3吗?
  18. digitalpersona 开发
  19. 嵌入式linux安装dropbear
  20. filezilla删除服务器文件,FileZilla的设置FTP服务器

热门文章

  1. python绘制饼图explode_python - 使用Python生成复合饼图或饼图饼图 - 堆栈内存溢出...
  2. JS逻辑运算符的与,或,非
  3. 论文重复率一般要求是多少?
  4. 一般描绘性形容词_描绘性形容词和限制性形容词
  5. 美元符号在什么计算机语言,美元符号是什么?怎么打?
  6. 使用基于迭代的敏捷创建里程碑
  7. Intelij的IDEA启动报错!parent directory is read-only or the user lacks necessary permissions
  8. 分类性能度量指标 : ROC曲线、AUC值、正确率、召回率、敏感度、特异度
  9. OPTEE学习笔记 - IPC
  10. matlab中累乘,numpy中的裁剪、压缩和累乘