繁体   English   中英

从内核写入用户空间的问题-Linux设备驱动程序

[英]Problem with writing from kernel to user space - linux device driver

我正在尝试编写一个简单的Raspberry Pi GPIO驱动程序,将四个开关连接到四个GPIO引脚,以读取每个开关的状态。 问题是,我不确定如何从内核写入用户空间,当我插入设备内核模块并尝试使用cat命令读取设备文件时,我什么也没得到。 device_read函数如下:

static ssize_t gpio_driver_read(struct file *filp, char *buf, size_t len, loff_t *f_pos)
{
    /* Size of valid data in gpio_driver - data to send in user space. */
    int data_size = 0;

    /* Counter for 'for' loop. */
    int i;

    /* Print to kernel space. */
    printk(KERN_INFO "Reading active Switch state...\n");

    for (i = 0; i < 4; i = i+1)
    {
        printk(KERN_INFO "Loop number %d...\n", i);
        /* TODO: fill gpio_driver_buffer here. */
        if (i == 0 && mySwitches[0])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio12 value: %d\n", GetGpioPinValue(GPIO_12));
        else if (i == 1 && mySwitches[1])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio16 value: %d\n", GetGpioPinValue(GPIO_16));
        else if (i == 2 && mySwitches[2])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio20 value: %d\n", GetGpioPinValue(GPIO_20));
        else if (i == 3 && mySwitches[3])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio21 value: %d\n", GetGpioPinValue(GPIO_21));

        printk(KERN_INFO "%s\n", gpio_driver_buffer);

        /* Get size of valid data. */
        data_size = strlen(gpio_driver_buffer);

        printk(KERN_INFO "%d\n", data_size);


        /* Send data to user space. */
        if (copy_to_user(buf, gpio_driver_buffer, data_size) != 0)
        {
            return -EFAULT;
        }
    }

    return 0;
}

gpio_driver_buffer是一些默认大小的数组(我将其设置为80)。
mySwitches是一个由4个元素组成的数组,每个元素的值为0或1(在插入内核模块时,我将其作为参数传递,1表示我要监视开关的状态,0表示我不监视开关的状态。开关)。
GetGpioPinValue是一个返回开关状态的函数。

问题是,当我尝试使用cat命令读取设备文件时,什么也没得到。 但是,如您所见,我使用printk命令调试了程序,并且一切都正确地写入了内核空间。 问题可能在哪里?

看起来您从未写入实际文件。 由于您没有提及如何生成文件,因此我假设您正在写入任意文件,而不是驱动程序为/ proc或其他内容创建的文件。

在此处查看文章: 在Linux内核模块中读取/写入文件

您可以尝试以下方法:

int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_write(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}

然后调用它而不是“ copy_to_user”:

/* Send data to user space. */
        if (file_write(filep, 0, gpio_driver_buffer, data_size) != 0)
        {
            return -EFAULT;
        }

这里看看示例代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM