arm驱动linux内核中断编程

发布者:温暖微风最新更新时间:2016-06-06 来源: eefocus关键字:arm驱动  linux内核  中断编程 手机看文章 扫描二维码
随时随地手机看文章

第一部分获取中断(开启硬件中断)

一、中断的申请注销:
1)中断的申请

int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)

2)中断的注销

void free_irq(unsigned int irq, void *dev_id)

3)中断处理函数

static irqreturn_t irq_handle(int irq, void *dev__id);

参数:irq:表示中断号,这个参数还保留由于历史遗留问题,往后可能越来越没用了。由于第二个参数信息更强大
dev__id:就是request_irq()中void *dev_id参数。
二、中断申请函数参数

int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)

1)参数:
irq:是要申请的硬件中断号。
handler:是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它。
irqflags:是中断处理的属性,
a)若设置了IRQF_DISABLED,则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;
b)若设置了 IRQF_SHARED,则表示多个设备共享中断;//在另一篇文章会提到
c)若设置了IRQF_SAMPLE_RANDOM,表示对系统熵有贡献,对系统获取随机数有好处。
Tip:(flag是可以通过或的方式同时使用的)
devname:设置中断名称,通常是设备驱动程序的名称 在cat /proc/interrupts中可以看到此名称。
dev_id:在中断共享时会用到,一般设置为这个设备的设备结构体或者不使用时为NULL。因为在共享中断中同一个中断线(或可以说同一个中断号)可能挂载好几个设备,当使用void free_irq(unsigned int irq, void *dev_id)时,根据irq和dev_id可以找到中断线为irq上的标识为dev_id的某个具体设备。dev_id也经常在不是共享中断中的驱动传递数据

2)返回值:
a)request_irq()返回0表示成功;
b)返回-EINVAL表示无效的参数,如果返回这个值,应该看看传递给request_irq()的参数是否正确;
c)返回-EBUSY表示中断已经被占用且不能共享;
d)返回ENOMEM表示内存不足。嵌入式系统由于内存资源有限,经常会发生这样的错误。

3)扩展---unsigned long irqflags值
在include\linux\interrupt.h中

/*
* These correspond to the IORESOURCE_IRQ_* defines in
* linux/ioport.h to select the interrupt line behaviour. When
* requesting an interrupt without specifying a IRQF_TRIGGER, the
* setting should be assumed to be "as already configured", which
* may be as per machine or firmware initialisation.
*/
#define IRQF_TRIGGER_NONE 0x00000000
#define IRQF_TRIGGER_RISING 0x00000001
#define IRQF_TRIGGER_FALLING 0x00000002
#define IRQF_TRIGGER_HIGH 0x00000004
#define IRQF_TRIGGER_LOW 0x00000008
#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE 0x00000010
/*
* These flags used only by the kernel as part of the
* irq handling routines.
*
* IRQF_DISABLED - keep irqs disabled when calling the action handler
* IRQF_SAMPLE_RANDOM - irq is used to feed the random generator
* IRQF_SHARED - allow sharing the irq among several devices
* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
* IRQF_TIMER - Flag to mark this interrupt as timer interrupt
* IRQF_PERCPU - Interrupt is per cpu
* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
* registered first in an shared interrupt is considered for
* performance reasons)
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
#define IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000

Tip:下面是老版本(2.4内核irqflags的值),不要在新版本使用。(2.6 内核及2.6以上内核都为新内核)

/*
* Migration helpers. Scheduled for removal in 9/2007
* Do not use for new code !//不要的新版本使用,2.6 内核及2.6以上内核都为新内核
*/
static inline
unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
{
return flag;
}
#define SA_INTERRUPT deprecated_irq_flag(IRQF_DISABLED)
#define SA_SAMPLE_RANDOM deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
#define SA_SHIRQ deprecated_irq_flag(IRQF_SHARED)
#define SA_PROBEIRQ deprecated_irq_flag(IRQF_PROBE_SHARED)
#define SA_PERCPU deprecated_irq_flag(IRQF_PERCPU)
#define SA_TRIGGER_LOW deprecated_irq_flag(IRQF_TRIGGER_LOW)
#define SA_TRIGGER_HIGH deprecated_irq_flag(IRQF_TRIGGER_HIGH)
#define SA_TRIGGER_FALLING deprecated_irq_flag(IRQF_TRIGGER_FALLING)
#define SA_TRIGGER_RISING deprecated_irq_flag(IRQF_TRIGGER_RISING)
#define SA_TRIGGER_MASK deprecated_irq_flag(IRQF_TRIGGER_MASK)

三、使用模板
使用步骤:以外部中断为例
a)定义结构体,相当于定义(void *dev_id)中的(void *)

struct pin_desc{//声明一个引脚描述的结构体pin_desc
unsigned int pin;//引脚值,参考数据手册及板子电路原理图
unsigned int key_val;//值自已随便定义;看自己的项目需要
//...................
};

b)实例化结构体,相当于(void *dev_id)中的 dev_id

struct pin_desc pins_desc[3] = {//实例化结构体,以jz2440按键为列
{S3C2410_GPF0, 0x01},//S3C2410_GPFn在内核中定义好了
{S3C2410_GPF2, 0x02},
{S3C2410_GPG3, 0x03},
};

c)定义中断处理函数

static irqreturn_t irq_handle(int irq, void *dev__id){
struct pin_desc *pindesc = (struct pin_desc *)dev__id;
//................
return IRQ_RETVAL(IRQ_HANDLED);//返回IRQ_HANDLED表示中断已经处理
}

d)申请中断

request_irq(IRQ_EINT0, irq_handle, IRQ_TYPE_EDGE_BOTH, "s2", &pins_desc[0]);//IRQ_EINTn在内核中定义好了
request_irq(IRQ_EINT2, irq_handle, IRQ_TYPE_EDGE_BOTH, "s3", &pins_desc[1]);
request_irq(IRQ_EINT11, irq_handle, IRQ_TYPE_EDGE_BOTH, "s4", &pins_desc[2]);

e)释放内存

free_irq(IRQ_EINT0, &pins_desc[0]);
free_irq(IRQ_EINT2, &pins_desc[1]);
free_irq(IRQ_EINT11, &pins_desc[2]);

Tip:可以直接将IRQ_EINTn也在pins_desc定义,然后

int i = 0;
for(i = 0; i < 3; i++){
free_irq(pins_desc[i].irqnum, &pins_desc[i]);
}

关键字:arm驱动  linux内核  中断编程 引用地址:arm驱动linux内核中断编程

上一篇:纯Linux下的 ARM裸机调试环境搭建(GDB + JLink)
下一篇:arm驱动linux内核时钟

推荐阅读最新更新时间:2024-03-16 14:56

基于嵌入式操作系统的磁场测量系统的设计
引言   随着科技的发展,嵌入式操作系统在越来越多的领域发挥着重要的作用,目前已成为产品技术水平的标志之一。其中Linux因为其拥有开放性、多用户、多任务、良好的用户界面、丰富的网络功能、可靠的系统安全和良好的可移植等特性被广泛的应用到仪器测量设备中。   传统的磁场测量设备(持斯拉计、高斯计)普遍存在精度低(典型测量精度为1.5%)、操作不便等缺点。本文提出一种基于嵌入式Linux的中频磁场测量系统,它不但可以满足当前磁场测量数据采集的需要,还因为其嵌入了操作系统Linux,使具有可靠性好、升级方便的特点,既提高了磁场测量的准确性,又为仪器的功能升级带来便利。可应用于实验室仪器,医疗仪器,姿态控制,安全检测等需磁场检测的领域。
[单片机]
基于嵌入式操作系统的磁场测量系统的设计
基于ARM芯片S3C2410的TFT-LCD驱动方法
    S3C2410是三星公司生产的基于ARM920T内核的RISC微处理器,主频率可达203MHz,适用于信息家电、Smart Phone、Tablet、手持设备、移动终端等领域。其中,集成的LCD控制器具有通用性,可与大多数的LCD显示模块接口。     PD064VT5是一种用非晶硅TFT作为开关器件的有源矩阵液晶显示器,该模块包括TFT-LCD显示屏、驱动电路和背光源,其接口为TTL电平。分辨率为640 x480像素,可通过18bit数据信号显示262 144种色彩。     1 S3C2410的LCD控制器     S3C2410中的LCD控制器可用于传输视频数据并产生必要的控制信号(像VFRAME、VLI
[嵌入式]
ARM的嵌入式Linux移植体验之设备驱动
  设备驱动程序是操作系统内核和机器硬件之间的接口,它为应用程序屏蔽硬件的细节,一般来说,Linux的设备驱动程序需要完成如下功能:   ·设备初始化、释放;   ·提供各类设备服务;   ·负责内核和设备之间的数据交换;   ·检测和处理设备工作过程中出现的错误。   Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合,通过这些函数使得Windows的设备操作犹如文件一般。在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作,如open ()、close ()、read ()、write () 等。   Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发
[单片机]
linux内核对S3C2410睡眠模式的支持
  一、S3C2410支持4种供电模式   (1)NORMAL MODE   耗电最大、可以通过关闭具体控制器的时钟来节电   (2)SLOW MODE   在此模式下可以没有内部PLL,耗电情况依赖于外部时钟的频率   (3)IDLE MODE   FCLK被关断,主要由于CPU core节电。可以任何通过外部中断唤醒   (4)Power_OFF MODE   除了处理器唤醒逻辑单元外,处理器不损耗任何电量。可以通过EINT 或 RTC alarm interrupt唤醒系统   二、S3C2410各种节电模式的进入   (1)慢速模式(SLOW)   CLKSLOW的SLOW_BI
[单片机]
stm32f429的u-boot、uclinux内核烧写说明
最近比较忙,针对前面的留言说有怎么download u-boot、uclinux到stm32,我翻了翻以前记录下的笔记,特意贴上来,其实有些步骤我都已经忘记了。。。 一、搭建嵌入式linux开发环境 1. 准备一台Linux系统(Fedora,CentOS,Ubuntu等)的电脑,将BSP压缩包(linux-cortexm-2.0.0.tar.gz)拷贝到一个目录; 2. 解压BSP包: tar -xzvf linux-cortexm-2.0.0.tar.gz 3. 解压arm工具链: cd linux-cortexm-2.0.0/tools tar xvfj arm-2010q1-189-arm-uc
[单片机]
stm32f429的u-boot、uc<font color='red'>linux内核</font>烧写说明
ARMv8 Linux内核head.S源码分析
ARMv8Linux内核head.S主要工作内容: 1、 从el2特权级退回到el1 2、 确认处理器类型 3、 计算内核镜像的起始物理地址及物理地址与虚拟地址之间的偏移 4、 验证设备树的地址是否有效 5、 创建页表,用于启动内核 6、 设置CPU(cpu_setup),用于使能MMU 7、 使能MMU 8、 交换数据段 9、 跳转到start_kernel函数继续运行。 /* *Low-level CPU initialisation *Based on arch/arm/kernel/head.S * *Copyright (C) 1994-2002 Russell K
[单片机]
基于ARM LPC2210的以太网RTL8019AS驱动系统设计
Author :tiger-john WebSite :blog.csdn.net/tigerjb Email : jibo.tiger@gmail.com 开发环境 硬件环境:LPC2200 操作系统:UC/OS-II操作系统 编译环境:ADS1.2 Update-Time : 2011年2月28日星期四 Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体, 但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人 联系或留言给我。3Q --------------------------
[单片机]
基于<font color='red'>ARM</font> LPC2210的以太网RTL8019AS<font color='red'>驱动</font>系统设计
PIC16F87x的数据存储器规划和中断编程
  PIC系列单片机硬件系统设计简洁,指令系统设计精练;采用哈佛总线结构,芯片内部数据总线和指令总线分离;选址方式简单。   PIC16F87x系列单片机是PIC16系列子系列,是中间档次产品。PIC系列与其他单片机相比,让人印象最深的特点可能要属其内存的分页结构,有很多习惯了其他单片机编程的人认为PIC单片机的内存分页带来很多不便。本文介绍在PIC1687x系列单片机中,根据数据变量的访问特性安排其在数据存储器中的位置的方法及其中断编程,从一方面说明内存的规划对编程的影响。 1 PIC16F87x单片机存储器特点   PIC16F87x单片机采用哈佛总线结构,程序存储器和数据存储器分别有自己的总线。数据存储器被分成4个页(B
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved