 |
s3c2410触摸屏在linux下的驱动分析二 |
|
 |
|
s3c2410触摸屏在linux下的驱动分析二 |
|
副标题:s3c2410触摸屏在linux下的驱动分析二 |
| 日期:2008-3-20 22:39:11 来源:雪竹的BLOG 编辑:51Touch |
|
在/kernel/include/linux/sched.h 文件中: #define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE, 1) 该宏函数定义为__wake_up 函数,参数TASK_INTERRUPTIBLE 为1,表示要唤醒的任务的状态为中断模式,参数1 表示要唤醒的互斥进程数目为1。 对应的唤醒操作包括wake_up_interruptible和wake_up。wake_up函数不仅可以唤醒状态为TASK_UNINTERRUPTIBLE的进程,而且可以唤醒状态为TASK_INTERRUPTIBLE的进程。wake_up_interruptible只负责唤醒状态为TASK_INTERRUPTIBLE的进程。关于interruptible_sleep_on 和wake_up_interruptible 函数详细的用法可以参考一篇《关于linux内核中等待队列的问题》文档。 在/kernel/kernel/sched.c 文件中: void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr) { if (q) { unsigned long flags; wq_read_lock_irqsave(&q->lock, flags); __wake_up_common(q, mode, nr, 0); wq_read_unlock_irqrestore(&q->lock, flags); } } 宏函数wq_read_lock_irqsave 的作用主要就是保存IRQ 和FIQ 的中断使能状态,并禁止IRQ 中断;而宏函数wq_read_unlock_irqrestore 的作用就是恢复IRQ 和FIQ 的中断使能状态。现在可以得知__wake_up 这个函数的作用,它首先保存IRQ 和FIQ 的中断使能状态,并禁止IRQ 中断,接着调用__wake_up_common 函数来唤醒等待q 队列的进程,最后再恢复IRQ 和FIQ 的中断使能状态。
static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, int nr_exclusive, const int sync) 该函数的作用是唤醒在等待当前等待队列的进程。参数q 表示要操作的等待队列,mode 表示要唤醒任务的状态,如TASK_UNINTERRUPTIBLE 或TASK_INTERRUPTIBLE 等。nr_exclusive 是要唤醒的互斥进程数目,在这之前遇到的非互斥进程将被无条件唤醒。sync表示???
在/kernel/include/linux/wait.h 文件中: struct __wait_queue_head { wq_lock_t lock; struct list_head task_list; #if WAITQUEUE_DEBUG long __magic; long __creator; #endif }; typedef struct __wait_queue_head wait_queue_head_t; 这是等待队列数据结构。 # define wq_read_lock_irqsave spin_lock_irqsave # define wq_read_unlock_irqrestore spin_unlock_irqrestore 看到这里可以知道其实宏函数wq_read_lock_irqsave 和wq_read_unlock_irqrestore 等价于宏函数spin_lock_irqsave 和spin_unlock_irqrestore,并直接将自己的参数传了下去。
在/kernel/include/linux/spinlock.h 文件中:
#define spin_lock_irqsave(lock, flags) do {local_irq_save(flags);spin_lock(lock);}while (0) #define spin_unlock_irqrestore(lock, flags) do {spin_unlock(lock); local_irq_restore(flags); } while (0) 在这两个宏函数中,前面已经提到spin_lock 和spin_unlock 其实都为空函数,那么实际只执行了local_irq_save 和local_irq_restore 这两个宏函数。
在/kernel/include/asm-arm/system.h 文件中:
#define local_irq_save(x) __save_flags_cli(x) #define local_irq_restore(x) __restore_flags(x) 这里local_irq_save 和local_irq_restore 这两个宏函数又分别等价于__save_flags_cli 和__restore_flags 这两个宏函数。
在/kernel/include/asm-arm/proc-armo/system.h 文件中:
#define __save_flags_cli(x) \ do { \ unsigned long temp; \ __asm__ __volatile__( \ " mov %0, pc @ save_flags_cli\n" \ " orr %1, %0, #0x08000000\n" \ " and %0, %0, #0x0c000000\n" \ " teqp %1, #0\n" \ : "=r" (x), "=r" (temp) \ : \ : "memory"); \ } while (0)
#define __restore_flags(x) \ do { \ unsigned long temp; \ __asm__ __volatile__( \ " mov %0, pc @ restore_flags\n" \ " bic %0, %0, #0x0c000000\n" \ " orr %0, %0, %1\n" \ " teqp %0, #0\n" \ : "=&r" (temp) \ : "r" (x) \ : "memory"); \ } while (0) 最后用ARM 汇编指令实现了对当前程序状态寄存器CPSR 中的IRQ 和FIQ 中断使能状态的保存和恢复。而且在__save_flags_cli 宏函数中,除了对IRQ 和FIQ 中断使能状态的保存外,还禁止了IRQ 中断。
wake_up_interruptible(&(tsdev.wq)); 在这个tsEvent_raw 函数最后,调用wake_up_interruptible 函数来以中断模式唤醒等待tsdev.wq 队列的进程。 |
|
|
| 对这篇文章您有更多的想法?
请去论坛发表意见吧
|
 |
“s3c2410触摸屏在linux下的驱动分析二” 的相关新闻 |
 |
|
|
|
|
|
 |
站内搜索 |
 |
|