1.中断注册函数
int err = 0;
err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)&button_irqs[i]);
if (err)
{
disable_irq(button_irqs[i].irq);/* 使中断不起作用*/
free_irq(button_irqs[i].irq, (void *)&button_irqs[i]); /* 释放中断资源*/
return -EBUSY ; /*中断注册没成功的最终的返回值*/ //返回错误信息:请求的资源不可用
}
return 0; /* 正常返回*/
&button_irqs[i] 是该中断享有的资源,,buttons_interrupt为中断处理函数
return IRQ_RETVAL(IRQ_HANDLED); 中断处理函数 最后的返回函数
中断和等待队列的详细知识看mini2440的button驱动 等待队列机制, 是中断管理中常用到的机制
2.disable_irq关闭中断并等待中断处理完后返回, 而disable_irq_nosync立即返回.
3.open方法会实际的分配和占用资源
4.close/release方法将释放open方法所占用的资源
5.当进程中有可能发生阻塞的地方,都要有下面的操作 (如读写操作)
if (!ev_press)
{
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
else
wait_event_interruptible(button_waitq, ev_press);
}
都要首先去判断用户的设置,用户设置的是非阻塞还是阻塞。。
当设置为“非阻塞”的时候,遇到等待的条件,直接返回给用户。。
当用户设置了“阻塞”的时候,遇到等待的条件,将进程放在阻塞队列。当等待的条件满足时,进程会继续执行下面的操作。
6.static DECLARE_WAIT_QUEUE_HEAD(button_waitq); button_waitq 为等待队列的名字
创建一个等待队列头并初始化
下面介绍的是等待事件函数,其就是依据condition条件是否满足来选择是否返回或者阻塞等待。 等待condition变为true,否则一直睡眠
wait_event(wq, condition)
wait_event_timeout(wq, condition, timeout)
wait_event_interruptible(wq, condition)
wait_event_interruptible_timeout(wq, condition, timeout)
(1)不可中断的等待
(2)超时返回的等待
(3)可中断的等待
(4)可中断并超时返回的等待
唤醒休眠进程的函数:wake_up
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head *queue);
惯例:用wake_up唤醒wait_event,用wake_up_interruptible唤醒wait_event_interruptible |
7.注意驱动程序中结构体的应用, '.' 和'->'的区别,前者是变量,后者是指针
8.当有等待队列时要用到poll函数 ,而poll函数其实就是 poll_wait函数的应用
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait);
if (ev_press)
mask |= POLLIN | POLLRDNORM;
return mask;
poll 函数的写法 poll_wait函数所做的工作是把当前进程添加到wait参数指定的等待列表
9.static struct semaphore lock; 定义一个信号量
void sema_init(struct semaphore *sem,int val); 信号量的初始化
void init_MUTEX(struct semaphore *sem);互斥信号量的初始化 init_MUTEX(&lock);
或者DECLARE_MUTEX(ADC_LOCK);定义并初始化
信号量不是某个资源的信号量,其就是一个标志位。。就是一个整数,当大于0是表明进程可以去操作临近资源。。其他情况下不可以(已经被其他进程占用)。
步骤:申请信号量-----进入临界区操作-----释放信号量-----其他操作
if (!down_trylock(&lock)) 试着获取信号量,如果能够立即获得,它就获得该信号量并返回0,否则返回非0.并且它不会导致休眠
信号量只能在进程的上下文中使用
10.
驱动程序中printk(KERN_ERR "Failed to remap register block\n"); 用printk来打印
11.s3c2440有27根地址线,32根数据线。。地址线使用来接外设的,接需要寻址的外设(即有存储器的外设,没有存储器的外设不需要接地址线,