linux驱动之内核定时器驱动设计
mod_timer(&second_devp->
atomic_inc(&second_devp->
init_timer(&second_devp->
second_devp->
second_devp->
add_timer(&second_devp->
atomic_set(&second_devp->
就关闭设备,直接删除定时器*/
del_timer(&second_devp->s_timer);
return 0;
}
/*read函数的实现*/
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);
/*
采用put_user实现数值的传送
put_user函数存在对指针变量的检查,
因此不需要检测指针是否正确
*/
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,
};
/*初始化函数*/
static int __init second_init(void)
{
int ret;
/*设备号的申请,创建*/
dev_t devno = MKDEV(second_major,0);
/*静态申请设备号*/
if(second_major)
{
ret = register_chrdev_region(devno,1,"second");
}
/*动态申请设备号*/
else
{
ret = alloc_chrdev_region(&devno,0,1,"second");
second_major = MAJOR(devno);
}
if(ret < 0)
{
return ret;
}
/*分配设备结构体的地址空间*/
second_devp = kmalloc(sizeof(struct second_dev),GFP_KERNEL);
/*检查是否分配正确*/
if(!second_devp)
{
ret = -ENOMEM;
goto fail_malloc;
}
/*清零分配的空间*/
memset(second_devp,0,sizeof(struct second_dev));
/*创建设备类,用于自动创建设备文件*/
second_devp->myclass = class_create(THIS_MODULE,"second_timer_class");
/*字符设备初始化,绑定相关操作到设备*/
cdev_init(&second_devp->cdev,&second_fops);
/*设备的拥有者*/
second_devp->cdev.owner = THIS_MODULE,
/*添加设备到内核*/
ret = cdev_add(&second_devp->cdev,devno,1);
/*错误处理*/
if(ret)
{
printk(KERN_NOTICE "ERROR %d",ret);
goto fail_malloc;
}
/*依据以前创建的设备类,创建设备*/
device_create(second_devp->myclass,NULL,devno,NULL,"second%d",0);
return 0;
/*错误操作*/
fail_malloc:
unregister_chrdev_region(devno,1);
return ret;
}
/*退出函数*/
static void __exit second_exit(void)
{
/*释放设备*/
device_destroy(second_devp->myclass,MKDEV(second_major,0));
/*删除字符设备*/
cdev_del(&second_devp->cdev);
/*释放设备类*/
class_destroy(second_devp->myclass);
/*释放分配的内存空间大小*/
kfree(second_devp);
/*释放设备号*/
unregister_chrdev_region(MKDEV(second_major,0),1);
}
/*卸载和加载*/
module_init(second_init);
module_exit(second_exit);
/*LICENSE和作者信息*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("GP- 应用程序: #include #include #include #include #include #include #include int main() { int fd; int counter = 0; int old_counter = 0; fd = open("/dev/second0",O_RDONLY); if(fd != -1) { while(1) { read(fd,&counter,sizeof(unsigned int)); if(counter != old_counter) { printf("second after open /dev/second0 : %d",counter); old_counter = counter; } } } else { printf("Device open failure"); exit(1); } exit(0); } 实验效果: [root@EmbedSky Test]# ./app-timer Current jiffies is 2137721 second after open /dev/second0 : 1 Current jiffies is 2137921 second after open /dev/second0 : 2 Current jiffies is 2138121 second after open /dev/second0 : 3 Current jiffies is 2138321 second after open /dev/second0 : 4 Current ji
linux驱动内核定时器驱 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
