首页 > 其他分享 >字符设备,write一直返回-1的问题

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

时间:2024-04-27 15:57:09浏览次数:28  
标签:返回 字符 return dev write static device cdev printk

在学习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;

 

标签:返回,字符,return,dev,write,static,device,cdev,printk
From: https://www.cnblogs.com/atest/p/18162143

相关文章

  • oracle小技巧:字符串原样输出
       在sql查询中,我们经常需要原样输出字符串,如果字符串中含有大量的单引号、双引号或者特殊字符,那么需要用单引号转义拼接字符串,这样会非常的麻烦。      oracle提供了一个Q-quote的表达式来原样输出字符串。SELECTQ'[I'maboy,mynameis'david']'FROMDUAL......
  • 字符串置换
    3.1LintCode211-字符串置换  boolPermutation(string&A,string&B){  解法一:单纯使用数组计数,缺点是对如果带有特殊符号的字符串是无法处理的时间复杂度是O(n)#include<iostream>usingnamespacestd;constintN=1e5+10;intcnt1[26];intcnt2[26];bool......
  • 陈畅亮搞的专利在Windows上利用加解密DLL模块对数据库连接字符串进行加解密
    陈畅亮搞的专利在Windows上利用加解密DLL模块对数据库连接字符串进行加解密  这种专利权人是公司,个人是发明人,专利年费是申请人先垫付,然后公司报销了,这个专利本身就不属于员工的这个是公司是专利权人, 使用权是公司,如果想要维持权利的话,需要缴纳年费,专利发明现在一个市......
  • 顺序栈十进制转十六进制,还有键盘输入一个包括 '(' 和 ')' 的字符串string ,判断字符串
    设计一个进制转换程序,使用顺序栈设计一个把十进制数转换为十六进制数的接口,实现当通过键盘输入一个非负的十进制数,可以在终端输出对应的十六进制数。*@brief :十进制转十六进制*@param :@Segstackt*Manager:地址* @unsignedintData:转换的值*@re......
  • 一道关于顺序栈的笔试题:判断一个包含'('和')'的字符串是否有效
    若有一个包括'('和')'的字符串string,判断字符串是否有效。要求设计算法实现检查字符串是否有效,有效的字符串需满足以下条件:A.左括号必须用相同类型的右括号闭合。B.左括号必须以正确的顺序闭合。C.每个右括号都有一个对应的相同类型的左括号。思路图:参考代码:boolSeq......
  • 字符串里找数字
    #include<iostream>#include<string>#include<cctype>intmain(){std::stringinput;std::cout<<"请输入一个字符串:";std::getline(std::cin,input);//读取一行输入std::stringnumber;//用来存储找到的数字std::cou......
  • 如何在 C# 中使用 String.Split 分隔字符串
    一直以为split是用来分隔字符的,没想到还可以分隔数组。让程序变得更简单。微软官网的介绍在此记录下。https://learn.microsoft.com/zh-cn/dotnet/csharp/how-to/parse-strings-using-split 1、分单个字符stringphrase="Thequickbrownfoxjumpsoverthelazydog.";......
  • 获取天时分之间的时间间隔,返回天时分格式的日期,利用一天1440分钟
     写了老半天,还是电脑写的更简单,原来split还可以这么用,学到了。记录下//我写的publicstaticstringRetrieveSpanTimeByTime(stringfirstTime,stringendTime){intfirstDayIndex=firstTime.IndexOf("天");intendDayIndex=......
  • Android保存字符串到本地储存卡中saveLocal
    publicclassSaveLocal{//保存文件到sd卡publicstaticvoidsaveToFile(Stringcontent){BufferedWriterout=null;//获取SD卡状态Stringstate=Environment.getExternalStorageState();//判断SD卡是否就绪if(......
  • 找到字符串中所有字母异位词
    Problem:438.找到字符串中所有字母异位词目录思路Code给定两个字符串s和p,找到s中所有p的异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。异位词指由相同字母重排列形成的字符串(包括相同的字符串)。示例1:输入:s="cbaebabacd",p="abc"输出:......