编写驱动后 open 一直返回 -1

haohaokingXP 2010-10-26 10:14:55

写了一个简单的字符设备驱动程序,类似于ldd3中的scull,在测试程序 fd = open("/dev/newdevname", O_RDONLY ),
fd 一直返回-1。


在insmod后,在/proc/devices中可以看到newdevname和分配到major 250,
然后mknode /dev/newdevname c 250 0后,在/dev/也生成newdevname,以上都是OK,但是在写测试程序fd = open("/dev/newdevname", O_RDONLY ),fd 一直返回 -1,而且从printk来看open("/dev/newdevname", O_RDONLY )没有调用我编写open驱动函数。

猜测是调用system_call由于其他原因可能就返回-1,而没有调用我编写的open驱动函数,希望大虾帮我解决下!
...全文
430 点赞 收藏 16
写回复
16 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
haohaokingXP 2010-10-27
谢谢大家,结贴
回复
手机写程序 2010-10-26
试试下面的命令返回什么.
dd if=/dev/zero of=/dev/newdevname bs=1 count=1
dd if=/dev/newdevname of=/dev/null bs=1 count=1
回复
手机写程序 2010-10-26
lz的代码风格看起来是也是vc程序员啊,连设备节点都是这样的/dev/SimpleCharDevice.
回复
haohaokingXP 2010-10-26
加载时成功了,设备号也一致的。这个我确定
回复
太阳德生 2010-10-26
首先确认驱动加载是否成功,其次确认在驱动中,你的这个设备是动态分配设备号的,还是静态分配的,看你mknod的设备号,跟你在驱动中分配的是否一致。不一致肯定会不成功。
回复
haohaokingXP 2010-10-26
谢谢大家了,我发现了问题所在
static void SetupSimpleCdev(struct cdev* pcdev, int index)
{
dev_t devno = 0;
int error = 0;
cdev_init(pcdev, &pstCharDev_fops);
pcdev->owner = THIS_MODULE;
pcdev->ops = &pstCharDev_fops;
error = cdev_add(pcdev,devno, 1);
if (error){
printk(KERN_INFO "SimpleCharDevice:Error %d adding scull%d", error, index);
}
printk(KERN_INFO "SimpleCharDevice: setup cdev ok");

}
dev_t devno = 0; 没有计算devno,只是赋值给0
回复
Wenxy1 2010-10-26
1. 检查有没有/dev/SimpleCharDevice这个设备文件;如果没有,用mknod命令手工创建此设备文件;
2. ko文件是否insmod成功,lsmod看看;
3. 应用程序open失败,用perror打印出失败信息和errno错误码。
回复
haohaokingXP 2010-10-26
请看代码


// 驱动程序文件
#include <linux/module.h>
#include <linux/init.h>

#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/slab.h>

#define SMPLE_MEMORY_SIZE (100)

struct SimpleDevice_st {
char* pdata;
int num;
struct cdev cdev;
};

MODULE_AUTHOR("Wanghaodong");
MODULE_DESCRIPTION("A char device driver to show how to write a char deivce driver");
MODULE_VERSION("0.1");
MODULE_LICENSE("Dual BSD/GPL");

//Declare function START
static int Simple_InitModule(void);
static void Simple_CleanUpModule(void);
static ssize_t Simple_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
static ssize_t Simple_Open(struct inode* inode, struct file* file);
static void SetupSimpleCdev(struct cdev* pcdev, int index);

//Define and Init variable
module_init(Simple_InitModule);
module_exit( Simple_CleanUpModule);

static struct file_operations pstCharDev_fops ={
.owner = THIS_MODULE,
.read = Simple_read,
//.write = Simple_Write,
.open = Simple_Open,
//.realse= Simple_Realse,
};



struct SimpleDevice_st* npstDevice = NULL;
static int schar_Major = 0;
static int schar_Minor = 0;
static int schar_MinorNum = 1;

static char memory_buffer[SMPLE_MEMORY_SIZE] = {
1, 2, 3, 4, 5, 6, 7, 8, 9,10,

};
static int Simple_InitModule(void)
{
dev_t dev;
int result,i;

if(schar_Major == 0){
result = alloc_chrdev_region(&dev,schar_Minor, schar_MinorNum, "SimpleCharDevice");
schar_Major = MAJOR(dev);
}
else{
dev = MKDEV(schar_Major, schar_Minor);
result = register_chrdev_region(dev, schar_MinorNum, "SimpleCharDevice");
}
if(result < 0){
printk(KERN_INFO "SimpleCharDevice: can't get major %d\n", schar_Major);
result = -1;
goto fail;
}
else{
printk(KERN_INFO "SimpleCharDevice: sign major ok %d\n", schar_Major);
}

npstDevice = (struct SimpleDevice_st* )kmalloc(schar_MinorNum * sizeof(struct SimpleDevice_st), GFP_KERNEL);
if(!npstDevice){
printk(KERN_INFO "SimpleCharDevice: alloc memory failure");
goto fail;
}
memset(npstDevice, 0, schar_MinorNum * sizeof(struct SimpleDevice_st));

for(i = 0; i < schar_MinorNum; i++){
(npstDevice + i)->pdata = (char*)kmalloc(SMPLE_MEMORY_SIZE, GFP_KERNEL);
(npstDevice + i)->num = SMPLE_MEMORY_SIZE;
SetupSimpleCdev(&((npstDevice + i)->cdev), i);
memcpy((npstDevice + i)->pdata, memory_buffer, sizeof(memory_buffer));
}
printk(KERN_INFO "SimpleCharDevice: init Ok");

return 0;
fail:

printk(KERN_INFO "SimpleCharDevice: init failure");
Simple_CleanUpModule();

return result;



}
static void Simple_CleanUpModule(void)
{
int i;

if(npstDevice){
for (i = 0; i < schar_MinorNum; i++) {
cdev_del(&npstDevice[i].cdev);
kfree(npstDevice[i].pdata);
}
kfree(npstDevice);
}
}

static void SetupSimpleCdev(struct cdev* pcdev, int index)
{
dev_t devno = 0;
int error = 0;
cdev_init(pcdev, &pstCharDev_fops);
pcdev->owner = THIS_MODULE;
pcdev->ops = &pstCharDev_fops;
error = cdev_add(pcdev,devno, 1);
if (error){
printk(KERN_INFO "SimpleCharDevice:Error %d adding scull%d", error, index);
}
printk(KERN_INFO "SimpleCharDevice: setup cdev ok");

}

static ssize_t Simple_Open(struct inode* inode, struct file* file)
{
struct SimpleDevice_st* pstChrDevice = NULL;

printk(KERN_INFO "SimpleCharDevice:Open init");
pstChrDevice = container_of(inode->i_cdev, struct SimpleDevice_st, cdev);
file->private_data = pstChrDevice;

printk(KERN_INFO "SimpleCharDevice:Open OK");
return 0;
}

ssize_t Simple_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
struct SimpleDevice_st* pstChrDevice = NULL;
ssize_t rvalue = 0;
pstChrDevice = (struct SimpleDevice_st*)filp->private_data;

if( *f_pos + count > pstChrDevice->num){
count = pstChrDevice->num - *f_pos;
}

if( copy_to_user(buf, pstChrDevice->pdata, count) ){
printk(KERN_NOTICE "SimpleDevice: read failure");
return rvalue = 0;
}
rvalue = count;
*f_pos += rvalue;
return rvalue;
}

测试程序文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <memory.h>


int main()
{

int fd = 0;
char buffer[32];

memset(buffer, 0, 32);
fd = open("/dev/SimpleCharDevice", O_RDONLY);

if ( fd < 0){
printf("open file failure %d\n", fd);
return -1;
}

read(fd, buffer, 32);
printf("%s\n",buffer);
close(fd);

}


回复
haohaokingXP 2010-10-26
不好生意,我在公司加班,代码在家,回家就帖出来,呵呵。。。
回复
手机写程序 2010-10-26
快把代码交出来!哈哈.
回复
deep_pro 2010-10-26
就一个简单例子还藏着掖着 ,直接粘代码的话早解决了
回复
手机写程序 2010-10-26
你确定minor number 是0吗?
回复
haohaokingXP 2010-10-26
[Quote=引用 5 楼 eyey1 的回复:]

在driver里的file_operations.open函数你return -1了?
[/Quote]

这个真的没有。我已经写了没有调用我的file_operations.open
回复
ma100 2010-10-26
把驱动程序贴出来
回复
手机写程序 2010-10-26
在driver里的file_operations.open函数你return -1了?
回复
haohaokingXP 2010-10-26
[Quote=引用 3 楼 eyey1 的回复:]

试试下面的命令返回什么.
dd if=/dev/zero of=/dev/newdevname bs=1 count=1
dd if=/dev/newdevname of=/dev/null bs=1 count=1
[/Quote]

我只是写read 函数,没有写wirte函数,看看情况,然后编写write函数,但是我用cat /dev/newdevname会报错提示不是一个文件。
回复
相关推荐
发帖
Linux_Kernel
创建于2007-08-27

4152

社区成员

Linux/Unix社区 内核源代码研究区
申请成为版主
帖子事件
创建了帖子
2010-10-26 10:14
社区公告
暂无公告