linux下at91rm9200 RTC实时时钟驱动程序部分等待..


所属类别:Linux

文章作者:chenzhufly

特别推荐:免费发布信息 承包关键词~~抢爆了!HOT!


linux下at91rm9200 RTC实时时钟驱动程序部分等待对列wait_queue简单理解文章来源:http://gliethttp.cublog.cn1.wait_queue_head_t类型wait_queue_t类型DECLARE_WAIT_QUEUE_HEAD(at91_rtc_wait)宏DECLARE_WAITQUEUE(wait, current)宏均在include/linux/wait.h中有定义2.static DECLARE_WAIT_QUEUE_HEAD(at91_rtc_wait);定义队列头at91_rtc_wait,以后等待相应事件发生的应用程序将创建一个包含应用程序自身足够信息的wait队列,然后将那个wait队列作为at91_rtc_wait双向链表的第一个链表元素插入,队列头at91_rtc_wait原来的第一个双向链表元素将被链接成双向链表的第2个元素3.at91_rtc_read读取函数的理解gliethttp 2007-06-14驱动学习ssize_t at91_rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos){DECLARE_WAITQUEUE(wait, current); //对于多个应用程序分别同时调用at91_rtc_read,那么每个应用程序都对应一个局部unsigned long data; //变量wait,DECLARE_WAITQUEUE宏将每个应用程序对应的cpu上下文current存放到ssize_t retval; //相应应用程序占有的局部变量wait中if (count < sizeof(unsigned long))return -EINVAL;add_wait_queue(&at91_rtc_wait, &wait);//将当前应用程序局部变量wait插入到at91_rtc_wait队列头,作为第一个链表元素set_current_state(TASK_INTERRUPTIBLE);//设置当前进程为可中断,那么任何对该应用程序的信号操作,都会唤醒该应用程序for (;;) {//使得应用程序能够从schedule();函数返回,继续执行for(;;)循环体spin_lock_irq(&at91_rtc_lock);data = rtc_irq_data;if (data != 0) {rtc_irq_data = 0;break;}spin_unlock_irq(&at91_rtc_lock);if (file->f_flags & O_NONBLOCK) {retval = -EAGAIN;goto out;}if (signal_pending(current)) {retval = -ERESTARTSYS;goto out;}schedule();}spin_unlock_irq(&at91_rtc_lock);data -= 0x100;retval = put_user(data, (unsigned long *) buf);if (!retval)retval = sizeof(unsigned long);out:set_current_state(TASK_RUNNING);remove_wait_queue(&at91_rtc_wait, &wait);remove_wait_queue(&at91_rtc_update, &wait);return retval;}举一个例子来说:如果有5个应用程序p1,p2,p3,p4,p5都试图调用了at91_rtc_read读取数据,那么将会有5个wait局部变量w1,w2,w3,w4,w5被创建,每个局部变量都存储着相应应用程序的足够调度信息,假设5个应用程序的创建的顺序是p1->p2->p3->p4->p5,那么at91_rtc_wait队列头中的5个待唤醒的进程wait的链接顺序为at91_rtc_wait->w5->w4->w3->w2->w1。3.at91_rtc_interrupt中断函数的配对理解gliethttp 2007-06-14驱动学习static void at91_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs){unsigned int rtsr = AT91_SYS->RTC_SR & AT91_SYS->RTC_IMR;if (rtsr) {if (rtsr & AT91C_RTC_ALARM)rtc_irq_data = (AT91_RTC_AF AT91_RTC_IRQF);if (rtsr & AT91C_RTC_SECEV)rtc_irq_data = (AT91_RTC_UF AT91_RTC_IRQF);if (rtsr & AT91C_RTC_ACKUPD)wake_up_interruptible(&at91_rtc_update);rtc_irq_data += 0x100;AT91_SYS->RTC_SCCR = rtsr;//gliethttp 2007-06-14wake_up_interruptible(&at91_rtc_wait);//将唤醒at91_rtc_wait队列头中包含了5个进程调度信息的5个wait对应的应用程序kill_fasync(&at91_rtc_async_queue, SIGIO, POLL_IN);}}小结:多个wait_queue的链接是通过双向链表完成的,wait_queue结构中含有struct list_head task_list;双向链表结构域,所以所有多个wait_queue之间的关联操作都是通过list_add(),list_del(),list_entry()等链表函数简单的完成。

相关信息

· 用C

· 实用技巧:Linux操作系统定时关机或重启

· 在ASP.NET中如何用C

· 微软Teched2008:下一代IT创新源动力








....

77366 73898