字符设备,write一直返回-1的问题

在学习linux设备驱动时遇到的问题,请求大佬指点:

1、 insmod char_dev.ko 

2、 mknod /dev/mydevice c 240 0

3、 ./test

 write 返回-1, 内核没有调用的 device_write 函数。

 

char_dev.c

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>

#define DEVICE_NAME "mydevice"
#define BUF_SIZE 1024

static dev_t dev;
static struct cdev cdev;
static char buffer[BUF_SIZE];
static int buffer_len = 0;

static int device_open(struct inode *inode, struct file *filp)
{
    printk(KERN_INFO "device_open\n");
    // 设备打开时的操作
    return 0;
}

static int device_release(struct inode *inode, struct file *filp)
{
    printk(KERN_INFO "device_release\n");
    // 设备关闭时的操作
    return 0;
}

static ssize_t device_read(struct file *filp, char *user_buf, size_t count, loff_t *f_pos)
{
    printk(KERN_INFO "device_read\n");
    // 从设备读取数据
    size_t to_copy = min(count, (size_t)buffer_len);
    if (copy_to_user(user_buf, buffer, to_copy) != 0)
        return -EFAULT;

    return to_copy;
}

static ssize_t device_write(struct file *filp, const char *user_buf, size_t count, loff_t *f_pos)
{
    printk(KERN_INFO "device_write\n");
    // 向设备写入数据
    size_t to_copy = min(count, (size_t)BUF_SIZE);
    if (copy_from_user(buffer, user_buf, to_copy) != 0)
        return -EFAULT;

    buffer_len = to_copy;
    return to_copy;
}

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .open = device_open,
    .release = device_release,
    .read = device_read,
    .write = device_write,
};

static int __init chardev_init(void)
{
    printk(KERN_INFO "chardev_init\n");
    // 模块初始化函数
    if (alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME) < 0)
    {
        printk(KERN_ALERT "Failed to allocate character device region\n");
        return -1;
    }

    cdev_init(&cdev, &fops);
    cdev.owner = THIS_MODULE;
    cdev.ops = &fops;
    if (cdev_add(&cdev, dev, 1) < 0)
    {
        unregister_chrdev_region(dev, 1);
        printk(KERN_ALERT "Failed to add character device\n");
        return -1;
    }

    printk(KERN_INFO "Character device registered: %s\n", DEVICE_NAME);
    return 0;
}

static void __exit chardev_exit(void)
{
    printk(KERN_INFO "chardev_exit\n");
    // 模块退出函数
    cdev_del(&cdev);
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Character device unregistered\n");
}

module_init(chardev_init);
module_exit(chardev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Gaozy");
MODULE_DESCRIPTION("Character Device Driver");

 

test.c

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define DEMO_DEV_NAME       "/dev/cdd_demo"

int main(void)
{
    printf("hello char dev.\n");

    char buffer[64] = {0};
    int fd = open(DEMO_DEV_NAME, 0644);
    if (fd < 0) {
        printf("open %s failed = %d\n", DEMO_DEV_NAME, fd);
        return -1;
    }


    int size = write(fd, "hello world.", strlen("hello world."));
    printf("fd = %d, size = %d\n", fd, size);

/*
    for (int i=0; i<10; i++) {
        char buff[10];
        memset(buff, i, );
        int size = write(fd, buff, 10);
        if (size != 10) {
            printf("size = %d\n", size);
        }
    }
*/
/*
    for (int i=0; i<5; i++) {
        char buff[20];
        int size = read(fd, buff, sizeof(buff));
        for (int j=0; j<size; j++) {
            printf("%d ", buff[i]);
        }
        printf("\n");
    }
*/
    close(fd);

    return 0;
}

 

Makefile

BASEINCLUDE ?= /lib/modules/$(shell uname -r)/build/
#mydemo-objs := char_dev.o
obj-m := char_dev.o

all:
    $(MAKE) -C $(BASEINCLUDE) M=$(PWD) modules;
    g++ -g test.c -o test;

clean:
    ${MAKE} -C $(BASEINCLUDE) M=${PWD} clean;
    @rm -f *.ko;
    @rm -f test;

 

posted on 2024-04-27 15:44  gaozy6626  阅读(58)  评论(1编辑  收藏  举报