求助:关于I2C驱动,第二次insmod出问题

owlpark 2012-01-01 06:19:18
我刚才编写了一个基于I2C总线的at24c02 驱动
一切顺利调试,用测试程序测试 运行成功

不过也问题出来了:
当我rmmod 我的那个模块即命名为myi2cdrv
查看lsmod,那个模块除去了
再查看cat /proc/devices 也除去了
ls /dev/myi2cdrv 也除去了


接着(不重启开发板),再来insmod 刚才那个模块,
lsmod 有它,
但再查看cat /proc/devices 没有它
ls /dev/myi2cdrv 没有它。
用测试程序自然不成功

我觉得好奇怪,平时写个驱动,可以重复insmod/rmmod都可以,为啥这次不行了,晕死了。
看了代码 没问题,我在此贴出后面两个函数给大家看,希望高手,解决下,谢谢了~~

static int myi2cdrv_detach_client(struct i2c_client *client)
{
unregister_chrdev(myi2cdrv_major, "myi2cdrv_dev");
class_device_unregister(myi2cdrv_class_dev);
class_unregister(myi2cdrv_class);
return 0;
}

static int __init myi2cdrv_init(void)
{
i2c_add_driver(&my_i2c_driver);
return 0;
}
static void __exit myi2cdrv_exit(void)
{
i2c_del_driver(&my_i2c_driver);
}
module_init(myi2cdrv_init);
module_exit(myi2cdrv_exit);

...全文
167 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
owlpark 2012-01-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 deep_pro 的回复:]
at24cxx 的驱动2.6.25之后内核就有了
如果一定要找问题 现在的这些代码看不出来啊
[/Quote]

下以为所有代码:
帮忙看下

#define DATA_SIZE  1024
static struct i2c_client *myi2cdrv_client;
static int myi2cdrv_major = 0;
static char myi2cdrv_buf[DATA_SIZE] ;
static struct class * myi2cdrv_class = NULL;
static struct class_device *myi2cdrv_class_dev = NULL;

#define SET_OFFSET 0
//偏移量
static char myi2cdrv_offset = 0 ;

static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };

static struct i2c_client_address_data myi2cdrv_addr_data = {
.normal_i2c = normal_addr,
.probe = ignore,
.ignore = ignore,
};

static int myi2cdrv_attach_adapter(struct i2c_adapter *adapter);
static int myi2cdrv_detach_client(struct i2c_client *client);

static struct i2c_driver my_i2c_driver ={
.driver = {
.name = "my_i2c_driver",
},
.attach_adapter = myi2cdrv_attach_adapter,
.detach_client = myi2cdrv_detach_client,
};
static int myi2cdrv_open(struct inode *inode, struct file *file)
{
//myi2cdrv_offset = 0 ;
return 0;
}
static ssize_t myi2cdrv_read(struct file *file, char __user *buf, size_t size, loff_t *opps)
{
struct i2c_msg i2cmsg[2];

char addr = myi2cdrv_offset;
int ret;

printk("read offset = %d \n",addr);
i2cmsg[0].addr =myi2cdrv_client->addr;
i2cmsg[0].flags =0;
i2cmsg[0].len =1;
i2cmsg[0].buf =&addr;

i2cmsg[1].addr = myi2cdrv_client->addr;
i2cmsg[1].flags = 1;
i2cmsg[1].len = size;
i2cmsg[1].buf = myi2cdrv_buf;

ret = i2c_transfer(myi2cdrv_client->adapter, i2cmsg, 2);
if(ret == 2){
ret = copy_to_user(buf, myi2cdrv_buf, size);
if(!ret)
return size;
else
return size-ret;
}else{
return -1;
}


}
static ssize_t myi2cdrv_write(struct file *file, const char __user *buf, size_t size, loff_t *opps)
{
struct i2c_msg i2cmsg[1];
char addr = myi2cdrv_offset;
int ret;
ret = copy_from_user(&myi2cdrv_buf[1], buf, size);
if(ret){
size -=ret;
}
myi2cdrv_buf[0] = addr;
printk("write offset = %d \n",myi2cdrv_buf[0]);

i2cmsg[0].addr =myi2cdrv_client->addr;
i2cmsg[0].flags =0;
i2cmsg[0].len =size + 1;
i2cmsg[0].buf =myi2cdrv_buf;

ret = i2c_transfer(myi2cdrv_client->adapter, i2cmsg, 1);
if(ret == 1)
return size;
else
return -1;
}
static int myi2cdrv_close(struct inode *inode, struct file *file)
{
return 0;
}


static int myi2cdrv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int ret;
switch (cmd) {
case SET_OFFSET:
ret = copy_from_user(&myi2cdrv_offset ,(char *)arg ,1);
printk("ioctl offset = %d \n",myi2cdrv_offset);

break;
default:
printk("ioctl nothing to do \n");
}
return 0;
}

static struct file_operations myi2cdrv_dev_fops = {
.owner = THIS_MODULE,
.open = myi2cdrv_open,
.read = myi2cdrv_read,
.write = myi2cdrv_write,
.release = myi2cdrv_close,
.ioctl = myi2cdrv_ioctl,
};

static int myi2cdrv_client_detect(struct i2c_adapter *adapter, int addr, int kind)
{
myi2cdrv_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);

myi2cdrv_client->addr = addr;
myi2cdrv_client->adapter = adapter;
myi2cdrv_client->driver = &my_i2c_driver;
myi2cdrv_client->flags = 0;

i2c_attach_client(myi2cdrv_client);

myi2cdrv_major = register_chrdev(0, "myi2cdrv_dev",&myi2cdrv_dev_fops);
myi2cdrv_class = class_create(THIS_MODULE, "myclass");
myi2cdrv_class_dev = class_device_create(myi2cdrv_class, NULL, MKDEV(myi2cdrv_major,0), NULL, "myi2cdrv");

return 0;
}
static int myi2cdrv_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_probe(adapter, &myi2cdrv_addr_data, myi2cdrv_client_detect);
}

static int myi2cdrv_detach_client(struct i2c_client *client)
{

return 0;
}



static int __init myi2cdrv_init(void)
{
i2c_add_driver(&my_i2c_driver);
return 0;
}
static void __exit myi2cdrv_exit(void)
{

unregister_chrdev(myi2cdrv_major, "myi2cdrv_dev");
class_device_unregister(myi2cdrv_class_dev);
class_unregister(myi2cdrv_class);
i2c_del_driver(&my_i2c_driver);
}
module_init(myi2cdrv_init);
module_exit(myi2cdrv_exit);
MODULE_LICENSE("GPL");
deep_pro 2012-01-01
  • 打赏
  • 举报
回复
at24cxx 的驱动2.6.25之后内核就有了
如果一定要找问题 现在的这些代码看不出来啊

4,441

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧