无法从 linux 个字符设备读取
Can't read from linux character device
我正在为加速度计实现 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 读取时,它 returns 一个空字符串。
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
函数的概念:
reader(用户 space)仅看到 .read
返回的值,并将其解释为 已读取的字节数.
至于最后一个参数到.read
(position
在你的情况下),它的解释完全取决于驱动作者。 position
指向的值在文件打开时由内核核心初始化为 0。在那之后,内核本身再也不会修改它。
如果你想总是从头开始阅读,你可以忽略position
参数:
return size_requested;
或者,语义上更好,您可以递增值,由 position
指向,因此它将反映 总 读取的字节数。但否则请忽略它:
*position += size_requested;
return size_requested;
我正在为加速度计实现 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 读取时,它 returns 一个空字符串。
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
函数的概念:
reader(用户 space)仅看到 .read
返回的值,并将其解释为 已读取的字节数.
至于最后一个参数到.read
(position
在你的情况下),它的解释完全取决于驱动作者。 position
指向的值在文件打开时由内核核心初始化为 0。在那之后,内核本身再也不会修改它。
如果你想总是从头开始阅读,你可以忽略position
参数:
return size_requested;
或者,语义上更好,您可以递增值,由 position
指向,因此它将反映 总 读取的字节数。但否则请忽略它:
*position += size_requested;
return size_requested;