在驱动中定义中断
来源:互联网 发布:mp3编辑软件 编辑:程序博客网 时间:2024/04/30 09:11
1. 中断
涉及头文件:
#include <linux/interrupts>
中断的注册
int
request_irq(
unsigned int irq,
irq_handler_t handler,
unsigned long flags,
const char *name,
void *dev
);
@irq: 中断号
外部中断号:
a. irqnum gpio_to_irq(gpio);
EXYNOS4X12_GPM4();
//arm/mach-exynos/include/mach/gpio.h
b. IRQ_EINT(eintnum);
//arm/plat-samsung/include/plat/irqs.h
内部中断:
arch/arm/mach-exynos/include/mach/irqs.h
@handler: 中断处理函数
typedef irqreturn_t (*irq_handler_t)(int, void *);
中断处理函数的返回值:IRQ_HANDLED, IRQ_NONE;
型参:第一个int对应的是发生中断的中断号。
第二个void*型的实参是注册中断时的第5个参数dev。
@flags: 注册中断的标记
#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 | \
#define IRQF_SHARED 0x00000080
@name: 中断的名字
@dev: 传给中断处理函数的第二参数的实参
中断的共享
2. 中断的下半部
-------------------------------------------------------------------
实现中断的下半部机制1: tasklet 机制
涉及到的核心结构体:
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func)(unsigned long); //下半部的任务函数
unsigned long data; //下半部的任务函数需要的参数
};
使用步骤:
首先,实例化一个struct tasklet_struct的对象,代表下半部将被内核调度器调度的任务。
a. struct tasklet_struct task;
tasklet_init(&task, service_bh, dev);
b. DECLARE_TASKLET(task, service_bh, dev); //task是给tasklet起的名字,service_bh是执行tasklet时调用的函数,dev是一个用来传递给tasklet函数的ul类型的值
其次,在中断处理函数(上半部)中将下半部的任务交给调度器调度
tasklet_schedule(&task);
最后,如果写的是驱动模块,需要在模块的出口移除下半部的任务
tasklet_kill(&task);
-------------------------------------------------------------------
中断下半部的实现机制2: 工作队列机制
涉及到的核心结构体:
struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func; //下半部的任务函数
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
//下半部任务函数的类型:
typedef void (*work_func_t)(struct work_struct *work);
实现步骤:
首先,实例化对象
方法1,
struct work_struct work;
INIT_WORK(&work, service_bh);
方法2,
DECLARE_WORK(work, service_bh); \
其次,在中断的上半部将下半部的任务交给调度器调度
schedule_work(&work);
最后,驱动模块的出口需要等待下半部的任务完成
flush_work(&work);
涉及头文件:
#include <linux/interrupts>
中断的注册
int
request_irq(
unsigned int irq,
irq_handler_t handler,
unsigned long flags,
const char *name,
void *dev
);
@irq: 中断号
外部中断号:
a. irqnum gpio_to_irq(gpio);
EXYNOS4X12_GPM4();
//arm/mach-exynos/include/mach/gpio.h
b. IRQ_EINT(eintnum);
//arm/plat-samsung/include/plat/irqs.h
内部中断:
arch/arm/mach-exynos/include/mach/irqs.h
@handler: 中断处理函数
typedef irqreturn_t (*irq_handler_t)(int, void *);
中断处理函数的返回值:IRQ_HANDLED, IRQ_NONE;
型参:第一个int对应的是发生中断的中断号。
第二个void*型的实参是注册中断时的第5个参数dev。
@flags: 注册中断的标记
#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 | \
#define IRQF_SHARED 0x00000080
@name: 中断的名字
@dev: 传给中断处理函数的第二参数的实参
中断的共享
2. 中断的下半部
-------------------------------------------------------------------
实现中断的下半部机制1: tasklet 机制
涉及到的核心结构体:
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func)(unsigned long); //下半部的任务函数
unsigned long data; //下半部的任务函数需要的参数
};
使用步骤:
首先,实例化一个struct tasklet_struct的对象,代表下半部将被内核调度器调度的任务。
a. struct tasklet_struct task;
tasklet_init(&task, service_bh, dev);
b. DECLARE_TASKLET(task, service_bh, dev); //task是给tasklet起的名字,service_bh是执行tasklet时调用的函数,dev是一个用来传递给tasklet函数的ul类型的值
其次,在中断处理函数(上半部)中将下半部的任务交给调度器调度
tasklet_schedule(&task);
最后,如果写的是驱动模块,需要在模块的出口移除下半部的任务
tasklet_kill(&task);
-------------------------------------------------------------------
中断下半部的实现机制2: 工作队列机制
涉及到的核心结构体:
struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func; //下半部的任务函数
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
//下半部任务函数的类型:
typedef void (*work_func_t)(struct work_struct *work);
实现步骤:
首先,实例化对象
方法1,
struct work_struct work;
INIT_WORK(&work, service_bh);
方法2,
DECLARE_WORK(work, service_bh); \
其次,在中断的上半部将下半部的任务交给调度器调度
schedule_work(&work);
最后,驱动模块的出口需要等待下半部的任务完成
flush_work(&work);
0 0
- 在驱动中定义中断
- wince中断机制和在驱动中调用中断
- Linux驱动开发⑤--在驱动程序中测试CPU中断
- linux驱动,中断中关闭中断
- linux驱动中中断处理
- 多CPU的机器上在驱动中如何HOOK中断
- 中断定义
- WinCE驱动中设备中断的处理
- 按键驱动中中断的问题
- 中断在SDARM中调试
- 驱动开发中ioctl cmd定义分析
- s5pv210 的中断向量表及中断在Linux下虚拟地址和物理地址的定义
- "阻塞--中断"驱动模型在i2c在子系统、uart驱动、spi子系统中的实现
- "阻塞--中断"驱动模型在i2c在子系统、uart驱动、spi子系统中的实现
- zynq的pl中断在linux下的配置及中断驱动
- WinCE中中断的处理过程(驱动开发人员角度)
- WinCE中中断的处理过程(驱动开发人员角度)
- WinCE中中断的处理过程(驱动开发人员角度)
- 在ubuntu上软件安装的几种格式dev,rpm,bin,tar.gz
- JSP基本指令
- Caused by: java.lang.IllegalArgumentException: Can't use FLAG_RECEIVER_BOOT_UPGRADE here的解决
- 通过金矿模型介绍动态规划
- 时间转换,自适应文字高度,手机和邮箱验证
- 在驱动中定义中断
- Codeforces Round #332 (Div. 2) 599A Patrick and Shopping(模拟)
- Kibana User Guide [4.2] » Visualize » Metric
- MyBatis批量操作报错:Parameter 'xxxList' not found. Available parameters are [list]
- Hive之insert into 和insert overwrite
- CAS单点登录(SSO)完整教程
- JAVA wait(), notify(),sleep详解
- java字符串与16进制2进制互转
- HDU 3460 Ancient Printer(思维题或字典树)