Chinaunix首页 | 论坛 | 博客
  • 博客访问: 63308
  • 博文数量: 21
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-08 10:48
个人简介

完美之道,不在无可增加,而在无可删减。

文章分类
文章存档

2014年(2)

2008年(19)

我的朋友

分类: LINUX

2008-05-15 14:01:33

/*
*kernel module
*char device
*mytimer.c
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define DEVICE_NAME "chardev"

static ssize_t chardev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);

static struct file_operations chardev_fops = {
            .read = chardev_read,
};

static struct cdev *cdevp = NULL;
static dev_t devno;
static wait_queue_head_t queue;
static int flag = 0;
static struct timer_list timer;

static void timer_callback(unsigned long arg)
{
    printk("<4>callback...%ld %ld\n",timer.expires,jiffies);
    flag = 1;
    struct task_struct *p=(struct task_struct *)arg;
    wake_up_interruptible(&queue);
    //wake_up_process(p);
}

static ssize_t chardev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    char sendbuf[] = "hello world";
    init_timer(&timer);
    timer.expires = jiffies + HZ * 20;
    timer.data =(unsigned long)current;
    timer.function = timer_callback;
    add_timer(&timer);
    printk("<4> HZ...%d\n",HZ);
    printk("<4> befoer schedule...%ld %ld\n",timer.expires,jiffies);
    wait_event_interruptible(queue, flag != 0);
    //schedule();
    printk("<4>time out...%ld %ld\n",timer.expires,jiffies);
    flag = 0;
    del_timer(&timer);
    copy_to_user(buf, sendbuf, strlen(sendbuf));
    return strlen(res);
}

static int __init chardev_init(void)
{
    int ret;
    ret = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);
    if (ret < 0)
        goto out;
    cdevp = cdev_alloc();
    if (!cdevp)
        goto alloc_err;
    init_waitqueue_head(&queue);
    cdev_init(cdevp, &chardev_fops);
    ret = cdev_add(cdevp, devno, 1);
    if (!ret)
        goto out;
    cdev_del(cdevp);
    alloc_err:
        unregister_chrdev_region(devno, 1);
    out:
        return ret;
}

static void __exit chardev_exit(void)
{
    cdev_del(cdevp);
    unregister_chrdev_region(devno, 1);

    return;
}

MODULE_LICENSE("GPL");

module_init(chardev_init);
module_exit(chardev_exit);

/*
*user program
*test.c
*/
#include
#include
#include
#include
#include


int main()
{
    int fd=0;
    int rf=0;
    char buf[15];

    fd=open("/dev/chardev",O_RDWR);
    if ( fd == -1 )
        {
          printf("Cann't open file \n");
          exit(0);
        }
    memset(buf, 0, sizeof(buf));
    rf=read(fd,buf,12);
    if(rf<0)
         perror("read error\n");
         printf("R:%d :%s\n",rf,buf);
         close(fd);
    return 0;


}

cat /proc/devices 查看加载后的字符设备号

mknod /dev/chardev c * 0 //主设备号和此设备号

使用用户态程序测试
阅读(1395) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~