linux 内核定时器使用模板

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>

#define SECOND_MAJOR 130// 预设的 主设备号

static int second_major = SECOND_MAJOR;

//second设备结构体
struct second_dev{
    struct cdev cdev; //cdev 结构体
    atomic_t counter; //一共经历了多少秒  原子
    struct timer_list s_timer; //设备要使用的定时器
};

struct second_dev *second_devp;

//timer 处理函数
static void second_timer_handle(unsigned long arg)
{
    mod_timer(&second_devp->s_timer,jiffies+HZ);//修改timer到期时间 jiffies+delay Hz是延尺1秒
    atomic_inc(&second_devp->counter);//原子量自加
    printk(KERN_NOTICE "current jiffies is %d\n",jiffies);
}

//文件打开
int second_open(struct inode *inode, struct file *filp)
{
    //初始化定时器
    init_timer(&second_devp->s_timer);
    second_devp->s_timer.function = &second_timer_handle;
    second_devp->s_timer.expires  = jiffies + HZ;

    add_timer(&second_devp->s_timer);//添加注册timer
    atomic_set(&second_devp->counter, 0); // 计数清0

    return 0;
}

//文件释放
int second_release(struct inode *inode, struct file *filp)
{
    del_timer(&second_devp->s_timer);//册除timer

    return 0;
}

//读
static ssize_t second_read(struct file *filp, char __user *buf, size_t count,loff_t *ppos)
{
    int counter;

    counter = atomic_read(&second_devp->counter);
    if(put_user(counter, (int*)buf))
        return -EFAULT;
    else
        return sizeof(unsigned int);
}

//文件结构
static const struct file_operations second_fops = {
        .owner   = THIS_MODULE,
        .open    = second_open,
        .release = second_release,
        .read    = second_read,
};

//初始化并注册cdev
int second_init()
{
        int result , err;
        dev_t devno = MKDEV(second_major, 0);

        //申请设备号
        if(second_major)
            result = register_chrdev_region(devno, 1, "second");
        else{ // 动态分配
            result = alloc_chrdev_region(&devno, 0, 1, "second");
            second_major = MAJOR(devno);
        }
        if(result <0)
            return result;

        //动态申请设备结构体的内体
        second_devp = kmalloc(sizeof(struct second_dev), GFP_KERNEL);
        if(!second_devp){//申请失败
            result = -ENOMEM;
            goto fail_malloc;
        }

        memset(second_devp, 0, sizeof(struct second_dev));

        cdev_init(&second_devp->cdev, &second_fops);
        second_devp->cdev.owner = THIS_MODULE;
        err = cdev_add(&second_devp->cdev, (int)MKDEV(second_major, 0), 1);
        printk(KERN_NOTICE "second_major %d adding",second_major);
        if(err)
            printk(KERN_NOTICE "error %d adding",err);

        return 0;

fail_malloc:
        unregister_chrdev_region(devno, 1);
        return result;
}

//exit
void second_exit()
{
    cdev_del(&second_devp->cdev);
    kfree(second_devp);
    unregister_chrdev_region(MKDEV(second_major, 0), 1);
}

MODULE_AUTHOR("lunge");
MODULE_LICENSE("Dual BSD/GPL");

module_param(second_major, int, S_IRUGO);//模块参数   insmod xxx.ko second_major= 1000
module_init(second_init);
module_exit(second_exit);



///app
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

main()
{
    int fd;
    int counter     = 0;
    int old_counter = 0;

    //open
    fd = open("/dev/second",O_RDONLY);
    if(fd!= -1){
        while(1){
            read(fd, &counter, sizeof(unsigned int)); //读目前经历的秒数
            if(counter!=old_counter){
                printf("second after open /dev/second:%d \n",counter);
                old_counter = counter;
            }
        }
    }else{
        printf("device open failure\n");
    }
}


from: 设备驱动开发详解2,宋宝华





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值