中断与时钟机制
中断的概念
中断:在计算机执行程序的过程中,由于出现某个特殊的情况(事件),使得暂时中止正在运行的程序,而转去执行这一特殊事件的处理,处理完毕之后再回到原来程序继续向下继续执行,这个过程就是中断。
通常情况下,一个驱动程序只要申请中断,并添加中断处理函数就可以了。中断的到达和中断处理函数的调用,都是由内核框架完成的。
中断的分类
中断的分类:
硬件中断(外部中断,异步中断):可屏蔽中断和不可屏蔽中断。
软件中断(内部中断,同步中断):异常和系统调用。
中断又分为硬中断和软中断。
硬中断:就是由系统硬件产生的中断。系统硬件通常引起外部事件。外部事件具有随机性和突发性,因此硬中断也具有随机性和突发性。
软中断:是执行中断指令时产生的。软中断不用外设施加中断请求信号,因此中断的发生不是随机而是由程序安排好的。
中断又分为外部中断和内部中断。
外部中断一般是指计算机外设发出的中断请求。外部中断是可以通过编程方式屏蔽的。例如键盘中断,打印机中断,定时器中断等。
内部中断是指因硬件出错(突然掉电,奇偶校验错误)或者运算错误(除数为零,运算溢出,单步中断)所引起的中断。内部中断是不可屏蔽的中断。大多数内部中断都是由Linux内核进行处理的,所以驱动程序员往往不需要关系这些问题。
中断又分为同步中断和异步中断。
同步中断是指令执行的过程中有CPU控制的,CPU在执行完一条指令后才发出中断。
异步中断是由硬件设备随机产生的,产生中断时并不考虑与处理器的时钟同步问题,该类型的中断时可以随时产生的。
中断信号线
中断信号线(IRQ)
中断信号线是对中断输入线和中断输出线的统称。中断输入线是指接收中断信号的引脚。中断输出线是指发送中断信号的引脚。每一个能够产生中断的外设都有一条或者多条中断输出线,用来通知处理器产生中断。相应地,处理器也有一组中断输入线,用来接收连接到它的外部设备发出的中断信号。
中断控制器
中断控制器
中断控制器位于ARM处理器核心和中断源之间。外部中断源将中断发到中断控制器。中断控制器根据优先级进行判断,然后通过引脚将中断请求发送给ARM处理器核心。
Linux初始化中断步骤
Linux初始化中断具体步骤:
/* 1 获取中断号 */
/* 1.1 设备树中获取中断号 */ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
/* 1.2 GPIO中获取中断号 */ int gpio_to_irq(unsigned int gpio)
/* 2 编写中断服务函数 */ inputkeydev.key_irq1[0].handler = key_irq_handler;
/* 3 设置中断code类型 */ inputkeydev.key_irq1[0].code = KEY_0;
/* 4 申请中断 */ int __must_check request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
/* 5 释放中断 */ void free_irq(unsigned int, void *);
时间度量
Linux内核中的一个重要的全局变量是Hz,这个变量表示与时钟中断相关的一个值。时钟中断是由系统定时硬件以周期性的间隔产生,这个周期性的值由Hz来表示。
这里Hz的意思是每一秒钟时钟中断发生1000次。每当时钟中断发生时,内核内部计数器的值就会加上1。内部计数器是由jiffies变量来表示。当系统初始化时,这个变量被设置为0。
时间延时
短时延时
纳秒、微秒和毫秒延时函数。
void ndelay(unsigned long nsecs)
void udelay(unsigned long usecs)
void mdelay(unsigned long mseces)
长时延时