#ifndef _DEMO_H_
#define _DEMO_H_
#include /* needed for the _IOW etc stuff used later */
/********************************************************
* Macros to help debugging
********************************************************/
#undef PDEBUG /* undef it, just in case */
#ifdef DEMO_DEBUG
#ifdef __KERNEL__
# define PDEBUG(fmt, args...) printk( KERN_DEBUG "DEMO: " fmt, ## args)
#else//usr space
# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
#endif
#else
# define PDEBUG(fmt, args...) /* not debugging: nothing */
#endif
#undef PDEBUGG
#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */
//设备号
#define DEMO_MAJOR 224
#define DEMO_MINOR 0
#define COMMAND1 1
#define COMMAND2 2
//设备结构
struct DEMO_dev
{
struct cdev cdev; /* Char device structure */
};
//函数申明
ssize_t DEMO_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos);
ssize_t DEMO_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos);
loff_t DEMO_llseek(struct file *filp, loff_t off, int whence);
int DEMO_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
#endif /* _DEMO_H_ */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "demo.h"
MODULE_AUTHOR("wangzhzh");
MODULE_LICENSE("Dual BSD/GPL");
struct DEMO_dev *DEMO_devices;
static unsigned char demo_inc=0;
static u8 demoBuffer[256];
int DEMO_open(struct inode *inode, struct file *filp)
{
struct DEMO_dev *dev;
if(demo_inc>0)return -ERESTARTSYS;
demo_inc++;
dev = container_of(inode->i_cdev, struct DEMO_dev, cdev);
filp->private_data = dev;
return 0;
}
int DEMO_release(struct inode *inode, struct file *filp)
{
demo_inc--;
return 0;
}
ssize_t DEMO_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
int result;
loff_t pos= *f_pos; /* 文件的读写位置 */
if(pos>=256)
{
result=0;
goto out;
}
if(count>(256-pos))
{
count=256-pos;
}
pos += count;
if (copy_to_user(buf,demoBuffer+*f_pos,count))
{
count=-EFAULT; /* 把数据写到应用程序空间 */
goto out;
}
*f_pos = pos; /* 改变文件的读写位置 */
out:
return count;
}
ssize_t DEMO_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
{
ssize_t retval = -ENOMEM; /* value used in "goto out" statements */
loff_t pos= *f_pos;
if(pos>=256)
{
goto out;
}
if(count>(256-pos))
{
count=256-pos;
}
pos += count;
if (copy_from_user(demoBuffer+*f_pos, buf, count)) {
retval = -EFAULT;
goto out;
}
*f_pos = pos;
return count;
out:
return retval;
}
int DEMO_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
if(cmd==COMMAND1)
{
printk("ioctl command1 successfully\n");
return 0;
}
if(cmd==COMMAND2)
{
printk("ioctl command2 successfully\n");
return 0;
}
printk("ioctl error\n");
return -EFAULT;
}
loff_t DEMO_llseek(struct file *filp, loff_t off, int whence)
{
loff_t pos;
pos = filp->f_pos;
switch (whence)
{
case 0:
pos = off;
break;
case 1:
pos += off;
break;
case 2:
default:
return -EINVAL;
}
if ((pos>256) || (pos<0))
{
return -EINVAL;
}
return filp->f_pos=pos;
}
struct file_operations DEMO_fops = {
.owner = THIS_MODULE,
.llseek = DEMO_llseek,
.read = DEMO_read,
.write = DEMO_write,
.ioctl = DEMO_ioctl,
.open = DEMO_open,
.release = DEMO_release,
};
/*******************************************************
MODULE ROUTINE
*******************************************************/
void DEMO_cleanup_module(void)
{
dev_t devno = MKDEV(DEMO_MAJOR, DEMO_MINOR);
if (DEMO_devices)
{
cdev_del(&DEMO_devices->cdev);
kfree(DEMO_devices);
}
unregister_chrdev_region(devno,1);
}
int DEMO_init_module(void)
{
int result;
dev_t dev = 0;
dev = MKDEV(DEMO_MAJOR, DEMO_MINOR);
result = register_chrdev_region(dev, 1, "DEMO");
if (result < 0)
{
printk(KERN_WARNING "DEMO: can't get major %d\n", DEMO_MAJOR);
return result;
}
DEMO_devices = kmalloc(sizeof(struct DEMO_dev), GFP_KERNEL);
if (!DEMO_devices)
{
result = -ENOMEM;
goto fail;
}
memset(DEMO_devices, 0, sizeof(struct DEMO_dev));
cdev_init(&DEMO_devices->cdev, &DEMO_fops);
DEMO_devices->cdev.owner = THIS_MODULE;
DEMO_devices->cdev.ops = &DEMO_fops;
result = cdev_add (&DEMO_devices->cdev, dev, 1);
if(result)
{
printk(KERN_NOTICE "Error %d adding DEMO\n", result);
goto fail;
}
return 0;
fail:
DEMO_cleanup_module();
return result;
}
module_init(DEMO_init_module);
module_exit(DEMO_cleanup_module);
mknod /dev/demo c 224 0
#include
#include
#include
#include
#include
#include
#include
#define COMMAND1 1
#define COMMAND2 2
main()
{
int fd;
int i;
char data[256];
int retval;
fd=open("/dev/demo",O_RDWR);
if(fd==-1)
{
perror("error open\n");
exit(-1);
}
printf("open /dev/demo successfully\n");
retval=ioctl(fd,COMMAND1,0);
if(retval==-1)
{
perror("ioctl error\n");
exit(-1);
}
printf("send command1 successfully\n");
retval=write(fd,"fgj",3);
if(retval==-1)
{
perror("write error\n");
exit(-1);
}
retval=lseek(fd,0,0);
if(retval==-1)
{
perror("lseek error\n");
exit(-1);
}
retval=read(fd,data,3);
if(retval==-1)
{
perror("read error\n");
exit(-1);
}
printf("read successfully:%s\n",data);
close(fd);
}