tq2440_External Interrupt Controller

2024-06-11 16:18

本文主要是介绍tq2440_External Interrupt Controller,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在开始之前整理一下ARM9结构中断建立过程:

/* EXCEPTION HANDLER VECTOR TABLE */ 
^ DRAM_BASE 

HandleUndef # 4 
HandleSwi # 4 
HandlePrefetch # 4 
HandleAbort # 4 
HandleReserv # 4 
HandleIrq # 4 
HandleFiq # 4 
小注: 这里的^是MAP,#是FIELD 
也就是在DARM的BANK0里面最开始的地方定义了一个中断向量表(已经固化了的),这些中断向量在程序储存空间中占用一个连续的地址空间段(只有几个字节,一条指令的长度)。中断向量就是发生中断和异常时的一个标识,代表着中断程序的入口地址,即指定各异常中断与其处理程序的对应关系。当中断源发出的中断信号被CPU检测到后,如果中断系统允许响应这个中断请求,程序会自动跳转到这个中断向量处去执行。在中断向量区只存放有一条指向中断处理程序的指令,中断处理程序还存在其他的地方。因此,中断触发之后CPU就能找到对应的处理程序的入口了。



使用s3c2440的外部中断需要配置的寄存器有:SRCPND、INTMSK、INTPND、EXTINTn、PRIORITY、EINTMASK、EINTPEND,还有就是2440的外部中断I/O引脚是第F和G组所以也要根据需要配置这两组I/O对应的寄存器。当然还有一个中断模式选择的寄存器INTMOD,这是用来配置普通中断IRQ和快中断FIQ的,上电复位的初始状态是IRQ。

前面说到的那些寄存器有些是用来设置是否屏蔽中断请求的,有些是用来反映程序运行时中断请求的状态的这是为了能够进入中断处理程序。下面结合中断点灯例程序程序做一一介绍:

startup.S文件

@ File:startup.S
@ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数      
.extern     main
.text 
.global _start 
_start:      @ 注:在定义异常向量时即使有些异常模式不需要用到但是还是要按照中断向量的顺序一一定义      b   Reset          @0x00:上电复位HandleUndef:           @ 0x04: 未定义指令中止模式的向量地址b   HandleUndef HandleSWI:             @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式b   HandleSWIHandlePrefetchAbort:   @ 0x0c: 指令预取终止导致的异常的向量地址b   HandlePrefetchAbortHandleDataAbort:       @ 0x10: 数据访问终止导致的异常的向量地址b   HandleDataAbortHandleNotUsed:         @ 0x14: 保留b   HandleNotUsedb   HandleIRQ      @ 0x18: 中断模式的向量地址HandleFIQ:             @0x1C:快中断模式的向量地址b   HandleFIQ@下面是对上面需要用到的向量的定义:Reset:                  ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈  这里是栈顶,因为片内内存只有4K(4*1024=4096)bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启msr CPSR_c, #0xd2       @ 进入中断模式,只有在中断模式下才可以设置对应的栈,这里只是设置堆栈,所以禁止所有的中断ldr sp, =3072           @ 设置中断模式栈指针msr cpsr_c, #0xd3       @ 进入管理模式ldr sp, =4096           @ 设置管理模式栈指针,上电复位之后,CPU就处于管理模式,bl  init_led            @ 初始化LED的GPIO管脚bl  init_irq            @ 调用中断初始化函数,在init.c中msr cpsr_c, #0x53       @ 设置设置控制位[0-7bit],开IRQ中断。CPSR是使能跳转到异常中断向量入口的根本原因ldr lr, =halt_loop      @ 设置返回地址ldr pc, =main           @ 调用main函数  也可以直接用一句:bl main 代替
halt_loop:b   halt_loopHandleIRQ:sub lr, lr, #4                  @ 计算返回地址,用于返回stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器@ 注意,此时的sp是中断模式的sp@ 初始值是上面设置的3072ldr lr, =int_return             @ 设置调用EINT_Handle函数后的返回地址      ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中int_return:ldmia   sp!,    { r0-r12,pc }^  @ 中断返回,出栈, ^表示将spsr的值复制到cpsr,这样可以回到管理模式

init.c文件

#include"s3c2440.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))//用于将GPF组IO设置成外部中断
#define GPF1_int    (0x2<<(1*2))
#define GPF4_int    (0x2<<(4*2))
#define GPF2_int    (0x2<<(2*2))
#define GPF0_int    (0x2<<(0*2))#define GPF1_msk    (3<<(1*2))
#define GPF4_msk    (3<<(4*2))
#define GPF2_msk    (3<<(2*2))
#define GPF0_msk    (3<<(0*2))void disable_watch_dog(void)
{WTCON = 0;
}void init_led(void)
{GPBCON &= ~(GPB5_msk | GPB6_msk | GPB7_msk | GPB8_msk);GPBCON |= GPB5_out | GPB6_out | GPB7_out | GPB8_out;GPBDAT |=(0xF<<5);GPBUP &= ~((1<<5)|(1<<6)|(1<<7)|(1<<8));
}//外部中断初始化
void init_irq()
{GPFCON &= ~(GPF1_msk | GPF4_msk | GPF2_msk | GPF0_msk);GPFCON |= GPF1_int | GPF4_int | GPF2_int | GPF0_int;  //中断模式EXTINT0 &= ~((7<<0)|(7<<1)|(7<<2)|(7<<4));     //低电平触发PRIORITY = (PRIORITY & ((~0x01) | ~(0x3<<7)));INTMOD=0x0;SRCPND = 0x17;          //清除ENIT0、1、2、4的中断标志位INTPND = 0x17;              EINTPEND |= (1<<4);//使能中断EINTMASK &= ~(1<<4);INTMSK &= ~((1<<4)|(1<<2)|(1<<1)|(1<<0));
}
interrupt.c文件

#include "s3c2440.h"void EINT_Handle()
{unsigned long oft = INTOFFSET;
//  unsigned long val = EINTPEND;GPBDAT |= (0xF<<5);   // 所有LED熄灭if (oft==1){// K1被按下GPBDAT &= ~(1<<5);      // LED1点亮}if (oft==4){// K2被按下GPBDAT &= ~(1<<6);      // LED2点亮}if (oft==2){// K3被按下GPBDAT &= ~(1<<7);      // LED3点亮}if (oft==0){// K4被按下GPBDAT &= ~(1<<8);      // LED4点亮}//清中断标志位EINTPEND = (1<<1) | (1<<4) | (1<<2) | (1<<0);    SRCPND = 1<<oft;  //先INTPND = 1<<oft;  //后
}
main.c

int main( )
{while(1);return 0;	
}
makefile文件
objs := startup.o init.o interrupt.o main.oint.bin: $(objs)arm-linux-ld -Ttext 0x00000000 -o int_elf $^arm-linux-objcopy -O binary -S int_elf $@arm-linux-objdump -D -m arm int_elf > int.dis%.o:%.carm-linux-gcc -Wall -O2 -c -o $@ $<%.o:%.Sarm-linux-gcc -Wall -O2 -c -o $@ $<clean:rm -f int.bin int_elf int.dis *.o
编程小结:

(1)在启动代码里做好一些要用到的硬件初始化的C跳转,设置好中断异常模式下的堆栈、出入栈,然后设置中断向量

(2)中断初始化:设置模式,外部中断触发方式,优先级,清除标志位,使能中断
(3)中断处理函数的定义:处理内容+最后的清中断标志位

好了,外部中断就写到这里。微笑


























这篇关于tq2440_External Interrupt Controller的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1051659

相关文章

MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)

1、MVC MVC(Model-View-Controller) 是一种常用的架构模式,用于分离应用程序的逻辑、数据和展示。它通过三个核心组件(模型、视图和控制器)将应用程序的业务逻辑与用户界面隔离,促进代码的可维护性、可扩展性和模块化。在 MVC 模式中,各组件可以与多种设计模式结合使用,以增强灵活性和可维护性。以下是 MVC 各组件与常见设计模式的关系和作用: 1. Model(模型)

Spring 注解(@Repository 、@Service 和 @Controller )

Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller 。         在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层 、业务层 和控制层 相对应。虽然目前这 3 个注释和 @

easyswoole not controller class match

not controller class match composer.json 注册 App 这个名称空间了吗?执行过 composer dump-autoload 了吗?存在 Index 控制器,但是文件大小写、路径都对了吗? task socket listen fail 注意,在部分环境下,例如 win10 的 docker 环境中,不可把虚拟机共享目录作为 EasySwoole 的 T

Spring是如何找到URL请求对应的Controller的

文章来源 原文作者:Spring MVC 原文地址: https://blog.csdn.net/hl233211/article/details/77450697 http://ddrv.cn/a/58528 本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。 序:先贴一张SpringMVC整体的框架原理图 此文主要描述Spring在响应请求的时候是如何根据U

Win10 - 即插即用的external audio device detected问题

问题     有些牌子的笔记本,在win10下每次插入外设耳机,都会跳出带有 external audio device detected 字样的音频输出设备选择框需要选择 方案     1、在开始菜单选择 运行 ,输入 regedit 后回车打开注册表     2、在注册表中定位到 HKEY_CURRENT_USER\SOFTWARE\Realtek\Audio\RtkNGUI64

DDR的Controller、Channel、Chip、Rank、Bank、Row、Column、Sided、Dimm

目录 概览 1.概览             先从半导体生产开始,生产出来还没切割的叫晶圆(wafer)。切割出来还没封装的叫裸die(bare die)。封装好的叫颗粒(component)。做成内存条后叫模组(module)。下文我们也会按这样的称呼去区分。 2.Controller(内存控制器)         一开始内存控制器在主板上有独立的芯片;在英特尔微处理器

springmvc 页面跳转不到Controller层

可能产生的原因: 1、路径错误(犯了低级错误。。。) 2、检查Controller层的类是否未装配到spring中,看看是不是忘记写注解了。 3、注解扫描没扫描到你的Controller层。(很可能是这个原因)     比如你的包扫描只扫到 com.it.hoop。 而你的Controller所在包为:com.itt.hoop 当然扫描不到

Webots入门(二)-build up a controller

A simple controller 控制器程序读取传感器的值,然后修改行走速度来避开障碍物。 下面是控制器源代码mybot_simple.c: #include<webots/robot.h>#include<webots/differential_wheels.h>#include<webots/distance_sensor.h>#define SPEED 60#defi

sqlite3的db.interrupt方法深入解析

在Node.js环境中,sqlite3库是一个广受欢迎的轻量级数据库库,它为开发者提供了一个简洁的API来与SQLite数据库进行交互。在处理长时间运行或复杂的数据库查询时,有时可能需要中断这些查询。sqlite3库提供了db.interrupt方法来实现这一功能。本文将深入解析db.interrupt方法,包括其API函数定义和相应的代码示例解释。 一、db.interrupt方法简介 db

理解interrupt()方法

java interrupt()方法只是设置线程的中断标记,当对处于阻塞状态的线程调用interrupt方法时(处于阻塞状态的线程是调用sleep, wait, join 的线程),会抛出InterruptException异常,而这个异常会清除中断标记。因此,根据这两个思路,不同的run()方法设计,会导致不同的结果,下面是示例,并说明了运行了结果和原因 package com.concurr