分类: LINUX
2013-01-18 19:33:07
原文地址:linux内核驱动知识二,中断及时间和并发处理 作者:HYYLINUX
申请和释放中断接口
int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id);
void free_irq(unsigned int irq, void *dev_id);
申请中断接口参数
unsigned int irq 请求的中断号
irqreturn_t (*handler) 安装的处理函数指针.
unsigned long flags 一个与中断管理相关的选项的位掩码
const char *dev_name 这个传递给 request_irq 的字串用在 /proc/interrupts 来显示中断的拥有者
void *dev_id 用作共享中断线的指针. 它是一个独特的标识, 用在当释放中断线时以及可能还被驱动用来指向它自己的私有数据区,如果中断没有被共享, dev_id 可以设置为 NULL
时间
系统心跳
unsigned long 类型的Jiffies 和 jiffies_64 只读
#include
32-位 平台上当 HZ 是 1000 时, 计数器只是每 50 天溢出一次, 必要时你的代码应当准备处理这个事件
驱动常用延时函数
当一个设备驱动需要处理它的硬件的反应时间, 涉及到的延时常常是最多几个毫秒
相关函数:
#include
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
驱动常用延时函数
休眠
相关函数:
#include
void msleep(unsigned long msecs);
void ssleep(unsigned long msecs);
定时器
timer.h
初始化定时器init_timer
注意全局结构中三个成员要初始化,分别是:
expires
function
data
定时器开始add_timer
删除定时器del_timer
并发
信号量
信号量semaphore.h
互斥信号量void init_MUTEX(struct semaphore* sem)
#define init_MUTEX(sem) sema_init(sem, 1)
down up信号量分别代码锁定和解锁
衍生接口
int down_interruptible (sem);
可中断的,如果返回非零值,说明获取锁资源的过程中被中断了。
int down_trylock(sem);
不等待锁资源,发现没有资源就返回非零值
读取者/写入者信号量
初始化
void init_rwsem(struct rw_semaphore* sem)
锁定
down_read down_read_trylock
down_write down_write_trylock
downgrade_write
解锁
up_read up_write
自旋锁
自旋锁spinlock.h
初始化spin_lock_init(spinlock_t* lock)
锁定spin_lock
解锁spin_unlock
自旋的危害:spin_lock之后进入自旋状态,不可中断,一直自旋,极易导致死锁。
自旋锁提供大量合理的衍生函数
spin_lock_irqsave
spin_unlock_irqrestore
spin_lock_irq
spin_unlock_irq
spin_trylock
原子变量
原子变量atomic.h
保护的对象是一个简单的变量
初始化:atomic_t v = ATOMIC_INIT(0)
锁定:atomic_add
解锁:atomic_sub
原子变量位操作bitops.h
test_and_set_bit
test_and_clear_bit假定某位为锁,0为空闲,1为busy。
优点:简单,实用,无副作用,无需初始化。