宋宝华 《Linux设备驱动开发详解》示例代码之second设备

second.c代码
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>

#define	SECOND_MAJOR	252
static	int	second_major = SECOND_MAJOR;

struct	second_dev
{
	struct	cdev	cdev;
	atomic_t	counter;
	struct	timer_list	s_timer;
};

struct	second_dev	*second_devp;

static	void	second_timer_handle(unsigned long arg)
{
	mod_timer(&second_devp->s_timer, jiffies + HZ);
	atomic_inc(&second_devp->counter);

	printk(KERN_NOTICE "current jiffies is %ld\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);

	atomic_set(&second_devp->counter, 0);
	return 0;
}

int	second_release(struct inode *inode, struct file *filp)
{
	del_timer(&second_devp->s_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);
	return 0;
}
static	const	struct	file_operations second_fops = 
{
	.owner	=	THIS_MODULE,
	.open	=	second_open,
	.release=	second_release,
	.read	=	second_read,
};

static void	second_setup_cdev(struct second_dev *dev,int index )
{
	int err;
	int devno = MKDEV(second_major, index);
	cdev_init(&dev->cdev, &second_fops);
	dev->cdev.owner = THIS_MODULE;
	dev->cdev.ops 	= &second_fops;
	err	=	cdev_add(&dev->cdev, devno, 1);
	if(err)
		printk(KERN_ALERT "Error setup the second device");
}

int	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_setup_cdev(second_devp, 0);

	return 0;
fail_malloc:
	unregister_chrdev_region(devno, 1);
	return ret;
}

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

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

module_init(second_init);
module_exit(second_exit);
makefile
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD	:= $(shell pwd)


obj-m := second.o
default:
	$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules


test: test.c
	gcc $< -o $@.o  -g


clean:
	rm -rf *.o *.ko *~ *.order *.symvers *.markers *.mod.c


测试代码

/*======================================================================
    A test program to access /dev/second
    This example is to help understand kernel timer 
    
    The initial developer of the original code is Baohua Song
    <author@linuxdriver.cn>. All Rights Reserved.
======================================================================*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>

main()
{
  int fd;
  int counter = 0;
  int old_counter = 0;
  
  /*打开/dev/second设备文件*/
  fd = open("/dev/second", O_RDONLY);
  if (fd !=  - 1)
  {
    while (1)
    {
      read(fd,&counter, sizeof(unsigned int));//读目前经历的秒数
      if(counter!=old_counter)
      {	
      	printf("seconds after open /dev/second :%d\n",counter);
      	old_counter = counter;
      }	
    }    
  }
  else
  {
    printf("Device open failure\n");
  }
}

测试脚本

1 load_scull.sh

#!/bin/sh

/sbin/insmod second.ko
mknod /dev/second c 252 0

2 unload_scull.sh

#!/bin/sh

/sbin/rmmod second.ko
rm /dev/second -f

3 test.sh

#!/bin/sh
make clean
make 
make test
sudo ./unload_scull
sudo ./load_scull
sudo ./test.o


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值