当前位置: 首页 > news >正文

做网站书面报告申请西点培训前十名学校

做网站书面报告申请,西点培训前十名学校,郑州外贸网站建设公司,电子商务网站开发的主要支撑组件linux设备驱动归纳总结(六)#xff1a;1.中断的实现xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx一、什么是中断中断分两种#xff1a;1)中断#xff0c;又叫外部中断或异步中断#xff0c;它的产生是由于外设向处理器发出中断…linux设备驱动归纳总结(六)1.中断的实现xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx一、什么是中断中断分两种1)中断又叫外部中断或异步中断它的产生是由于外设向处理器发出中断请求。其中外部中断也有两种这是由配置寄存器设定的普通中断请求(IRQ)和快速中断请求(FIQ)。一般地linux下很少使用快速中断请求。2)异常又叫内部中断或同步中断它的产生是由于处理器执行指令出错。在以下的内容我是要介绍由于外部设备产生的中断。这里我还有两个名词要说清楚1)中断请求线在后面也叫中断号每个中断都会通过一个唯一的数值来标识而这个值就称做中断请求线2)在2440芯片中有些中断是需要共享一个中断寄存器中的一位如EINT4——EINT7它们是共享寄存器SRCPEND的第4位。具体可以查看芯片手册。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx二、什么是中断处理函数在相应一个中断是内核会执行该信号对应的一个函数该函数就叫做该中断对应的中断处理函数。一般来说中断的优先级是最高的一但接收到中断内核就会调用对应的中断处理函数。中断处理函数运行在中断上下文中。中断上下文与内核上下文有一点区别内核上下文是指应用层调用系统调用陷入内核执行内核代表陷入的进程执行操作。函数中可以通过current查看当前进程(即应用层的进程)的信息并且可以睡眠。中断上下文中不能通过current查看调用它的应用层进程的信息同时处于中断上下文时不能睡眠。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx一、从硬件角度看中断中断的产生到处理器获得中断这段过程中还要通过中断处理器来筛选信号。先温习一下S3C2440芯片手册的知识中断是如何产生的中断处理器本身如何处理中断。先看一下一幅经典的图这是介绍中断控制器的工作流程从硬件上的分类有两种不同的中断类型1)自己占有SORCPND寄存器的一位(withoutsub-register)。2)几个中断共同享用SRCPND寄存器的一位(withsub-register)。其实两种都差不多只是多了两步的检测。我以自己占用一位的中断来举例如EINT1在我的开发板EINT1上接了一个按键。1)当我按下按键产生电平变化传到S3C2440的中断控制器上(即将要进入上面图的流程图)。2)首先信号要经过寄存器SRCPNDSRCPND是用来配置当前的处理器要接收什么中断如果该寄存器配置成接收EINT1中断(对应位置一)则允许继续下一步。3)然后信号经过寄存器MASK这是用来设置当前系统需要屏蔽的中断。注意这里的屏蔽跟上一个寄存器的不接收中断是不一样的。这里的屏蔽是指中断是接受了但是由于某种原因先暂时不屏蔽产生的中断。4)通过INTPND寄存器查看当前是否有相同的中断已经被请求(如果是INTPND对应位置一)。5)如果没有相同的中断在请求中断处理器才会把这个信号传给处理器这时处理器才会知道有EINT0的中断真正来了要对信号进行处理了。注如果设定了EINT0是快速中断模式(FIQ)中断通过SRCPND寄存器后就会通过MODE寄存器的判断确定是FIQ后中断控制器优先将该中断传给CPU处理。6)对应传来的中断类型(IRQ或FIQ)通过CPSR寄存器切换到对应的工作模式(ARM有七种工作模式)。7)切换工作模式后进入指定的中断处理入口执行中断处理函数。注意第6、7步在linux下的实现相对复杂不像在裸板程序只需要切换一下工作模式执行相应的函数就可以了。迟点会介绍linux如何实现。来个流程图比较只在同时来个类比处理器是老板中断处理器是小秘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx四、注册和释放中断处理函数上面的介绍只是讲解了一个设备产生中断后要经过怎么样的步骤才能让处理器接收到中断信号。传入处理器后接下来的工作就是由内核来实现了那是一个复杂的机制我们这里先不说。但是内核提供了相关的接口给我们我们只要通过接口告诉内核当来了指定中断时内核你该执行哪个中断处理函数。注册中断处理函数/*include*/intrequest_irq(unsigned int irq, irq_handler_t handler,unsignedlong irqflags, const char *devname, void *dev_id)使用将中断号irq与中断处理函数handler对应参数irq指定要分配的中断号中断号的定义在“include/mach/irqs.h”中。注意不管是单独占有中断请求线的中断还是共享中断请求线的每个中断都有一个对应的中断号。所以调用该函数不需要考虑是哪种中断(是否共享寄存器)你想哪种中断响应你就填对应的中断号。handler中断处理函数指针。irqflags中断处理标记待会介绍devname该字符串将显示在/proc/irq和/pro/interrupt中。dev_idID号待会会介绍。返回值成功返回0失败返回非0。注册函数需要注意两件事1)该函数会睡眠。2)必须判断返回值。中断处理标志irqflags这里先介绍几个待会要用的/*linux-2.6.29/include/linux/interrupt.h*/29#define IRQF_TRIGGER_NONE 0x0000000030#define IRQF_TRIGGER_RISING 0x00000001 //上升沿触发中断31#define IRQF_TRIGGER_FALLING 0x00000002 //下降沿触发中断32#define IRQF_TRIGGER_HIGH 0x00000004 //高电平触发中断33#define IRQF_TRIGGER_LOW 0x00000008 //低电平触发中断34#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \35IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)36#define IRQF_TRIGGER_PROBE 0x00000010释放中断处理函数voidfree_irq(unsigned int irq, void *dev_id)编写中断处理函数中断处理函数声明如下staticirqreturn_t intr_handler(int irq, void *dev_id)先看第一个参数irq这是调用中断处理函数时传给它的中断号对于新版本的内核这个参数已经用处不大一般只用于打印。第二个参数dev_id这个参数与request_irq()的参数dev_id一致由于待会的程序我并不需要用这个参数所以先不介绍。再看返回值中断处理函数的返回值有三个/*linux-2.6.29/include/linux/interrupt..h*/21#define IRQ_NONE (0) //如果产生的中断并不会执行该中断处理函数时返回该值22#define IRQ_HANDLED (1) //中断处理函数正确调用会返回23#define IRQ_RETVAL(x) ((x) ! 0) //指定返回的数值如果非0返回IRQ_HADLER否则26#ifndef IRQ_NONE //返回IRQ_NONE。接下来就要写函数了在我的开发板中有一个按键是对应EINT1我要实现的操作是当我按下按键终端打印”keydown”。在这个程序中我并没有使用dev_id。这将在会以后的章节介绍。/*6th_irq_1/1st/test.c*/1#include2#include34#include5。。。省略。。。13irqreturn_t irq_handler(int irqno, void *dev_id) //中断处理函数14{15printk(key down\n);16return IRQ_HANDLED;17}1819static int __init test_init(void) //模块初始化函数20{21int ret;2223/*注册中断处理函数必须查看返回值24* IRQ_EINT1:中断号定义在include/mach/irqs.h中25* irq_handler中断处理函数26* IRQ_TIRGGER_FALLING中断类型标记下降沿触发中断27* ker_INT_EINT1中断的名字显示在/proc/interrupts等文件中28*NULL现在我不使用dev_id所以这里不传参数29*/30ret request_irq(IRQ_EINT1, irq_handler, IRQF_TRIGGER_FALLING,31key INT_EINT1, NULL);32if(ret){33P_DEBUG(request irq failed!\n);34return -1;35}36printk(hello irq\n);37return 0;38}3940static void __exit test_exit(void) //模块卸载函数41{42free_irq(IRQ_EINT1, NULL);43printk(good bye irq\n);44}4546module_init(test_init);47module_exit(test_exit);4849MODULE_LICENSE(GPL);50MODULE_AUTHOR(xoao bai);51MODULE_VERSION(v0.1);接下来验证一下[root:1st]# insmod test.kohelloirq[root:1st]# key down //按下按键显示keydownkeydownkeydown[root:1st]# cat /proc/interruptsCPU017:11 s3c-ext0 key INT_EINT1显示我注册和中断名字30:423482 s3c S3C2410 Timer Tick32:0 s3c s3c2410-lcd51:2782 s3c-ext eth070:49 s3c-uart0 s3c2440-uart71:69 s3c-uart0 s3c2440-uart79:0 s3c-adc s3c2410_action80:0 s3c-adc adc, s3c2410_action83:0 - s3c2410-wdtErr:0[root:key INT_EINT1]# rmmod test //卸载goodbye irq[root:key INT_EINT1]# cat /proc/interrupts //卸载后我的中断名字消失了CPU030:828977 s3c S3C2410 Timer Tick32:0 s3c s3c2410-lcd51:3202 s3c-ext eth070:192 s3c-uart0 s3c2440-uart71:277 s3c-uart0 s3c2440-uart79:0 s3c-adc s3c2410_action80:0 s3c-adc adc, s3c2410_action83:0 - s3c2410-wdtErr:0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx五、proc/interrupt接下来稍稍介绍一下proc/interrupt[root:1st]# cat /proc/interruptsCPU017:11 s3c-ext0 key INT_EINT1显示我注册和中断名字首先第一列是中断号之前的程序应该有人会有疑问中断号在哪里找的在S3C2440中这些中断号定义在文件include/mach/irqs.h中在这里可以找到对应的中断25/* main cpu interrupts */26#define IRQ_EINT0 S3C2410_IRQ(0) /* 16 */27#define IRQ_EINT1 S3C2410_IRQ(1)28#define IRQ_EINT2 S3C2410_IRQ(2)29#define IRQ_EINT3 S3C2410_IRQ(3)30#define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */在这里我标了两处红笔第一处可以看到S3C2440所有的中断号在原来的基值上加了16构成中断号但不同的芯片或许有不同的定义方法。第二处有些中断号是共享的。在S3C2440中EINT4---EINT7是共享寄存器SRCPND中的一位所以linux系统给这样的中断分配了一个共享的中断号。那就是说如果你使用IRQ_EINT4t7当收到这些中断时都会调用对应的中断处理函数。这就需要在中断处理函数中通过第一个传参irq来辨别中断并执行相应的操作。如13irqreturn_t irq_handler(int irqno, void *dev_id) //中断处理函数14{15switch(irqno){16。。。。}17}那肯定有人会说这太麻烦了吧有没有更好的办法处理共享中断号那当然是有继续看文件include/mach/irqs.h61/* interrupts generated from the external interrupts sources */62#define IRQ_EINT4 S3C2410_IRQ(32) /* 48 */63#define IRQ_EINT5 S3C2410_IRQ(33)64#define IRQ_EINT6 S3C2410_IRQ(34)65#define IRQ_EINT7 S3C2410_IRQ(35)66#define IRQ_EINT8 S3C2410_IRQ(36)看到了吧内核把共享的中断分离出来只要使用这些标记就可以了。其实上面我只是想说明无论在硬件上ARM是怎么实现中断的(是否共享)在内核看来所有的中断都是一样的都可以独自获得一个中断号。第二列“11”是对应处理器响应该中断的次数。第三列“s3c-ext0”是处理这个中断的中断控制器第四列一看就知道调用irq_request()时定义的中断名字。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx六、总结其实要实现中断大部分的工作已经给内核包了我们只需要做的就是告诉内核当来了什么中断要执行怎么样的函数这也是今天介绍的重点其实步骤很简单1)调用两个函数requesr_irq和free_irq。2)实现中断处理函数irq_handler()。还有没讲的知识1)还有几个irqflag没介绍。2)没有介绍dev_id。可能有人会加载上面的模块失败这也是我今天没介绍的只是共享中断号。这里说的共享和硬件的共享不一样性质下节会介绍。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
http://www.sadfv.cn/news/267170/

相关文章:

  • 免费炫酷企业网站源码记事本怎么做网站
  • 德阳建设局官方网站天津放心站内优化seo
  • 宁波门户网站建设广州做网站信科建设
  • 怎么制作网站视频播放器外包优化是什么意思
  • 品牌网站建设哪好哈尔滨互联网广告公司
  • 怎样设置网站主域名怎么建立网站的步骤
  • 厂字型布局网站有必要 在线 网页 代理
  • 企业网站建设 详细方案网站建设及空间
  • 网站与网页的区别.网站建设服务方案ppt
  • 东莞倣网站游戏开发软件工具
  • WordPress手机站插件WordPress上图片加载不出来
  • 手机网站优势网站建设法律法规
  • 怎么查找网站的根目录局域网如何做视频网站建设
  • 响应式电商网站制作广告推广平台代理
  • 网站建设技能考试试题三服务器调用wordpress
  • 江苏建筑工程信息网站app 软件开发
  • 网站内容建设出现的问题数据查询插件 wordpress
  • 酷站海洛牡丹江网络推广公司
  • 做盗版电影网站后果泰安招聘网
  • 网站在线推广计算机培训班价格
  • 网站做电商销售需要注册吗wordpress修改头像
  • 网站维护内容及费用毕业设计选择做网站的意义
  • 网站开发的历史创意广告图片及文字解析
  • 自建网站 好处网络营销与直播电商专业学什么就业方向是什么
  • 一站式平台网站开发技术室内装修3d动态演示效果图
  • 做网站难不难软件公司名称大全查询
  • 手机网站开发总结深圳家装
  • 电白网站建设平台网站做代理商
  • 长沙企业网站开发微联讯点如何做网盟推广网站
  • 深圳网站模板wordpress 页面父子级