驱动模块
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NAME "sync_test"
static int chardev_var = 0;
static int chardev_count = 0;
static struct semaphore sem;
static spinlock_t spin;
static struct cdev boardid_cdev;
static struct class *boardid_class;
static struct device *boardid_device;
static int device_major = 0;
static ssize_t boardid_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
{
ssize_t ret;
if(down_interruptible(&sem)){
return -ERESTARTSYS;
}
ret = copy_to_user(buf, &chardev_var, len);
if(ret)
{
up(&sem);
printk("read error\n");
return -EFAULT;
}
up(&sem);
return sizeof(int);
}
static ssize_t boardid_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos)
{
ssize_t ret;
if(down_interruptible(&sem)){
return -ERESTARTSYS;
}
ret = copy_from_user(&chardev_var, buf, len);
if(ret)
{
up(&sem);
printk("read error\n");
return -EFAULT;
}
up(&sem);
return sizeof(int);
}
static int boardid_open(struct inode *inode, struct file *file)
{
spin_lock(&spin);
printk("get spinlock\n");
if(chardev_count){
spin_unlock(&spin);
return -EBUSY;
}
chardev_count++;
spin_unlock(&spin);
return 0;
}
static int boardid_release(struct inode *inode, struct file *file)
{
chardev_count--;
return 0;
}
static const struct file_operations boardid_fops = {
.owner = THIS_MODULE,
.open = boardid_open,
.read = boardid_read,
.write = boardid_write,
.release = boardid_release
};
static int __init boardid_init(void)
{
dev_t dev_id;
int retval;
if (device_major) {
dev_id = MKDEV(device_major, 0);
retval = register_chrdev_region(dev_id, 1, NAME);
} else {
retval = alloc_chrdev_region(&dev_id, 0, 1, NAME);
device_major = MAJOR(dev_id);
}
if(retval){
printk("boardid chrdev region failed\n");
retval = -EBUSY;
goto err_chrdev_region;
}
cdev_init(&boardid_cdev, &boardid_fops);
retval = cdev_add(&boardid_cdev, dev_id, 1);
if (retval) {
printk("boardid cdev add failed\n");
retval = -EBUSY;
goto err_cdev_add;
}
boardid_class = class_create(THIS_MODULE, NAME);
if (IS_ERR(boardid_class)) {
printk("%s: class_create failed\n", NAME);
retval = PTR_ERR(boardid_class);
goto err_class_create;
}
boardid_device = device_create(boardid_class, NULL, dev_id, NULL, "%s", NAME);
if (IS_ERR(boardid_device)) {
printk("%s: class_device_create failed\n", NAME);
retval = PTR_ERR(boardid_device);
goto err_device_create;
}
printk("cdev:board_version:%d\n",chardev_var);
init_MUTEX(&sem);
spin_lock_init(&spin);
return 0;
err_device_create:
class_destroy(boardid_class);
err_class_create:
cdev_del(&boardid_cdev);
err_cdev_add:
unregister_chrdev_region(dev_id, 1);
err_chrdev_region:
return retval;
}
static void __exit boardid_exit(void)
{
dev_t dev_id = MKDEV(device_major, 0);
device_destroy(boardid_class, dev_id);
class_destroy(boardid_class);
cdev_del(&boardid_cdev);
unregister_chrdev_region(dev_id, 1);
}
module_init(boardid_init);
module_exit(boardid_exit);
MODULE_DESCRIPTION("board_version Driver");
MODULE_LICENSE("GPL");
应用测试程序:
#include
#include
int main()
{
int fd;
int wrbuf = 72;
int rdbuf;
int ret = 0;
fd = open("/dev/sync_test", O_RDWR);
if (fd < 0){
printf("open /dev/sync_test devices failed!\n");
}else{
printf("sync_test driver open successfully!\n");
}
ret=write(fd, &wrbuf, sizeof(int));
if(ret == sizeof(int)){
printf("write ok!\n");
}else{
printf("write failed!\n");
close(fd);
return 0;
}
lseek(fd, 0, SEEK_SET);
ret = read(fd, &rdbuf, sizeof(int));
if(ret == sizeof(int)){
printf("read ok!\n");
printf("rdbuf:%d\n",rdbuf);
}else{
printf("read failed!\n");
}
close(fd);
}
注:很好的参考资料---》