[16559.934862] devno=242221056
[16559.934864] globalmem init success
设备中能找到devno=231的设备
test@test:~/Linux_driver/.vscode/CH5$ cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
5 ttyprintk
6 lp
7 vcs
10 misc
13 input
21 sg
29 fb
89 i2c
99 ppdev
108 ppp
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
204 ttyMAX
226 drm
231 globalmem_tmp
244 aux
245 hidraw
sudo mknod -m 766 /dev/globalmem_tmp c 231 0 新建一个设备
ls -al /dev | grep global
crwxrw-rw- 1 root root 231, 0 12月 2 15:43 globalmem_tmp
输入的时候提示找不到这个设备是什么原因呢
sudo echo "abc" > /dev/globalmem_tmp
bash: /dev/globalmem_tmp: No such device or address
代码如下
代码: 全选
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
#define GLOBALMEM_SIZE 0x100
#define MEM_CLEAR 0x1
#define GLOBALMEM_MAJOR 231
static int globalmem_major=GLOBALMEM_MAJOR;
module_param(globalmem_major,int,S_IRUGO);
struct globalmem_dev{
struct cdev cdev;
unsigned int current_len;
unsigned char mem[GLOBALMEM_SIZE];
struct mutex mutex;
wait_queue_head_t r_wait;
wait_queue_head_t w_wait;
};
struct globalmem_dev *globalmem_devp;
static ssize_t globalmem_read_queue(struct file *filp,char __user *buf,size_t size,loff_t *ppos)
{
int ret;
struct globalmem_dev *dev=filp->private_data;
DECLARE_WAITQUEUE(wait,current);
mutex_lock(&dev->mutex);
add_wait_queue(&dev->r_wait,&wait);
while(dev->current_len == 0){
if(filp->f_flags & O_NONBLOCK){
printk(KERN_INFO "NONBLOCK_DEVICE\n");
ret=-EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
mutex_unlock(&dev->mutex);
schedule();
if(signal_pending(current)){
ret=-ERESTARTSYS;
goto out2;
}
mutex_lock(&dev->mutex);
}
if(size > dev->current_len)
size=dev->current_len;
if(copy_to_user(buf,dev->mem,size)){
printk("copy_to_user_fail\n");
ret=-EFAULT;
goto out;
}
else
{
memcpy(dev->mem,dev->mem+size,dev->current_len-size);
dev->current_len-=size;
printk(KERN_INFO "read %d bytes,current_len:%d\n",size,dev->current_len);
wake_up_interruptible(&dev->w_wait);
ret=size;
}
out:
mutex_unlock(&dev->mutex);
out2:
remove_wait_queue(&dev->w_wait,&wait);
set_current_state(TASK_RUNNING);
return ret;
}
static ssize_t globalmem_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos)
{
unsigned long p=*ppos;
unsigned int count=size;
int ret=0;
struct globalmem_dev *dev=filp->private_data;
DECLARE_WAITQUEUE(wait,current);
mutex_lock(&dev->mutex);
add_wait_queue(&dev->w_wait,&wait);
while(dev->current_len == GLOBALMEM_SIZE)
{
if(filp->f_flags & O_NONBLOCK){
printk(KERN_INFO "NONBLOCK_DEVICE\n");
ret = -1;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
mutex_unlock(&dev->mutex);
schedule();
if(signal_pending(current)){
ret =-1;
goto out2;
}
mutex_lock(&dev->mutex);
}
if(copy_from_user(dev->mem+p,buf,count)){
ret=-1;
}
else
{
dev->current_len+=count;
printk(KERN_INFO "written %d bytes,current_len:%d\n",count,dev->current_len);
wake_up_interruptible(&dev->r_wait);
}
out:
mutex_unlock(&dev->mutex);
out2:
remove_wait_queue(&dev->w_wait,&wait);
set_current_state(TASK_RUNNING);
return ret;
}
static loff_t globalmem_llseek(struct file *filp,loff_t offset,int orig)
{
loff_t ret=0;
switch(orig){
case 0:
if(offset < 0)
{
ret =-1;
break;
}
if((unsigned int)offset > GLOBALMEM_SIZE){
ret = -1;
break;
}
case 1:
if((filp->f_pos+offset) < 0){
ret =-1;
break;
}
filp->f_pos+=offset;
ret=filp->f_pos;
break;
default:
ret =-1;
break;
}
return ret;
}
static long globalmem_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
struct globalmem_dev *dev=filp->private_data;
switch(cmd){
case MEM_CLEAR:
mutex_lock(&dev->mutex);
memset(dev->mem,0,GLOBALMEM_SIZE);
printk(KERN_INFO "globalmem is set to zero\n");
mutex_unlock(&dev->mutex);
break;
default:
return -1;
}
}
static int globalmem_open(struct inode *inode,struct file *filp)
{
filp->private_data=globalmem_devp;
return 0;
}
static int globalmem_release(struct inode *inode,struct file *filp)
{
return 0;
}
static const struct file_operations globalmem_fops={
.owner=THIS_MODULE,
.llseek=globalmem_llseek,
.read=globalmem_read_queue,
.write=globalmem_write,
.unlocked_ioctl=globalmem_ioctl,
.open=globalmem_open,
.release=globalmem_release,
};
static void globalmem_setup_cdev(struct globalmem_dev *dev,int index)
{
int err,devno=MKDEV(globalmem_major,index);
dev->cdev.owner=THIS_MODULE;
err=cdev_add(&dev->cdev,devno,1);
if(err)
printk(KERN_NOTICE "Error %d adding globalmem%d",err,index);
}
static int __init globalmem_init(void)
{
int ret;
dev_t devno=MKDEV(globalmem_major,0);
printk("devno=%d\n",devno);
if(globalmem_major)
ret=register_chrdev_region(devno,1,"globalmem_tmp");
else{
ret=alloc_chrdev_region(&devno,0,1,"globalmem_tmp");
globalmem_major=MAJOR(devno);
}
if(ret < 0)
return ret;
globalmem_devp=kzalloc(sizeof(struct globalmem_dev),GFP_KERNEL);
if(!globalmem_devp){
ret=-EFAULT;
goto fail_malloc;
}
mutex_init(&globalmem_devp->mutex);
globalmem_setup_cdev(globalmem_devp,0);
printk("globalmem init success\n");
init_waitqueue_head(&globalmem_devp->r_wait);
init_waitqueue_head(&globalmem_devp->w_wait);
return 0;
fail_malloc:
unregister_chrdev_region(devno,1);
return ret;
}
module_init(globalmem_init);
static void __exit globalmem_exit(void)
{
cdev_del(&globalmem_devp->cdev);
kfree(globalmem_devp);
unregister_chrdev_region(MKDEV(globalmem_major,0),1);
}
module_exit(globalmem_exit);
MODULE_AUTHOR("MAPLE");
MODULE_LICENSE("GPL V2");