内核定时器的使用

来源:互联网 发布:mac怎么删除下载文件 编辑:程序博客网 时间:2024/03/28 18:35

1.内核模块代码

#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <asm/uaccess.h>#include <linux/cdev.h>#include <linux/fs.h>#include <linux/slab.h>#include <linux/types.h>#include <asm/atomic.h>int timer_open(struct inode *, struct file *);int timer_release(struct inode *, struct file *);ssize_t timer_read(struct file *, char __user *, size_t, loff_t *);ssize_t timer_write(struct file *, char __user *, size_t, loff_t *);loff_t timer_llseek(struct file *, loff_t, int);int timer_ioctl(struct file *, unsigned int, unsigned long);#define N 100#define CLEAR_DATA 1struct timer_dev{    struct cdev cdev;    struct timer_list timer;    atomic_t counter;};struct file_operations timer_fops = {    .owner = THIS_MODULE,    .llseek = timer_llseek,    .open = timer_open,    .release = timer_release,    .unlocked_ioctl = timer_ioctl,    .read = timer_read,    .write = timer_write,};dev_t dev_num;struct timer_dev *dev;void timer_func(unsigned long data){    mod_timer(&dev->timer, jiffies + HZ);    atomic_inc(&dev->counter);    return ;}int timer_open(struct inode *inodep, struct file *filp){    init_timer(&dev->timer);    dev->timer.function = timer_func;    dev->timer.expires = jiffies + HZ;    add_timer(&dev->timer);    return 0;}int timer_release(struct inode *inodep, struct file *filp){    del_timer(&dev->timer);    return 0;}ssize_t timer_read(struct file *filp, char __user *buf, size_t len, loff_t *fpos){    int counter;    counter = atomic_read(&dev->counter);    if(put_user(counter, (int *)buf) < 0)    {        return -EFAULT;    }    return sizeof(int);}ssize_t timer_write(struct file *filp, char __user *buf, size_t len, loff_t *fpos){    return 0;}loff_t timer_llseek(struct file *filp, loff_t off, int whence){    return 0;}int timer_ioctl(struct file *filp, unsigned int cmd, unsigned long val){    return 0;}static int __init timer_init(void){    if(alloc_chrdev_region(&dev_num, 0, 1, "timer"))        return -EFAULT;    dev = kzalloc(sizeof(struct timer_dev), GFP_KERNEL);    cdev_init(&dev->cdev, &timer_fops);    dev->cdev.owner = THIS_MODULE;    dev->cdev.ops = &timer_fops;    int err = cdev_add(&dev->cdev, dev_num, 1);    if(err)        goto fail;    printk("timer_init is success\n");    return 0;fail:    kfree(dev);    return err;}static void __exit timer_exit(void){        unregister_chrdev_region(dev_num, 1);    cdev_del(&dev->cdev);    kfree(dev);    printk("timer_exit is success\n");    return ;} MODULE_LICENSE("GPL");module_init(timer_init);module_exit(timer_exit);

2.Makefile文件

TARGET= timerobj-m := ${TARGET}.oCURRENT_PATH := $(shell pwd)LINUX_KERNEL := $(shell uname -r)LINUX_KERNEL_PATH := /usr/src/linux-headers-${LINUX_KERNEL}.PHONY: all.PHONY: clean.PHONY: install.PHONY: removeall:    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modulesclean:    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) cleaninstall:    sudo ./${TARGET}.shremove:    sudo ./clean.sh

3. timer.sh 脚本

#!/bin/shmodule="timer"mode="666"/sbin/insmod ${module}.ko || exit 1rm -f /dev/${module}major=$(awk 'BEGIN{count = 0;} {if($2 == module && count == 0) {print $1; count++;} }' module=$module /proc/devices)mknod /dev/${module} c $major 0chmod $mode /dev/${module}

4. clean.sh脚本

#!/bin/bashmodule="timer"/sbin/rmmod ${module} || exit 1rm -f /dev/${module}

5.应用程序的使用:

#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(int argc, char *argv[]){    int fd;    if((fd = open("/dev/timer", O_RDWR)) < 0)        goto fail;    int counter = 0, old_counter = 0;    while(1)    {        if(read(fd, &counter, sizeof(counter)) < 0)            goto fail;        if(counter != old_counter)            printf("counter = %d\n", counter);        old_counter = counter;    }    return 0;fail:    printf("read_timer error: %s\n", strerror(errno));    exit(1);}

本文引述自 http://edsionte.com/techblog/archives/1738

0 0
原创粉丝点击