S5PV210中断控制器详解(一):概述和使用中断
来源:互联网 发布:php网络验证源码post 编辑:程序博客网 时间:2024/06/04 23:22
1 S5PV210的Interrupt Controller简介
S5PV210是三星推出的一款基于Cortex-A8的Soc,其内部集成的中断控制器由4个ARM PrimeCell PL192矢量中断控制器级连(daisy-chain)而成,每个PL192 VIC(Vectored Interrupt Controller)支持32个中断源,所以最多支持128个。S5PV210使用了其中的93个。所谓“矢量”是指当中断发生时,软件可以直接从VIC得到提前设好的中断服务程序ISR(Interrupt Service Routine),对于S5PV210这样的单核CPU来说,PL192是一种比较高效的VIC。硬件上的连接图大体如下所示:
在图中,各个VIC之间连接的比较重要重要的信号,楼主都已经标注出来,最终连接到ARM CPU上的输入信号只有两个,IRQ和FIQ
2 什么样的中断会被送到CPU处理?
中断分为两种,一种是真实的外部硬件触发的中断,另一种叫软中断softInt,它是由软件写寄存器而触发。对应的寄存器为VICSOFTINT,当其中的某个bit位为非0,时,VIC就收到了一个softInt,softInt一般都是用在调试中,用于手动产生一个中断
下面这张图清楚的描述了中断请求的步骤:
左边的或门的输入是VICINTSOURCE和VICSoftInt,VICINTSOURCE来自外部,是其它Soc内部模块或者Soc外部产生的真实中断;VICSoftInt在框图的内部,是有VIC自己产生的。无论这两者哪个发生了,在VICRawInterrupt处都会看到这个中断源的存在。VICRawInterrupt对应的寄存器为:
这里三星官方给出的描述似乎有点问题,status of FIQ interrupt before masking,事实上,IRQ的status也是能看到的。
再看Interrupt Requst Logic图,中间的与门,其输入是从左边过来的VICRawInterrupt和VICIntEnable,VICIntEnable表明了已经使能的中断源,与之对应的寄存器有两个,如下所示
给VICENABLE寄存器里的某个bit写1,表明使能某个中断,而给VICINTCLEAR里的某个bit写1,表明是要disable某个中断。这两个寄存器都有一个特点,给对应的bit写0无效。不知道是为什么,许多中断控制器都采用这种方式,完全可以用一个VICENABLE寄存器来完成,写1为enable,写0为disable
VICIntSelect决定了Interrupt Requst Logic图最右边的选择器是输出IRQ和FIQ,这很好理解,对应的寄存器为:
默认情况下,所有的中断源都设置为IRQ interrupt
3 收到中断后,应该做些什么?
在ARM CPU收到中断的触发之后,硬件会自动将中断前的CPSR到SPSR_irq,保存PC到LR_irq,将CPSR的低5位设置为0x12(IRQ模式),并且关闭IRQ使能位(CPSR bit 7置1),然后ARM会将PC转到中断向量表的0x18偏移处,开始执行IRQ的入口函数。IRQ Handler在开始是要保存寄存器现场,然后跳转到真正的IRQ Handler。以上的这些内容对于所有的ARM CPU来说,都是一样的,固定动作。
到了IRQ Handler后,首先软件需要知道,哪个中断发生了,S5PV210的做法就是遍历VIC0IRQSTATUS~VIC3IRQSTATUS,不为0,代表该VIC有中断发生(VICIRQSTATUS也就是Interrupt request logic图中最右边的输出信号)。
再去读取发生中断的VIC对应的VICADDRESS,此时中断控制器硬件已经替我们选好了优先级最高的中断,并将其ISR推送到VICADDRESS寄存器里,我们可以直接拿到就执行,不用再像老式的方法,遍历VICIRQSTATUS里的每个bit位,找到不为0的那个,映射到具体的ISR,效率要高不少。
在ISR的结尾,需要将中断清除,以告诉硬件(Uart0和Interrupt controller),这次中断我处理完了,可以接收下个中断了。三星官方要求将All VICADDRESS都写0,不用担心误清了VIC0,2,3的中断,因为中断发生的源头还在,还会再次触发
When user clears interrupt pending, user must write 0 to all the VICADDRESS registers (VIC0ADDRESS, VIC1ADDRESS, VIC2ADDRESS, and VIC3ADDRESS).
关于矢量和优先级,请参考这篇博文S5PV210中断控制器详解(二):矢量和优先级。
4 编程使用中断
有了前面的理论知识后,编程使用中断就会水到渠成。以UART0为例,它是连接在VIC1的的第10号中断源上。
初始化代码如下:
void uart0_irq_init(void){ VIC1INTSELECT &= ~(1<<10); /* 设置为IRQ中断 */ VIC1INTENABLE |= 1<<10; /* 使能中断 */ VIC1VECTADDR10 = (unsigned int)Uart0_ISR; /* 设置ISR */}
中断向量表处的代码为:
IRQ_Handler:sub lr, lr, #4 /* 1.计算返回地址 */stmfd sp!, {r0-r12, lr} /* 2.保护现场 */bl do_irq /* 3. 处理异常 */ldmfd sp!, {r0-r12, pc}^ /* 4. 恢复现场 ^表示把spsr恢复到cpsr */
void do_irq(void){ void (*isr)(void) = NULL; if(0 != VIC0IRQSTATUS) isr = VIC0ADDRESS; else if(0 != VIC1IRQSTATUS) //如果uart0中断发生,VIC1IRQSTATUS不为0 isr = VIC1ADDRESS; //VIC1ADDRESS给出的就是之前给VIC1VECTADDR10写入的内容 else if(0 != VIC2IRQSTATUS) isr = VIC2ADDRESS; else if(0 != VIC3IRQSTATUS) isr = VIC3ADDRESS; if (isr) { (*isr)(); VIC0ADDRESS = 0; /* 清中断向量 */ VIC1ADDRESS = 0; VIC2ADDRESS = 0; VIC3ADDRESS = 0; }}
最后是Uar0IRQ的中断服务函数Uart0_ISR
void Uart0_ISR(void){ /* Check the exactly reason for uart0,tx rx or error Do something for it */ URP0 = 0xf; /* 清UART0里的中断源,URP0寄存器地址是0xE2900030 */}
阅读全文
0 0
- S5PV210中断控制器详解(一):概述和使用中断
- S5PV210中断控制器详解(二):矢量和优先级
- S5PV210的向量中断控制器
- 详解中断下半部tasklet 和workqueue(基于S5PV210的按键中断)
- 详解中断下半部tasklet 和workqueue(基于S5PV210的按键中断)
- 中断和中断处理(一)
- S5PV210系列 (裸机十)之按键和CPU的中断系统(一)
- ARM 中断处理和中断控制器
- STM32之外部中断和中断控制器
- 又是中断(一)-概述
- 十.ARM裸机学习之中断系统1(S5PV210的中断系统详解)
- 4.S5PV210中断相关寄存器详解
- 中断触发流程三(中断控制器)
- 中断触发流程三(中断控制器)
- 中断控制器
- 基于S5PV210的中断和外部按键中断
- (7)中断概述
- wince6.0 s5pv210 中断
- c.getContext("2d"); 为null 的问题
- Jsoup解析HTML获取数据的简单实例
- Walk
- Touch事件传递
- 部署CentOS 7操作系统
- S5PV210中断控制器详解(一):概述和使用中断
- 【LeetCode】1.Two Sum
- 随手记录的学习想法
- mysql function sf_get_full_manage_name_en
- 一个挺好的python中文分词库jieba
- 【已解决】:selenium.common.exceptions.WebDriverException: Message: 'geckodriver' ...
- Spring_04_Bean 生命周期
- 程序员应该思考的问题
- 重新定义一个全新的区块链运行架构:他们的技术有何不同?