近期一直在学习等待队列设备之类的问题,今天正好有机会和大家讨论一下.

设备驱动程序:

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/uaccess.h>

#include <linux/timer.h>

#include <linux/sched.h>

#include <linux/wait.h>

MODULE_LICENSE("GPL");

#define BUF_SIZE    256

#define DEVICE      ((const char*)"kgrunt")

struct kgrunt_dev

{

struct cdev cdev;

char *buf;

int len;

int bytes;

struct timer_list timer;

int timer_flag;

wait_queue_head_t queue;

dev_t dev;

};

static struct kgrunt_dev kgrunt;

static void kgrunt_timer_fn(unsigned long d)

{

struct kgrunt_dev *dev = (struct kgrunt_dev *)d;

struct timer_list *timer = &dev->timer;

dev->bytes = snprintf(dev->buf, dev->len,\

"timer experis: %lu,jiffers: %lu, current pid: %d, comm:%s\n",\

timer->expires,jiffies, current->pid, current->comm);

wake_up_interruptible(&dev->queue);//唤醒等待队列

if (dev->timer_flag)

mod_timer(timer, timer->expires + HZ);

}

static int kgrunt_open(struct inode *inode, struct file *file)

{

printk("kgrunt open\n");

struct kgrunt_dev *dev = \

container_of(inode->i_cdev, struct kgrunt_dev, cdev);//由inode对应的字符设备指针得到kgrunt设备的地址

file->private_data = dev;

mod_timer(&dev->timer, jiffies + HZ);//注册定时器

dev->timer_flag = 1;

return 0;

}

static int kgrunt_realse(struct inode *inode, struct file *file)

{

printk("kgrunt release\n");

struct kgrunt_dev * dev = container_of(inode->i_cdev, struct kgrunt_dev, cdev);

dev->timer_flag = 0;

del_timer_sync(&dev->timer);

return 0;

}

static ssize_t kgrunt_read(struct file *file, char __user *buf, size_t count, loff_t *pos)

{

int err;

struct kgrunt_dev *dev = (struct kgrunt_dev *)file->private_data;

printk("read data ,count: %d, pos: %d\n", count, (int)*pos);

if (count < 0)

return -EINVAL;

if (count == 0)

return 0;

if (dev->bytes == 0)

if (file->f_flags & O_NONBLOCK)

return -EAGAIN;

err = wait_event_interruptible(dev->queue, dev->bytes > 0);//等待队列

if (err == ERESTARTSYS)

return -EINTR;

if (count > dev->bytes)

count = dev->bytes;

if (copy_to_user(buf, dev->buf, count) > 0)

{

每日一道理
正所谓“学海无涯”。我们正像一群群鱼儿在茫茫的知识之海中跳跃、 嬉戏,在知识之海中出生、成长、生活。我们离不开这维持生活的“海水”,如果跳出这个“海洋”,到“陆地”上去生活,我们就会被无情的“太阳”晒死。

printk("copy data to user failed\n");

return -EFAULT;

}

dev->bytes = 0;

return count;

}

static ssize_t kgrunt_write(struct file *file, char __user *buf, size_t count, loff_t *pos)

{

/*nothing to do*/

return -EPERM;

}

static loff_t kgrunt_llseek(struct file *file, loff_t offset, int whence)

{

/*nothing to do*/

return -EPERM;

}

static struct file_operations kgrunt_fops =

{

.owner  =   THIS_MODULE,

.open   =   kgrunt_open,

.release=   kgrunt_realse,

.read   =   kgrunt_read,

.write  =   kgrunt_write,

.llseek =   kgrunt_llseek,

};

static __init int kgrunt_init(void)

{

int err;

printk("init kgrunt\n");

if ((err = alloc_chrdev_region(&kgrunt.dev, 0, 1, DEVICE)) < 0)//主动注册设备号

{

printk("alloc_chardev_region ERR\n");

goto cdev_alloc_fail;

}

printk("MAJOR: %d, MINOR: %d\n", MAJOR(kgrunt.dev), MINOR(kgrunt.dev));

if ((kgrunt.buf = kmalloc(BUF_SIZE, GFP_KERNEL)) == NULL)

{

goto kmalloc_fali;

}

printk("kmalloc succfull\n");

kgrunt.len = BUF_SIZE;

kgrunt.bytes = 0;

cdev_init(&kgrunt.cdev, &kgrunt_fops);//初始化设备

kgrunt.cdev.owner = kgrunt_fops.owner;

setup_timer(&kgrunt.timer, kgrunt_timer_fn, (unsigned long)&kgrunt);//初始化、设置定时器

kgrunt.timer_flag = 0;

init_waitqueue_head(&kgrunt.queue);//初始化等待队列

if ((err = cdev_add(&kgrunt.cdev, kgrunt.dev, 1)) < 0)//注册设备

{

printk("cedv_add fail\n");

goto cdev_add_fail;

}

return 0;

cdev_add_fail:

kfree(&kgrunt.buf);

kmalloc_fali:

unregister_chrdev_region(kgrunt.dev, 1);

cdev_alloc_fail:

return err;

}

static __exit void kgrunt_exit(void)

{

printk("kgrunt exit\n");

cdev_del(&kgrunt.cdev);

kfree(kgrunt.buf);

unregister_chrdev_region(kgrunt.dev, 1);

}

module_init(kgrunt_init);

module_exit(kgrunt_exit);

应用程序:

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#define DEVICE (const char*)"/dev/kgrunt"

int main(int argc, char **argv)

{

char buf[256];

int fd, ret;

memset(buf, 0, sizeof(buf));

if ((fd = open(DEVICE, O_RDONLY)) < 0)

{

printf("open device failed\n");

return 0;

}

while(1)

{

memset(buf, 0, sizeof(buf));

if ((ret = read(fd, buf, sizeof(buf))) < 0)

{

sleep(1);

continue;

}

sleep(1);

printf("read data: %s\n", buf);

}

}

文章结束给大家分享下程序员的一些笑话语录: 祝大家在以后的日子里. 男生象Oracle般健壮; 女生象win7般漂亮; 桃花运象IE中毒般频繁; 钱包如Gmail容量般壮大, 升职速度赶上微软打补丁 , 追女朋友像木马一样猖獗, 生活像重装电脑后一样幸福, 写程序敲代码和聊天一样有**。

--------------------------------- 原创文章 By
等待队列和设备
---------------------------------

转载于:https://www.cnblogs.com/jiangu66/archive/2013/05/29/3106838.html

等待队列设备[置顶] Linux设备驱动,等待队列相关推荐

  1. linux 统一设备模型 pci,Linux设备驱动模型摘抄

    Linux设备驱动模型摘抄Linux设备驱动模型摘抄Linux设备驱动模型摘抄Linux设备驱动模型摘抄Linux设备驱动模型摘抄 Linux设备驱动模型摘抄(1) Linux统一设备模型 简介 Li ...

  2. linux查找设备所在分片,Linux设备驱动统一模型解析

    soc节点指定了<0x0 0xe0000000 0x00100000>:此属性值指定对于1024KB范围的地址空间,在物理0x0处寻址的子节点映射到物理0xe0000000的父地址.通过这 ...

  3. Linux设备驱动程序学习-Linux设备模型(总线、设备、驱动程序和类)

    文章的例子和实验使用<LDD3>所配的lddbus模块(稍作修改). 总线 总线是处理器和一个或多个设备之间的通道,在设备模型中, 所有的设备都通过总线相连, 甚至是内部的虚拟" ...

  4. Linux设备树led,linux设备树下LED灯控制

    linux设备树下LED灯控制 linux设备树下LED灯控制 原理图: 所以在设备树下子节点下插入gpioled节点: gpioled { #address-cells = <1>; # ...

  5. 《linux设备驱动程序》——Linux设备模型

    一.概论 1.2.6版内核对系统结构的一般性抽象描述.现在内核使用了该抽象支持了多种不同的任务,其中包括: 1).电源管理和系统关机. 2).与用户控件通信. 3).热插拔设备. 4).设备类型. 5 ...

  6. linux 统一设备模型 pci,linux设备模型____宏观印象

    linux设备模型____宏观印象 最近一个机会需要研究一个marvell芯片的设备的驱动,涉及驱动和一些用户态相关部分,正好学习一下驱动和sysfs,本文先是原理,后面的文章是详细描述.本文依托的是 ...

  7. linux如何切换到设备,如何编写Linux设备驱动程序(转)

    序言 Linux是Unix操作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环 境下的驱动程序有很大的区别.在Linux环境下设计驱动程序 ...

  8. qt窗口置顶linux环境下,Qt 实现窗口置顶与取消置顶

    原生的Qt 实现窗口置顶的方法 setWindowFlags(Qt::WindowStaysOnTopHint); 目前还不知道怎么实现取消窗口置顶,还请知道使用的哥们分享. 我通过window AP ...

  9. linux设备分层优点,Linux设备驱动的分层设计思想

    代码清单8第2行获取platform_data,而platform_data实际上是定义GPIO按键硬件信息的数组,第31行的for循环工具这些信息申请GPIO并初始化中断,对于LDD6140电路板而 ...

最新文章

  1. 中科院基因组所高远组诚聘生物信息学方向助理/副研及博士
  2. 关于数据存储的经典题
  3. java继承中构造方法_java之继承中构造方法总结(文字版)
  4. Android开发工具之Android Studio----Gradle
  5. Python中__new__和__init__区别
  6. Java 中的位移运算符
  7. Design Compiler指南——后综合过程
  8. JavaScript -- arguments、apply 、call、bind
  9. AndroidStudio_安卓原生开发_保存全局数据---Android原生开发工作笔记141
  10. php fopen 清空文件内容,如何在c语言中清空文件里的内容?
  11. UVA490 Rotating Sentences【输入输出+水题】
  12. android sensor架构_转 Camx 架构知识点
  13. java权限管理与用户角色权限设计
  14. 数据库实验第七周【集合查询数据更新】
  15. 【Week7 作业B】TT的旅行日记
  16. 图书馆抢座系统(python) 附源码
  17. 罗格斯大学电气与计算机工程专业怎么样,罗格斯大学电气与计算机工程硕士专业...
  18. [Swift]语言介绍
  19. 【U8】13.0 固定资产折旧清单与折旧分配表不一致的问题
  20. tensorflow之四运转方式入门

热门文章

  1. VMware虚拟机中ubuntu的磁盘怎么扩容
  2. ROS学习笔记12(用Python写一个简单的消息发布和消息订阅)
  3. mt4 不显示服务器速度,mt4上面怎么显示时间?
  4. java输入框1-100_Java开发笔记(一百三十九)JavaFX的输入框
  5. iphone分辨率_AppStore今日推荐 iphone放大分辨率减少白噪点的照片处理工具
  6. FLOPs FLOPS
  7. 9.6.1 三维数据可视化之散点图
  8. Yearn已部署新YFI策略Brownie Mix
  9. Tokenview:交易所比特币净流出量大幅增加
  10. 策略的静态与动态报表——绝对值得收藏的策略资料(文尾视频)