无法从Linux字符设备读取

标签 c linux-kernel device-driver

我正在为加速度计实现 SPI 驱动程序。 SPI 部分已完成,但我无法从用户空间读取值。

static char charDevMessage[CD_BUFFER_SIZE] = { 0 };
...
static ssize_t char_dev_read(struct file *filep, char *buffer, size_t len, loff_t *position)
{

    int error_count = 0;
    struct xyz_values xyz;
    size_t size_requested;

    xyz = adxl345_get_xyz();
    memset(charDevMessage, 0, CD_BUFFER_SIZE);
    sprintf(charDevMessage, "%d,%d,%d", xyz.x, xyz.y, xyz.z);
    printk(KERN_INFO "MOB: %s, requested size: %d\n", charDevMessage, len);

    if (len >= CD_BUFFER_SIZE)
    {
        size_requested = CD_BUFFER_SIZE;
    }
    else
    {
        size_requested = len;
    }

    error_count = copy_to_user(buffer, charDevMessage, size_requested);      

    if (error_count == 0)          
    {
        printk(KERN_INFO "MOB: Sent %d characters to the user\n", size_requested);
        return (size_requested = 0);      

    }
    else
    {
        printk(KERN_INFO "MOB: Failed to send %d characters to the user\n", error_count);
        return -EFAULT;              

    }
}

当我安装驱动程序时,该节点已创建。但是当我尝试 cat 或尝试通过 python 读取时,它返回一个空字符串。

dmesg 表示已成功发送到用户空间:

[ 3094.495972] MOB: SPI Character device has been opened 1 time(s)
[ 3094.506075] MOB: -349,-512,511 , requested size:49
[ 3094.514487] MOB: Sent 256 characters to the user
[ 3094.522646] MOB: Character device successfully closed
[ 3120.658568] MOB: SPI Character device has been opened 2 time(s)
[ 3120.668609] MOB: 0,0,0 , requested size:48
[ 3120.676392] MOB: Sent 256 characters to the user
[ 3120.684740] MOB: Character device successfully closed

我做错了什么?

最佳答案

您误解了.read函数的概念:

读取器(用户空间)仅看到 .read 返回的,并将其解释为已读取的字节数 .

至于 .read最后一个参数(在您的情况下是位置),其解释完全取决于驱动程序的作者position 指向的值在文件打开时由内核初始化为 0。此后,内核本身不再修改它。

如果你想总是从头开始读取,你可以忽略 position 参数:

return size_requested;

或者,从语义上讲,您可以增加由位置指向的值,这样它将反射(reflect)读取的字节数。但除此之外忽略它:

*position += size_requested;
return size_requested;

关于无法从Linux字符设备读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40738054/

相关文章:

linux - 有没有一种方法/工具可以在 Linux 下列出标记为 "thin"的 TCP 连接?

c - 为什么这个 union 末尾有 char 数组?

linux - 对 linux 内核开发的一些事情没有概念

c - RRD具有高精度?

c - 为什么我不能从某些处理器异常中返回?玩具内核开发

c - 加速Linux可执行程序-arm处理器。位切换

windows - 为什么当我尝试打开删除挂起的文件时 Windows 返回 ERROR_ACCESS_DENIED

c - 为什么案例 : always requires constant expression while if() doesn't?

c - 每个中断处理程序都需要自旋锁吗?

c - 如何在 x86_64 上为 mmap 支持 IA-32?