历史上的今天
返回首页

历史上的今天

今天是:2025年03月30日(星期日)

正在发生

2021年03月30日 | linux-2.6.26内核中ARM中断实现详解(1)

2021-03-30 来源:eefocus

看了一些网络上关于linux中断实现的文章,感觉有一些写的非常好,在这里首先感谢他们的无私付出,然后也想再补充自己对一些问题的理解。先从函数注册引出问题吧。


一、中断注册方法


在linux内核中用于申请中断的函数是requeST_IRq(),函数原型在Kernel/irq/manage.c中定义:


int request_irq(unsigned int irq, irq_handler_t handler,


unsigned lONg irqflags, const char *devname, void *dev_id)


irq是要申请的硬件中断号。


handler是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它。


irqflags是中断处理的属性,若设置了IRQF_DISABLED (老版本中的SA_INteRRUPT,本版zhon已经不支持了),则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置了IRQF_SHARED (老版本中的SA_SHIRQ),则表示多个设备共享中断,若设置了IRQF_SAMPLE_RANDOM(老版本中的SA_SAMPLE_RANDOM),表示对系统熵有贡献,对系统获取随机数有好处。(这几个flag是可以通过或的方式同时使用的)


dev_id在中断共享时会用到,一般设置为这个设备的设备结构体或者NULL。


devname设置中断名称,在cat /proc/interrupts中可以看到此名称。


request_irq()返回0表示成功,返回-INVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经被占用且不能共享。


关于中断注册的例子,大家可在内核中搜索下request_irq。


在编写驱动的过程中,比较容易产生疑惑的地方是:


1、中断向量表在什么位置?是如何建立的?


2、从中断开始,系统是怎样执行到我自己注册的函数的?


3、中断号是如何确定的?对于硬件上有子中断的中断号如何确定?


4、中断共享是怎么回事,dev_id的作用是?


本文以2.6.26内核和S3C2410处理器为例,为大家讲解这几个问题。


二、异常向量表的建立


在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。V和中断向量表的对应关系如下:


V=0 ~ 0x00000000~0x0000001C


V=1 ~ 0xffff0000~0xffff001C


arch/arm/mm/proc-arm920.S中


.section ".text.init", #alloc, #execinstr


__arm920_setup:


…… orr r0, r0, #0x2100 @ ..1. ...1 ..11 ...1


//bit13=1 中断向量表基址为0xFFFF0000。R0的值将被付给CP15的C1.


在linux中,向量表建立的函数为:


init/main.c->start_kernel()->trap_init()


void __init trap_init(void)


{


unsigned long vectors = CONFIG_VECTORS_BASE;


……


memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);


memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);


....


}


在2.6.26内核中CONFIG_VECTORS_BASE最初是在各个平台的配置文件中设定的,如:


arch/arm/configs/s3c2410_defconfig中


CONFIG_VECTORS_BASE=0xffff0000


__vectors_end 至 __vectors_start之间为异常向量表。


位于arch/arm/kernel/entry-armv.S


.globl __vectors_start


__vectors_start:


swi SYS_ERROR0:


b vector_und + stubs_offset //复位异常:


ldr pc, .LCvswi + stubs_offset //未定义指令异常:


b vector_pa^ + stubs_offset //软件中断异常:


b vector_da^ + stubs_offset //数据异常:


b vector_addrexcptn + stubs_offset //保留:


b vector_irq + stubs_offset //普通中断异常:


b vector_fiq + stubs_offset //快速中断异常:


.globl __vectors_end:


__vectors_end:


__stubs_end 至 __stubs_start之间是异常处理的位置。也位于文件arch/arm/kernel/entry-armv.S中。vector_und、vector_pa^、vector_irq、vector_fiq都在它们中间。


stubs_offset值如下:


.equ stubs_offset, __vectors_start + 0x200 - __stubs_start


stubs_offset是如何确定的呢?(引用网络上的一段比较详细的解释)


当汇编器看到B指令后会把要跳转的标签转化为相对于当前PC的偏移量(±32M)写入指令码。从上面的代码可以看到中断向量表和stubs都发生了代码搬移,所以如果中断向量表中仍然写成b vector_irq,那么实际执行的时候就无法跳转到搬移后的vector_irq处,因为指令码里写的是原来的偏移量,所以需要把指令码中的偏移量写成搬移后的。我们把搬移前的中断向量表中的irq入口地址记irq_PC,它在中断向量表的偏移量就是irq_PC-vectors_start, vector_irq在stubs中的偏移量是vector_irq-stubs_start,这两个偏移量在搬移前后是不变的。搬移后 vectors_start在0xffff0000处,而stubs_start在0xffff0200处,所以搬移后的vector_irq相对于中断 向量中的中断入口地址的偏移量就是,200+vector_irq在stubs中的偏移量再减去中断入口在向量表中的偏移量,即200+ vector_irq-stubs_start-irq_PC+vectors_start = (vector_irq-irq_PC) + vectors_start+200-stubs_start,对于括号内的值实际上就是中断向量表中写的vector_irq,减去irq_PC是由汇编器完成的,而后面的 vectors_start+200-stubs_start就应该是stubs_offset,实际上在entry-armv.S中也是这样定义的。


推荐阅读

史海拾趣

AnalogicTech公司的发展小趣事

AnalogicTech深知品质是企业生存和发展的关键。因此,公司建立了严格的质量管理体系,从原材料采购到产品出厂的每一个环节都进行严格把控。同时,公司还注重客户反馈和需求,不断优化产品和服务,以满足客户的期望和需求。这种对品质的执着追求和对客户的深度关注,使得AnalogicTech赢得了众多客户的信任和忠诚。

DMC Tools公司的发展小趣事

在发展过程中,DMC Tools公司积极寻求国际合作,与多家国际知名电子企业建立了长期稳定的合作关系。通过与这些企业的合作,DMC Tools公司不仅学习到了先进的生产技术和管理经验,还拓宽了自己的市场视野。这些国际合作项目为公司带来了大量的订单和利润,同时也提升了公司的国际竞争力。

East Texas Integrated Circuits公司的发展小趣事

East Texas Integrated Circuits公司(ETIC)成立于XX世纪初,最初只是一个由几位电子工程师组成的创业团队。他们的梦想是利用最新的技术研发高性能的集成电路。通过不断的努力,他们成功地研发出了一种新型的低功耗集成电路,这种电路能够在保持高速度的同时降低能源消耗,迅速在市场上获得了认可。

ENTRELECUK公司的发展小趣事

在电子行业的早期,ENTRELEC UK以其创新的接触器设计在市场中脱颖而出。随着技术的进步,公司不断研发新产品,如过载继电器和电动机保护开关,这些产品迅速获得了市场的认可。公司通过持续的研发投入,确保产品始终走在行业前沿,为客户提供更安全、更可靠的解决方案。

Concurrent Logic公司的发展小趣事

面对日新月异的市场需求和不断变化的技术趋势,Concurrent Logic始终坚持创新驱动的发展战略。他们投入大量资源在研发上,不断探索新的并行计算技术和应用。通过持续的创新和市场的不断拓展,Concurrent Logic逐渐巩固了其在电子行业中的领导地位,成为了并行计算领域的一面旗帜。他们的产品被广泛应用于云计算、大数据分析、人工智能等多个前沿领域,为整个电子行业的发展注入了新的活力。

以上是关于电子行业里Concurrent Logic公司发展起来的相关故事,每个故事都反映了该公司在不同发展阶段所面临的关键节点和决策。

Global Mixed-Mode Technology Inc公司的发展小趣事
三相缺相报警灯电路可以与其他电气保护设备配合使用,共同保障电气系统的安全稳定运行。例如,当三相缺相报警灯电路检测到缺相情况时,可以发出警报信号给操作人员或监控系统;同时,断路器或过载保护器等设备也可以根据设定的保护参数来切断故障电路或降低负载功率等措施来防止设备损坏或生产事故的发生。这些设备之间通过电气信号或控制逻辑相互关联和配合工作。

问答坊 | AI 解惑

高质量C 编程指南

如题,对写好代码很有帮助。…

查看全部问答>

后PC时代,高校纷纷转向嵌入式专业

作为后PC时代及后网络时代的新秀,嵌入式系统凭借其在网络安全、智能家电、车载电子、消费类电子、工业控制、医疗电子等领域内日益广泛地应用和发展,已无疑成为后PC时代的擎天之柱,现在的电子技术俨然已成为嵌入式系统技术的天下。 2010年 ...…

查看全部问答>

[请问]怎样在EVC4.0SP4中引用miracl库函数?

我在工程的Header Files里添加了miracl.h和mirdef.h两个头文件,还添加了ms32.lib文件,但在编程中使用otnum()等等miracl库中的函数时仍提示错误。 Repw.obj : error LNK2019: unresolved external symbol \"int __cdecl otnum(struct bigtype *,v ...…

查看全部问答>

关于对嵌入式开发了解的问题

  小弟由于想转入到嵌入式开发的领域中来,所以需要一些最基本的了解,以便有一个更清晰的学习开端,请多多指教:      问题1:在网上查了下嵌入式开发的理解,但越看越晕,一会儿是嵌入式开发,一会儿是linux嵌入 ...…

查看全部问答>

VC开发驱动怎么设置环境啊。急。

想在VC里面写驱动 但是搭建环境完全不会  哪个好心人给我详细说明。。…

查看全部问答>

MSP430中断嵌套机制

(1)430默认的是关闭中断嵌套的,除非你在一个中断程序中再次开总中断EINT。(2)当进入中断程序时,只要不在中断中再次开中断,刚总中断是关闭的,此时来中断不管是比当前中断的优先级高还是低都不执行。(3)若在中断A中开了总中断,刚可以响应 ...…

查看全部问答>

这个IAR调试问题怎么解决啊

本人菜鸟。今天在使用IAR出现了这个问题,以前都好好的。。怎么会出现头文件加载错误的…

查看全部问答>

LPC800 开发板 电路图

我下载到了电路图,可是没看懂如何在面包板上接线。 请高手帮忙介绍一下。这几排孔哪些已经定义好了。谢谢。…

查看全部问答>

论坛被侵略了……

真不知道怎么说好 …

查看全部问答>

你问我答——FPGA布线时需要注意哪些?

大家好:         我在布FPGA板子,是四层还是二层的呢,希望大家给点建议。         电源线,时钟线,低线有什麽讲究的! 谢谢大家了!…

查看全部问答>