📄 chardev.c
字号:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/ioctl.h>
int init_module(void);
void cleanup_module(void);
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static int device_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
#define DEVICE_NAME "chardev"
#define MAJOR_NUM 250
#define SUCCESS 0
#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, int *)
#define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, int *)
static int Device_Open = 0; static int Major; static int arg_flag = 0;
static int pointer;
static int msgx_init = 0;
static int msgy_init = 0;
static int msgz_init = 0;
static int counterx = 0;
static int countery = 0;
static int counterz = 0;
static char msgx[80];
static char msgy[80];
static char msgz[80];
static char *msg_Ptr;
static struct file_operations fops =
{
read : device_read,
write : device_write,
open : device_open,
release : device_release,
ioctl : device_ioctl
};
int init_module(void)
{
Major = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
msg_Ptr = msgx;
if (Major < 0)
{
printk ("\nRegistering the character device failed with %d\n", Major);
return Major;
}
printk("<1>\nThe device has been registered!\n");
return SUCCESS;
}
void cleanup_module(void)
{
int ret = unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
msg_Ptr = msgx;
if (ret < 0)
printk("\nError in unregister_chrdev: %d\n", ret);
printk("<1>\nThe device has been removed!\n");
}
static int device_open(struct inode *inode, struct file *file)
{
if (Device_Open)
return -EBUSY;
printk("\nDevice is open\n");
Device_Open++;
if (msgx_init == 0)
sprintf(msgx,"I already told you %d times I'm WangKai!\n", counterx);
if (msgy_init == 0)
sprintf(msgy,"I already told you %d times I'm a student!\n", countery);
if (msgz_init == 0)
sprintf(msgz,"I already told you %d times I'm 20 years old!\n", counterz);
pointer = 0;
return SUCCESS;
}
static int device_release(struct inode *inode, struct file *file)
{
printk("\nDevice is closed\n");
Device_Open--;
return SUCCESS;
}
static ssize_t device_read(struct file *filp,char *buffer,
size_t length,loff_t *offset)
{
int bytes_read = 0;
if (pointer == 1)
return 0;
printk("\nRead data from kernelspace to userspace\n");
while (length && *msg_Ptr && !pointer)
{
put_user(*(msg_Ptr++), buffer++);
length--;
bytes_read++;
}
if (arg_flag==0) {counterx++;msg_Ptr = msgx;}
if (arg_flag==1) {countery++;msg_Ptr = msgy;}
if (arg_flag==2) {counterz++;msg_Ptr = msgz;}
pointer = 1;
return bytes_read;
}
static ssize_t device_write(struct file *filp,const char *buffer,
size_t length,loff_t *offset)
{
int bytes_write = 0;
if (*buffer == 0)
return 0;
printk("\nWrite data from userspace to kernelspace\n");
while (length && *buffer)
{
get_user(*(msg_Ptr++), buffer++);
length--;
bytes_write++;
}
if (arg_flag==0) msgx_init = 1;
if (arg_flag==1) msgy_init = 1;
if (arg_flag==2) msgz_init = 1;
msg_Ptr = msg_Ptr-bytes_write;
return bytes_write;
}
static int device_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case IOCTL_SET_MSG:
if (arg==1) {msg_Ptr=msgx;arg_flag=0;}
if (arg==2) {msg_Ptr=msgy;arg_flag=1;}
if (arg==3) {msg_Ptr=msgz;arg_flag=2;}
break;
case IOCTL_GET_MSG:
if (msg_Ptr==msgx) *(long *)arg=1;
if (msg_Ptr==msgy) *(long *)arg=2;
if (msg_Ptr==msgz) *(long *)arg=3;
default:
break;
}
return 0;
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("WangKai");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -