赞
踩
1.什么是中断
中断的发明是用来解决宏观上的并行需要的。宏观就是从整体上来看,并行就是多件事情都完成了。
如:一个人在看电影,快递来了暂停电影跑去收快递,收完快递继续回来看电影,这个例子就是宏观上的并行和微观上的串行。例子中一个人等同于SoC中1个CPU(也就是单核CPU),这个CPU看电影就不能收快递,收快递就不能看电影(也就是说不能真正的并行)。单核心CPU在微观角度是串行的,但是因为CPU很快,所以在宏观看来可以并行。
2.中断处理第一阶段:绑定异常向量表
在CPU设计时,就事先定义了CPU中一些特定地址作为特定异常的入口地址,硬件已经决定了发生什么异常CPU自动跳转PC到哪个地址去执行,软件需要做的就是把处理这个异常的代码的首地址填入这个异常向量地址。
-> 像内存一样去访问异常向量表
iRAM中的异常向量表起始地址为0xD0037400。知道了异常向量表的起始地址后,各个异常对应的入口就很好知道了。
-> 函数名的实质就是函数的首地址
函数名就是这个函数的函数指针,编译器会把这个函数的函数体对应的代码段和这个函数的函数名(实质是符号)对应起来,函数名实际对应的是函数体那一个代码段的首地址。
-> int.h文件进行异常向量表的绑定:
- #ifndef __INT_H__
- #define __INT_H__
-
-
- #define exception_vector_table_base 0xD0037400 //cpu异常向量表的基地址
- #define exception_reset (exception_vector_table_base + 0x00)
- #define exception_undef (exception_vector_table_base + 0x04)
- #define exception_sotf_int (exception_vector_table_base + 0x08)
- #define exception_prefetch (exception_vector_table_base + 0x0C)
- #define exception_data (exception_vector_table_base + 0x10)
- #define exception_irq (exception_vector_table_base + 0x18)
- #define exception_fiq (exception_vector_table_base + 0x1C)
-
- #define r_exception_reset (*(volatile unsigned int *)exception_reset)
- #define r_exception_undef (*(volatile unsigned int *)exception_undef)
- #define r_exception_sotf_int (*(volatile unsigned int *)exception_sotf_int)
- #define r_exception_prefetch (*(volatile unsigned int *)exception_prefetch)
- #define r_exception_data (*(volatile unsigned int *)exception_data)
- #define r_exception_irq (*(volatile unsigned int *)exception_irq)
- #define r_exception_fiq (*(volatile unsigned int *)exception_fiq)
-> 异常向量的执行函数int.c:
- #include "int.h"
- #include "stdio.h"
-
-
-
- void system_init_exception(void)
- {
- r_exception_reset = (unsigned int)reset_exception;
- r_exception_undef = (unsigned int)undef_exception;
- r_exception_sotf_int = (unsigned int)sotf_int_exception;
- r_exception_prefetch = (unsigned int)prefetch_exception;
- r_exception_data = (unsigned int)data_exception;
- r_exception_irq = (unsigned int)IRQ_handle;
- r_exception_fiq = (unsigned int)IRQ_handle;
-
-
- }
-
- void reset_exception(void) //复位异常,到此处执行复位的操作,下面的各个函数的功能都类似
- {
- printf("reset_exception.\n");
- }
-
- void undef_exception(void)
- {
- printf("undef_exception.\n");
- }
-
- void sotf_int_exception(void)
- {
- printf("sotf_int_exception.\n");
- }
-
- void prefetch_exception(void)
- {
- printf("prefetch_exception.\n");
- }
-
- void data_exception(void)
- {
- printf("data_exception.\n");
- }
-
-
-
- // 真正的中断处理程序。意思就是说这里只考虑中断处理,不考虑保护/恢复现场
- void irq_handler(void)
- {
- //printf("irq_handler.\n");
- // SoC支持很多个(在低端CPU例如2440中有30多个,在210中有100多个)中断
- // 这么多中断irq在第一个阶段走的是一条路,都会进入到irq_handler来
- // 我们在irq_handler中要去区分究竟是哪个中断发生了,然后再去调用该中断
- // 对应的isr。
-
- }
3.中断处理第三阶段:判断具体发生的中断
处理过程:
S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。
当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,我们软件只要去这个寄存器中执行函数就行了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。